diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2006-11-06 19:00:10 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2006-11-06 19:00:10 +0000 |
commit | 58d26e02cd8686e177eebb9fb81e6b17798bbb30 (patch) | |
tree | e7329ae5a85bb2d6b8bba0ebcd65c6c41999f96f | |
parent | 0b5d496ea2fd532dcf5e5b6b804a7db32f488364 (diff) | |
download | vyos-strongswan-58d26e02cd8686e177eebb9fb81e6b17798bbb30.tar.gz vyos-strongswan-58d26e02cd8686e177eebb9fb81e6b17798bbb30.zip |
Load /tmp/tmp.IBEBMao893/strongswan-2.8.0+dfsg into
branches/source-dist/debian/strongswan.
231 files changed, 21839 insertions, 50162 deletions
@@ -1,3 +1,13 @@ +strongswan-2.8.0 +---------------- + +- Implementation of ModeConfig push mode via the new connection keyword + modeconfig=push allows interoperability with Cisco VPN gateways. + +- The command ipsec statusall now shows "DPD active" for all ISAKMP SAs + that are under active Dead Peer Detection control. + + strongswan-2.7.3 ---------------- @@ -11,7 +11,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: Makefile,v 1.4 2004/11/14 21:50:59 as Exp $ +# RCSID $Id: Makefile,v 1.5 2006/08/28 11:12:36 as Exp $ FREESWANSRCDIR=$(shell pwd) @@ -244,7 +244,7 @@ programs install clean checkprograms:: @for d in $(SUBDIRS) ; \ do \ (cd $$d && $(MAKE) FREESWANSRCDIR=.. $@ ) || exit 1; \ - done; \ + done; clean:: rm -rf $(RPMTMPDIR) $(RPMDEST) diff --git a/Makefile.ver b/Makefile.ver index b8f0d8ffd..c13d3a0da 100644 --- a/Makefile.ver +++ b/Makefile.ver @@ -1 +1 @@ -IPSECVERSION=2.7.3 +IPSECVERSION=2.8.0 @@ -41,7 +41,7 @@ Contents 6.1 Loading private key files in PKCS#1 format 6.2 Entering passphrases interactively 6.3 Multiple private keys - 7. Configuring CA properties - ipsec.conf + 7. Configuring CA properties - ipsec.onf 8. Smartcard support 8.1 Configuring a smartcard-based connection 8.2 Entering the PIN code @@ -69,7 +69,8 @@ Contents 14.1 Authentication and encryption algorithms 14.2 NAT traversal 14.3 Dead peer detection - 14.4 IKE Mode Config + 14.4 IKE Mode Config Pull Mode + 14.5 IKE Mode Config Push Mode 15. Copyright statement and acknowledgements @@ -2918,8 +2919,8 @@ even if they might be supported by the responder. Currently please refer to README.NAT-Traversal document in the strongSwan distribution. - - + + 14.3 Dead peer detection -------------------- @@ -2969,14 +2970,15 @@ dpdaction=clear for dynamic roadwarrior connections. The default value is dpdaction=none, which disables DPD. -14.4 IKE Mode Config - --------------- - +14.4 IKE Mode Config Pull Mode + ------------------------- + The IKE Mode Config protocol <draft-ietf-ipsec-isakmp-mode-cfg-04.txt> allows the dynamic assignment of virtual IP addresses and optional DNS and WINS server -information to IPsec clients. Currently only "Mode Config Pull Mode" is -implemented where the client actively sends a Mode Config request to the server -in order to obtain a virtual IP. +information to IPsec clients. As a default the "Mode Config Pull Mode" is +used where the client actively sends a Mode Config request to the server +in order to obtain a virtual IP. The server answers with a Mode Config reply +message containing the requested information. Client side configuration (carol): @@ -3008,6 +3010,22 @@ the virtual IP address defined by the rightsourceip parameter. In the future an LDAP-based lookup mechanism will be supported. +14.5 IKE Mode Config Push Mode + ------------------------- + +Cisco VPN equipment uses the alternative "Mode Config Push Mode" where the +initiating clients waits for the server to push down a virtual address via +a Mode Config set message. The receipt is acknowledged by the client with a +Mode Config ack message. + +Mode Config Push Mode is activated by the parameter + + modeconfig=push + +as part of the connection definition in ipsec.conf. The default value is +modeconfig=pull. + + 15. Copyright statement and acknowledgements ---------------------------------------- @@ -3058,7 +3076,7 @@ an LDAP-based lookup mechanism will be supported. Copyright (c) 2000, Kai Martius X.509, OCSP and smartcard functionality: - +° Copyright (c) 2000, Andreas Hess, Patric Lichtsteiner, Roger Wegmann Copyright (c) 2001, Marco Bertossa, Andreas Schleiss Copyright (c) 2002, Uli Galizzi, Ariane Seiler, Mario Strasser @@ -3087,5 +3105,5 @@ an LDAP-based lookup mechanism will be supported. for more details. ----------------------------------------------------------------------------- -This file is RCSID $Id: README,v 1.34 2006/04/26 18:19:34 as Exp $ +This file is RCSID $Id: README,v 1.36 2006/10/20 15:43:51 as Exp $ diff --git a/doc/draft-richardson-ipsec-opportunistic.txt b/doc/draft-richardson-ipsec-opportunistic.txt deleted file mode 100644 index 4c87d857a..000000000 --- a/doc/draft-richardson-ipsec-opportunistic.txt +++ /dev/null @@ -1,2688 +0,0 @@ - - -Independent submission M. Richardson -Internet-Draft SSW -Expires: November 19, 2003 D. Redelmeier - Mimosa - May 21, 2003 - - - Opportunistic Encryption using The Internet Key Exchange (IKE) - draft-richardson-ipsec-opportunistic-11.txt - -Status of this Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at http:// - www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on November 19, 2003. - -Copyright Notice - - Copyright (C) The Internet Society (2003). All Rights Reserved. - -Abstract - - This document describes opportunistic encryption (OE) using the - Internet Key Exchange (IKE) and IPsec. Each system administrator - adds new resource records to his or her Domain Name System (DNS) to - support opportunistic encryption. The objective is to allow - encryption for secure communication without any pre-arrangement - specific to the pair of systems involved. - - DNS is used to distribute the public keys of each system involved. - This is resistant to passive attacks. The use of DNS Security - (DNSSEC) secures this system against active attackers as well. - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 1] - -Internet-Draft opportunistic May 2003 - - - As a result, the administrative overhead is reduced from the square - of the number of systems to a linear dependence, and it becomes - possible to make secure communication the default even when the - partner is not known in advance. - - This document is offered up as an Informational RFC. - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 - 3. Specification . . . . . . . . . . . . . . . . . . . . . . . . 10 - 4. Impacts on IKE . . . . . . . . . . . . . . . . . . . . . . . . 21 - 5. DNS issues . . . . . . . . . . . . . . . . . . . . . . . . . . 24 - 6. Network address translation interaction . . . . . . . . . . . 28 - 7. Host implementations . . . . . . . . . . . . . . . . . . . . . 29 - 8. Multi-homing . . . . . . . . . . . . . . . . . . . . . . . . . 30 - 9. Failure modes . . . . . . . . . . . . . . . . . . . . . . . . 32 - 10. Unresolved issues . . . . . . . . . . . . . . . . . . . . . . 34 - 11. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 - 12. Security considerations . . . . . . . . . . . . . . . . . . . 42 - 13. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 44 - 14. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 45 - Normative references . . . . . . . . . . . . . . . . . . . . . 46 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 47 - Full Copyright Statement . . . . . . . . . . . . . . . . . . . 48 - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 2] - -Internet-Draft opportunistic May 2003 - - -1. Introduction - -1.1 Motivation - - The objective of opportunistic encryption is to allow encryption - without any pre-arrangement specific to the pair of systems involved. - Each system administrator adds public key information to DNS records - to support opportunistic encryption and then enables this feature in - the nodes' IPsec stack. Once this is done, any two such nodes can - communicate securely. - - This document describes opportunistic encryption as designed and - mostly implemented by the Linux FreeS/WAN project. For project - information, see http://www.freeswan.org. - - The Internet Architecture Board (IAB) and Internet Engineering - Steering Group (IESG) have taken a strong stand that the Internet - should use powerful encryption to provide security and privacy [4]. - The Linux FreeS/WAN project attempts to provide a practical means to - implement this policy. - - The project uses the IPsec, ISAKMP/IKE, DNS and DNSSEC protocols - because they are standardized, widely available and can often be - deployed very easily without changing hardware or software or - retraining users. - - The extensions to support opportunistic encryption are simple. No - changes to any on-the-wire formats are needed. The only changes are - to the policy decision making system. This means that opportunistic - encryption can be implemented with very minimal changes to an - existing IPsec implementation. - - Opportunistic encryption creates a "fax effect". The proliferation - of the fax machine was possible because it did not require that - everyone buy one overnight. Instead, as each person installed one, - the value of having one increased - as there were more people that - could receive faxes. Once opportunistic encryption is installed it - automatically recognizes other boxes using opportunistic encryption, - without any further configuration by the network administrator. So, - as opportunistic encryption software is installed on more boxes, its - value as a tool increases. - - This document describes the infrastructure to permit deployment of - Opportunistic Encryption. - - The term S/WAN is a trademark of RSA Data Systems, and is used with - permission by this project. - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 3] - -Internet-Draft opportunistic May 2003 - - -1.2 Types of network traffic - - To aid in understanding the relationship between security processing - and IPsec we divide network traffic into four categories: - - * Deny: networks to which traffic is always forbidden. - - * Permit: networks to which traffic in the clear is permitted. - - * Opportunistic tunnel: networks to which traffic is encrypted if - possible, but otherwise is in the clear or fails depending on the - default policy in place. - - * Configured tunnel: networks to which traffic must be encrypted, and - traffic in the clear is never permitted. - - Traditional firewall devices handle the first two categories. No - authentication is required. The permit policy is currently the - default on the Internet. - - This document describes the third category - opportunistic tunnel, - which is proposed as the new default for the Internet. - - Category four, encrypt traffic or drop it, requires authentication of - the end points. As the number of end points is typically bounded and - is typically under a single authority, arranging for distribution of - authentication material, while difficult, does not require any new - technology. The mechanism described here provides an additional way - to distribute the authentication materials, that of a public key - method that does not require deployment of an X.509 based - infrastructure. - - Current Virtual Private Networks can often be replaced by an "OE - paranoid" policy as described herein. - -1.3 Peer authentication in opportunistic encryption - - Opportunistic encryption creates tunnels between nodes that are - essentially strangers. This is done without any prior bilateral - arrangement. There is, therefore, the difficult question of how one - knows to whom one is talking. - - One possible answer is that since no useful authentication can be - done, none should be tried. This mode of operation is named - "anonymous encryption". An active man-in-the-middle attack can be - used to thwart the privacy of this type of communication. Without - peer authentication, there is no way to prevent this kind of attack. - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 4] - -Internet-Draft opportunistic May 2003 - - - Although a useful mode, anonymous encryption is not the goal of this - project. Simpler methods are available that can achieve anonymous - encryption only, but authentication of the peer is a desireable goal. - The latter is achieved through key distribution in DNS, leveraging - upon the authentication of the DNS in DNSSEC. - - Peers are, therefore, authenticated with DNSSEC when available. - Local policy determines how much trust to extend when DNSSEC is not - available. - - However, an essential premise of building private connections with - strangers is that datagrams received through opportunistic tunnels - are no more special than datagrams that arrive in the clear. Unlike - in a VPN, these datagrams should not be given any special exceptions - when it comes to auditing, further authentication or firewalling. - - When initiating outbound opportunistic encryption, local - configuration determines what happens if tunnel setup fails. It may - be that the packet goes out in the clear, or it may be dropped. - -1.4 Use of RFC2119 terms - - The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, - SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL, when they appear in this - document, are to be interpreted as described in [5] - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 5] - -Internet-Draft opportunistic May 2003 - - -2. Overview - -2.1 Reference diagram - - --------------------------------------------------------------------- - - The following network diagram is used in the rest of this document as - the canonical diagram: - - [Q] [R] - . . AS2 - [A]----+----[SG-A].......+....+.......[SG-B]-------[B] - | ...... - AS1 | ..PI.. - | ...... - [D]----+----[SG-D].......+....+.......[C] AS3 - - - - Figure 1: Reference Network Diagram - - --------------------------------------------------------------------- - - In this diagram, there are four end-nodes: A, B, C and D. There are - three gateways, SG-A, SG-B, SG-D. A, D, SG-A and SG-D are part of - the same administrative authority, AS1. SG-A and SG-D are on two - different exit paths from organization 1. SG-B/B is an independent - organization, AS2. Nodes Q and R are nodes on the Internet. PI is - the Public Internet ("The Wild"). - -2.2 Terminology - - The following terminology is used in this document: - - Security gateway: a system that performs IPsec tunnel mode - encapsulation/decapsulation. [SG-x] in the diagram. - - Alice: node [A] in the diagram. When an IP address is needed, this - is 192.1.0.65. - - Bob: node [B] in the diagram. When an IP address is needed, this is - 192.2.0.66. - - Carol: node [C] in the diagram. When an IP address is needed, this - is 192.1.1.67. - - Dave: node [D] in the diagram. When an IP address is needed, this is - 192.3.0.68. - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 6] - -Internet-Draft opportunistic May 2003 - - - SG-A: Alice's security gateway. Internally it is 192.1.0.1, - externally it is 192.1.1.4. - - SG-B: Bob's security gateway. Internally it is 192.2.0.1, externally - it is 192.1.1.5. - - SG-D: Dave's security gateway. Also Alice's backup security gateway. - Internally it is 192.3.0.1, externally it is 192.1.1.6. - - - A single dash represents clear-text datagrams. - - = An equals sign represents phase 2 (IPsec) cipher-text datagrams. - - ~ A single tilde represents clear-text phase 1 datagrams. - - # A hash sign represents phase 1 (IKE) cipher-text datagrams. - - . A period represents an untrusted network of unknown type. - - Configured tunnel: a tunnel that is directly and deliberately hand - configured on participating gateways. Configured tunnels are - typically given a higher level of trust than opportunistic - tunnels. - - Road warrior tunnel: a configured tunnel connecting one node with a - fixed IP address and one node with a variable IP address. A road - warrior (RW) connection must be initiated by the variable node, - since the fixed node cannot know the current address for the road - warrior. - - Anonymous encryption: the process of encrypting a session without any - knowledge of who the other parties are. No authentication of - identities is done. - - Opportunistic encryption: the process of encrypting a session with - authenticated knowledge of who the other parties are. - - Lifetime: the period in seconds (bytes or datagrams) for which a - security association will remain alive before needing to be re- - keyed. - - Lifespan: the effective time for which a security association remains - useful. A security association with a lifespan shorter than its - lifetime would be removed when no longer needed. A security - association with a lifespan longer than its lifetime would need to - be re-keyed one or more times. - - Phase 1 SA: an ISAKMP/IKE security association sometimes referred to - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 7] - -Internet-Draft opportunistic May 2003 - - - as a keying channel. - - Phase 2 SA: an IPsec security association. - - Tunnel: another term for a set of phase 2 SA (one in each direction). - - NAT: Network Address Translation (see [20]). - - NAPT: Network Address and Port Translation (see [20]). - - AS: an autonomous system (AS) is a group of systems (a network) that - are under the administrative control of a single organization. - - Default-free zone: a set of routers that maintain a complete set of - routes to all currently reachable destinations. Having such a - list, these routers never make use of a default route. A datagram - with a destination address not matching any route will be dropped - by such a router. - - -2.3 Model of operation - - The opportunistic encryption security gateway (OE gateway) is a - regular gateway node as described in [2] section 2.4 and [3] with the - additional capabilities described here and in [7]. The algorithm - described here provides a way to determine, for each datagram, - whether or not to encrypt and tunnel the datagram. Two important - things that must be determined are whether or not to encrypt and - tunnel and, if so, the destination address or name of the tunnel end - point which should be used. - -2.3.1 Tunnel authorization - - The OE gateway determines whether or not to create a tunnel based on - the destination address of each packet. Upon receiving a packet with - a destination address not recently seen, the OE gateway performs a - lookup in DNS for an authorization resource record (see Section 5.2). - The record is located using the IP address to perform a search in the - in-addr.arpa (IPv4) or ip6.arpa (IPv6) maps. If an authorization - record is found, the OE gateway interprets this as a request for a - tunnel to be formed. - -2.3.2 Tunnel end-point discovery - - The authorization resource record also provides the address or name - of the tunnel end point which should be used. - - The record may also provide the public RSA key of the tunnel end - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 8] - -Internet-Draft opportunistic May 2003 - - - point itself. This is provided for efficiency only. If the public - RSA key is not present, the OE gateway performs a second lookup to - find a KEY resource record for the end point address or name. - - Origin and integrity protection of the resource records is provided - by DNSSEC ([16]). Section 3.2.4.1 documents an optional restriction - on the tunnel end point if DNSSEC signatures are not available for - the relevant records. - -2.3.3 Caching of authorization results - - The OE gateway maintains a cache, in the forwarding plane, of source/ - destination pairs for which opportunistic encryption has been - attempted. This cache maintains a record of whether or not OE was - successful so that subsequent datagrams can be forwarded properly - without additional delay. - - Successful negotiation of OE instantiates a new security association. - Failure to negotiate OE results in creation of a forwarding policy - entry either to drop or transmit in the clear future datagrams. This - negative cache is necessary to avoid the possibly lengthy process of - repeatedly looking up the same information. - - The cache is timed out periodically, as described in Section 3.4. - This removes entries that are no longer being used and permits the - discovery of changes in authorization policy. - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 9] - -Internet-Draft opportunistic May 2003 - - -3. Specification - - The OE gateway is modeled to have a forwarding plane and a control - plane. A control channel, such as PF_KEY, connects the two planes. - (See [6].) The forwarding plane performs per datagram operations. - The control plane contains a keying daemon, such as ISAKMP/IKE, and - performs all authorization, peer authentication and key derivation - functions. - -3.1 Datagram state machine - - Let the OE gateway maintain a collection of objects -- a superset of - the security policy database (SPD) specified in [7]. For each - combination of source and destination address, an SPD object exists - in one of five following states. Prior to forwarding each datagram, - the responder uses the source and destination addresses to pick an - entry from the SPD. The SPD then determines if and how the packet is - forwarded. - -3.1.1 Non-existent policy - - If the responder does not find an entry, then this policy applies. - The responder creates an entry with an initial state of "hold policy" - and requests keying material from the keying daemon. The responder - does not forward the datagram, rather it attaches the datagram to the - SPD entry as the "first" datagram and retains it for eventual - transmission in a new state. - -3.1.2 Hold policy - - The responder requests keying material. If the interface to the - keying system is lossy (PF_KEY, for instance, can be), the - implementation SHOULD include a mechanism to retransmit the keying - request at a rate limited to less than 1 request per second. The - responder does not forward the datagram. It attaches the datagram to - the SPD entry as the "last" datagram where it is retained for - eventual transmission. If there is a datagram already so stored, - then that already stored datagram is discarded. - - Because the "first" datagram is probably a TCP SYN packet, the - responder retains the "first" datagram in an attempt to avoid waiting - for a TCP retransmit. The responder retains the "last" datagram in - deference to streaming protocols that find it useful to know how much - data has been lost. These are recommendations to decrease latency. - There are no operational requirements for this. - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 10] - -Internet-Draft opportunistic May 2003 - - -3.1.3 Pass-through policy - - The responder forwards the datagram using the normal forwarding - table. The responder enters this state only by command from the - keying daemon, and upon entering this state, also forwards the - "first" and "last" datagrams. - -3.1.4 Deny policy - - The responder discards the datagram. The responder enters this state - only by command from the keying daemon, and upon entering this state, - discards the "first" and "last" datagrams. Local administration - decides if further datagrams cause ICMP messages to be generated - (i.e. ICMP Destination Unreachable, Communication Administratively - Prohibited. type=3, code=13). - -3.1.5 Encrypt policy - - The responder encrypts the datagram using the indicated security - association database (SAD) entry. The responder enters this state - only by command from the keying daemon, and upon entering this state, - releases and forwards the "first" and "last" datagrams using the new - encrypt policy. - - If the associated SAD entry expires because of byte, packet or time - limits, then the entry returns to the Hold policy, and an expire - message is sent to the keying daemon. - - All states may be created directly by the keying daemon while acting - as a responder. - -3.2 Keying state machine - initiator - - Let the keying daemon maintain a collection of objects. Let them be - called "connections" or "conn"s. There are two categories of - connection objects: classes and instances. A class represents an - abstract policy - what could be. An instance represents an actual - connection - what is implemented at the time. - - Let there be two further subtypes of connections: keying channels - (Phase 1 SAs) and data channels (Phase 2 SAs). Each data channel - object may have a corresponding SPD and SAD entry maintained by the - datagram state machine. - - For the purposes of opportunistic encryption, there MUST, at least, - be connection classes known as "deny", "always-clear-text", "OE- - permissive", and "OE-paranoid". The latter two connection classes - define a set of source and/or destination addresses for which - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 11] - -Internet-Draft opportunistic May 2003 - - - opportunistic encryption will be attempted. The administrator MAY - set policy options in a number of additional places. An - implementation MAY create additional connection classes to further - refine these policies. - - The simplest system may need only the "OE-permissive" connection, and - would list its own (single) IP address as the source address of this - policy and the wild-card address 0.0.0.0/0 as the destination IPv4 - address. That is, the simplest policy is to try opportunistic - encryption with all destinations. - - The distinction between permissive and paranoid OE use will become - clear in the state transition differences. In general a permissive - OE will, on failure, install a pass-through policy, while a paranoid - OE will, on failure, install a drop policy. - - In this description of the keying machine's state transitions, the - states associated with the keying system itself are omitted because - they are best documented in the keying system ([8], [9] and [10] for - ISAKMP/IKE), and the details are keying system specific. - Opportunistic encryption is not dependent upon any specific keying - protocol, but this document does provide requirements for those using - ISAKMP/IKE to assure that implementations inter-operate. - - The state transitions that may be involved in communicating with the - forwarding plane are omitted. PF_KEY and similar protocols have - their own set of states required for message sends and completion - notifications. - - Finally, the retransmits and recursive lookups that are normal for - DNS are not included in this description of the state machine. - -3.2.1 Nonexistent connection - - There is no connection instance for a given source/destination - address pair. Upon receipt of a request for keying material for this - source/destination pair, the initiator searches through the - connection classes to determine the most appropriate policy. Upon - determining an appropriate connection class, an instance object is - created of that type. Both of the OE types result in a potential OE - connection. - - Failure to find an appropriate connection class results in an - administrator defined default. - - In each case, when the initiator finds an appropriate class for the - new flow, an instance connection is made of the class which matched. - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 12] - -Internet-Draft opportunistic May 2003 - - -3.2.2 Clear-text connection - - The non-existent connection makes a transition to this state when an - always-clear-text class is instantiated, or when an OE-permissive - connection fails. During the transition, the initiator creates a - pass-through policy object in the forwarding plane for the - appropriate flow. - - Timing out is the only way to leave this state (see Section 3.2.7). - -3.2.3 Deny connection - - The empty connection makes a transition to this state when a deny - class is instantiated, or when an OE-paranoid connection fails. - During the transition, the initiator creates a deny policy object in - the forwarding plane for the appropriate flow. - - Timing out is the only way to leave this state (see Section 3.2.7). - -3.2.4 Potential OE connection - - The empty connection makes a transition to this state when one of - either OE class is instantiated. During the transition to this - state, the initiator creates a hold policy object in the forwarding - plane for the appropriate flow. - - In addition, when making a transition into this state, DNS lookup is - done in the reverse-map for a TXT delegation resource record (see - Section 5.2). The lookup key is the destination address of the flow. - - There are three ways to exit this state: - - 1. DNS lookup finds a TXT delegation resource record. - - 2. DNS lookup does not find a TXT delegation resource record. - - 3. DNS lookup times out. - - Based upon the results of the DNS lookup, the potential OE connection - makes a transition to the pending OE connection state. The - conditions for a successful DNS look are: - - 1. DNS finds an appropriate resource record - - 2. It is properly formatted according to Section 5.2 - - 3. if DNSSEC is enabled, then the signature has been vouched for. - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 13] - -Internet-Draft opportunistic May 2003 - - - Note that if the initiator does not find the public key present in - the TXT delegation record, then the public key must be looked up as a - sub-state. Only successful completion of all the DNS lookups is - considered a success. - - If DNS lookup does not find a resource record or DNS times out, then - the initiator considers the receiver not OE capable. If this is an - OE-paranoid instance, then the potential OE connection makes a - transition to the deny connection state. If this is an OE-permissive - instance, then the potential OE connection makes a transition to the - clear-text connection state. - - If the initiator finds a resource record but it is not properly - formatted, or if DNSSEC is enabled and reports a failure to - authenticate, then the potential OE connection should make a - transition to the deny connection state. This action SHOULD be - logged. If the administrator wishes to override this transition - between states, then an always-clear class can be installed for this - flow. An implementation MAY make this situation a new class. - -3.2.4.1 Restriction on unauthenticated TXT delegation records - - An implementation SHOULD also provide an additional administrative - control on delegation records and DNSSEC. This control would apply - to delegation records (the TXT records in the reverse-map) that are - not protected by DNSSEC. Records of this type are only permitted to - delegate to their own address as a gateway. When this option is - enabled, an active attack on DNS will be unable to redirect packets - to other than the original destination. - -3.2.5 Pending OE connection - - The potential OE connection makes a transition to this state when the - initiator determines that all the information required from the DNS - lookup is present. Upon entering this state, the initiator attempts - to initiate keying to the gateway provided. - - Exit from this state occurs either with a successfully created IPsec - SA, or with a failure of some kind. Successful SA creation results - in a transition to the key connection state. - - Three failures have caused significant problems. They are clearly - not the only possible failures from keying. - - Note that if there are multiple gateways available in the TXT - delegation records, then a failure can only be declared after all - have been tried. Further, creation of a phase 1 SA does not - constitute success. A set of phase 2 SAs (a tunnel) is considered - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 14] - -Internet-Draft opportunistic May 2003 - - - success. - - The first failure occurs when an ICMP port unreachable is - consistently received without any other communication, or when there - is silence from the remote end. This usually means that either the - gateway is not alive, or the keying daemon is not functional. For an - OE-permissive connection, the initiator makes a transition to the - clear-text connection but with a low lifespan. For an OE-pessimistic - connection, the initiator makes a transition to the deny connection - again with a low lifespan. The lifespan in both cases is kept low - because the remote gateway may be in the process of rebooting or be - otherwise temporarily unavailable. - - The length of time to wait for the remote keying daemon to wake up is - a matter of some debate. If there is a routing failure, 5 minutes is - usually long enough for the network to re-converge. Many systems can - reboot in that amount of time as well. However, 5 minutes is far too - long for most users to wait to hear that they can not connect using - OE. Implementations SHOULD make this a tunable parameter. - - The second failure occurs after a phase 1 SA has been created, but - there is either no response to the phase 2 proposal, or the initiator - receives a negative notify (the notify must be authenticated). The - remote gateway is not prepared to do OE at this time. As before, the - initiator makes a transition to the clear-text or the deny connection - based upon connection class, but this time with a normal lifespan. - - The third failure occurs when there is signature failure while - authenticating the remote gateway. This can occur when there has - been a key roll-over, but DNS has not caught up. In this case again, - the initiator makes a transition to the clear-text or the deny - connection based upon the connection class. However, the lifespan - depends upon the remaining time to live in the DNS. (Note that - DNSSEC signed resource records have a different expiry time than non- - signed records.) - -3.2.6 Keyed connection - - The pending OE connection makes a transition to this state when - session keying material (the phase 2 SAs) is derived. The initiator - creates an encrypt policy in the forwarding plane for this flow. - - There are three ways to exit this state. The first is by receipt of - an authenticated delete message (via the keying channel) from the - peer. This is normal teardown and results in a transition to the - expired connection state. - - The second exit is by expiry of the forwarding plane keying material. - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 15] - -Internet-Draft opportunistic May 2003 - - - This starts a re-key operation with a transition back to pending OE - connection. In general, the soft expiry occurs with sufficient time - left to continue to use the keys. A re-key can fail, which may - result in the connection failing to clear-text or deny as - appropriate. In the event of a failure, the forwarding plane policy - does not change until the phase 2 SA (IPsec SA) reaches its hard - expiry. - - The third exit is in response to a negotiation from a remote gateway. - If the forwarding plane signals the control plane that it has - received an unknown SPI from the remote gateway, or an ICMP is - received from the remote gateway indicating an unknown SPI, the - initiator should consider that the remote gateway has rebooted or - restarted. Since these indications are easily forged, the - implementation must exercise care. The initiator should make a - cautious (rate-limited) attempt to re-key the connection. - -3.2.7 Expiring connection - - The initiator will periodically place each of the deny, clear-text, - and keyed connections into this sub-state. See Section 3.4 for more - details of how often this occurs. The initiator queries the - forwarding plane for last use time of the appropriate policy. If the - last use time is relatively recent, then the connection returns to - the previous deny, clear-text or keyed connection state. If not, - then the connection enters the expired connection state. - - The DNS query and answer that lead to the expiring connection state - are also examined. The DNS query may become stale. (A negative, - i.e. no such record, answer is valid for the period of time given by - the MINIMUM field in an attached SOA record. See [12] section - 4.3.4.) If the DNS query is stale, then a new query is made. If the - results change, then the connection makes a transition to a new state - as described in potential OE connection state. - - Note that when considering how stale a connection is, both outgoing - SPD and incoming SAD must be queried as some flows may be - unidirectional for some time. - - Also note that the policy at the forwarding plane is not updated - unless there is a conclusion that there should be a change. - -3.2.8 Expired connection - - Entry to this state occurs when no datagrams have been forwarded - recently via the appropriate SPD and SAD objects. The objects in the - forwarding plane are removed (logging any final byte and packet - counts if appropriate) and the connection instance in the keying - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 16] - -Internet-Draft opportunistic May 2003 - - - plane is deleted. - - The initiator sends an ISAKMP/IKE delete to clean up the phase 2 SAs - as described in Section 3.4. - - Whether or not to delete the phase 1 SAs at this time is left as a - local implementation issue. Implementations that do delete the phase - 1 SAs MUST send authenticated delete messages to indicate that they - are doing so. There is an advantage to keeping the phase 1 SAs until - they expire - they may prove useful again in the near future. - -3.3 Keying state machine - responder - - The responder has a set of objects identical to those of the - initiator. - - The responder receives an invitation to create a keying channel from - an initiator. - -3.3.1 Unauthenticated OE peer - - Upon entering this state, the responder starts a DNS lookup for a KEY - record for the initiator. The responder looks in the reverse-map for - a KEY record for the initiator if the initiator has offered an - ID_IPV4_ADDR, and in the forward map if the initiator has offered an - ID_FQDN type. (See [8] section 4.6.2.1.) - - The responder exits this state upon successful receipt of a KEY from - DNS, and use of the key to verify the signature of the initiator. - - Successful authentication of the peer results in a transition to the - authenticated OE Peer state. - - Note that the unauthenticated OE peer state generally occurs in the - middle of the key negotiation protocol. It is really a form of - pseudo-state. - -3.3.2 Authenticated OE Peer - - The peer will eventually propose one or more phase 2 SAs. The - responder uses the source and destination address in the proposal to - finish instantiating the connection state using the connection class - table. The responder MUST search for an identical connection object - at this point. - - If an identical connection is found, then the responder deletes the - old instance, and the new object makes a transition to the pending OE - connection state. This means that new ISAKMP connections with a - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 17] - -Internet-Draft opportunistic May 2003 - - - given peer will always use the latest instance, which is the correct - one if the peer has rebooted in the interim. - - If an identical connection is not found, then the responder makes the - transition according to the rules given for the initiator. - - Note that if the initiator is in OE-paranoid mode and the responder - is in either always-clear-text or deny, then no communication is - possible according to policy. An implementation is permitted to - create new types of policies such as "accept OE but do not initiate - it". This is a local matter. - -3.4 Renewal and teardown - -3.4.1 Aging - - A potentially unlimited number of tunnels may exist. In practice, - only a few tunnels are used during a period of time. Unused tunnels - MUST, therefore, be torn down. Detecting when tunnels are no longer - in use is the subject of this section. - - There are two methods for removing tunnels: explicit deletion or - expiry. - - Explicit deletion requires an IKE delete message. As the deletes - MUST be authenticated, both ends of the tunnel must maintain the key - channel (phase 1 ISAKMP SA). An implementation which refuses to - either maintain or recreate the keying channel SA will be unable to - use this method. - - The tunnel expiry method, simply allows the IKE daemon to expire - normally without attempting to re-key it. - - Regardless of which method is used to remove tunnels, the - implementation requires a method to determine if the tunnel is still - in use. The specifics are a local matter, but the FreeS/WAN project - uses the following criteria. These criteria are currently - implemented in the key management daemon, but could also be - implemented at the SPD layer using an idle timer. - - Set a short initial (soft) lifespan of 1 minute since many net flows - last only a few seconds. - - At the end of the lifespan, check to see if the tunnel was used by - traffic in either direction during the last 30 seconds. If so, - assign a longer tentative lifespan of 20 minutes after which, look - again. If the tunnel is not in use, then close the tunnel. - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 18] - -Internet-Draft opportunistic May 2003 - - - The expiring state in the key management system (see Section 3.2.7) - implements these timeouts. The timer above may be in the forwarding - plane, but then it must be re-settable. - - The tentative lifespan is independent of re-keying; it is just the - time when the tunnel's future is next considered. (The term lifespan - is used here rather than lifetime for this reason.) Unlike re-keying, - this tunnel use check is not costly and should happen reasonably - frequently. - - A multi-step back-off algorithm is not considered worth the effort - here. - - If the security gateway and the client host are the same and not a - Bump-in-the-Stack or Bump-in-the-Wire implementation, tunnel teardown - decisions MAY pay attention to TCP connection status as reported by - the local TCP layer. A still-open TCP connection is almost a - guarantee that more traffic is expected. Closing of the only TCP - connection through a tunnel is a strong hint that no more traffic is - expected. - -3.4.2 Teardown and cleanup - - Teardown should always be coordinated between the two ends of the - tunnel by interpreting and sending delete notifications. There is a - detailed sub-state in the expired connection state of the key manager - that relates to retransmits of the delete notifications, but this is - considered to be a keying system detail. - - On receiving a delete for the outbound SAs of a tunnel (or some - subset of them), tear down the inbound ones also and notify the - remote end with a delete. If the local system receives a delete for - a tunnel which is no longer in existence, then two delete messages - have crossed paths. Ignore the delete. The operation has already - been completed. Do not generate any messages in this situation. - - Tunnels are to be considered as bidirectional entities, even though - the low-level protocols don't treat them this way. - - When the deletion is initiated locally, rather than as a response to - a received delete, send a delete for (all) the inbound SAs of a - tunnel. If the local system does not receive a responding delete for - the outbound SAs, try re-sending the original delete. Three tries - spaced 10 seconds apart seems a reasonable level of effort. A - failure of the other end to respond after 3 attempts, indicates that - the possibility of further communication is unlikely. Remove the - outgoing SAs. (The remote system may be a mobile node that is no - longer present or powered on.) - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 19] - -Internet-Draft opportunistic May 2003 - - - After re-keying, transmission should switch to using the new outgoing - SAs (ISAKMP or IPsec) immediately, and the old leftover outgoing SAs - should be cleared out promptly (delete should be sent for the - outgoing SAs) rather than waiting for them to expire. This reduces - clutter and minimizes confusion for the operator doing diagnostics. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 20] - -Internet-Draft opportunistic May 2003 - - -4. Impacts on IKE - -4.1 ISAKMP/IKE protocol - - The IKE wire protocol needs no modifications. The major changes are - implementation issues relating to how the proposals are interpreted, - and from whom they may come. - - As opportunistic encryption is designed to be useful between peers - without prior operator configuration, an IKE daemon must be prepared - to negotiate phase 1 SAs with any node. This may require a large - amount of resources to maintain cookie state, as well as large - amounts of entropy for nonces, cookies and so on. - - The major changes to support opportunistic encryption are at the IKE - daemon level. These changes relate to handling of key acquisition - requests, lookup of public keys and TXT records, and interactions - with firewalls and other security facilities that may be co-resident - on the same gateway. - -4.2 Gateway discovery process - - In a typical configured tunnel, the address of SG-B is provided via - configuration. Furthermore, the mapping of an SPD entry to a gateway - is typically a 1:1 mapping. When the 0.0.0.0/0 SPD entry technique - is used, then the mapping to a gateway is determined by the reverse - DNS records. - - The need to do a DNS lookup and wait for a reply will typically - introduce a new state and a new event source (DNS replies) to IKE. - Although a synchronous DNS request can be implemented for proof of - concept, experience is that it can cause very high latencies when a - queue of queries must all timeout in series. - - Use of an asynchronous DNS lookup will also permit overlap of DNS - lookups with some of the protocol steps. - -4.3 Self identification - - SG-A will have to establish its identity. Use an IPv4 ID in phase 1. - - There are many situations where the administrator of SG-A may not be - able to control the reverse DNS records for SG-A's public IP address. - Typical situations include dialup connections and most residential- - type broadband Internet access (ADSL, cable-modem) connections. In - these situations, a fully qualified domain name that is under the - control of SG-A's administrator may be used when acting as an - initiator only. The FQDN ID should be used in phase 1. See Section - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 21] - -Internet-Draft opportunistic May 2003 - - - 5.3 for more details and restrictions. - -4.4 Public key retrieval process - - Upon receipt of a phase 1 SA proposal with either an IPv4 (IPv6) ID - or an FQDN ID, an IKE daemon needs to examine local caches and - configuration files to determine if this is part of a configured - tunnel. If no configured tunnels are found, then the implementation - should attempt to retrieve a KEY record from the reverse DNS in the - case of an IPv4/IPv6 ID, or from the forward DNS in the case of FQDN - ID. - - It is reasonable that if other non-local sources of policy are used - (COPS, LDAP), they be consulted concurrently but some clear ordering - of policy be provided. Note that due to variances in latency, - implementations must wait for positive or negative replies from all - sources of policy before making any decisions. - -4.5 Interactions with DNSSEC - - The implementation described (1.98) neither uses DNSSEC directly to - explicitly verify the authenticity of zone information, nor uses the - NXT records to provide authentication of the absence of a TXT or KEY - record. Rather, this implementation uses a trusted path to a DNSSEC - capable caching resolver. - - To distinguish between an authenticated and an unauthenticated DNS - resource record, a stub resolver capable of returning DNSSEC - information MUST be used. - -4.6 Required proposal types - -4.6.1 Phase 1 parameters - - Main mode MUST be used. - - The initiator MUST offer at least one proposal using some combination - of: 3DES, HMAC-MD5 or HMAC-SHA1, DH group 2 or 5. Group 5 SHOULD be - proposed first. [11] - - The initiator MAY offer additional proposals, but the cipher MUST not - be weaker than 3DES. The initiator SHOULD limit the number of - proposals such that the IKE datagrams do not need to be fragmented. - - The responder MUST accept one of the proposals. If any configuration - of the responder is required then the responder is not acting in an - opportunistic way. - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 22] - -Internet-Draft opportunistic May 2003 - - - SG-A SHOULD use an ID_IPV4_ADDR (ID_IPV6_ADDR for IPv6) of the - external interface of SG-A for phase 1. (There is an exception, see - Section 5.3.) The authentication method MUST be RSA public key - signatures. The RSA key for SG-A SHOULD be placed into a DNS KEY - record in the reverse space of SG-A (i.e. using in-addr.arpa). - -4.6.2 Phase 2 parameters - - SG-A MUST propose a tunnel between Alice and Bob, using 3DES-CBC - mode, MD5 or SHA1 authentication. Perfect Forward Secrecy MUST be - specified. - - Tunnel mode MUST be used. - - Identities MUST be ID_IPV4_ADDR_SUBNET with the mask being /32. - - Authorization for SG-A to act on Alice's behalf is determined by - looking for a TXT record in the reverse-map at Alice's address. - - Compression SHOULD NOT be mandatory. It may be offered as an option. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 23] - -Internet-Draft opportunistic May 2003 - - -5. DNS issues - -5.1 Use of KEY record - - In order to establish their own identities, SG-A and SG-B SHOULD - publish their public keys in their reverse DNS via DNSSEC's KEY - record. See section 3 of RFC 2535 [16]. - - For example: - - KEY 0x4200 4 1 AQNJjkKlIk9...nYyUkKK8 - - 0x4200: The flag bits, indicating that this key is prohibited for - confidentiality use (it authenticates the peer only, a separate - Diffie-Hellman exchange is used for confidentiality), and that - this key is associated with the non-zone entity whose name is the - RR owner name. No other flags are set. - - 4: This indicates that this key is for use by IPsec. - - 1: An RSA key is present. - - AQNJjkKlIk9...nYyUkKK8: The public key of the host as described in - [17]. - - Use of several KEY records allows for key rollover. The SIG Payload - in IKE phase 1 SHOULD be accepted if the public key given by any KEY - RR validates it. - -5.2 Use of TXT delegation record - - Alice publishes a TXT record to provide authorization for SG-A to act - on Alice's behalf. Bob publishes a TXT record to provide - authorization for SG-B to act on Bob's behalf. These records are - located in the reverse DNS (in-addr.arpa) for their respective IP - addresses. The reverse DNS SHOULD be secured by DNSSEC, when it is - deployed. DNSSEC is required to defend against active attacks. - - If Alice's address is P.Q.R.S, then she can authorize another node to - act on her behalf by publishing records at: - - S.R.Q.P.in-addr.arpa - - The contents of the resource record are expected to be a string that - uses the following syntax, as suggested in [15]. (Note that the - reply to query may include other TXT resource records used by other - applications.) - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 24] - -Internet-Draft opportunistic May 2003 - - - --------------------------------------------------------------------- - - - X-IPsec-Server(P)=A.B.C.D KEY - - Figure 2: Format of reverse delegation record - - --------------------------------------------------------------------- - - P: Specifies a precedence for this record. This is similar to MX - record preferences. Lower numbers have stronger preference. - - A.B.C.D: Specifies the IP address of the Security Gateway for this - client machine. - - KEY: Is the encoded RSA Public key of the Security Gateway. The key - is provided here to avoid a second DNS lookup. If this field is - absent, then a KEY resource record should be looked up in the - reverse-map of A.B.C.D. The key is transmitted in base64 format. - - The pieces of the record are separated by any whitespace (space, tab, - newline, carriage return). An ASCII space SHOULD be used. - - In the case where Alice is located at a public address behind a - security gateway that has no fixed address (or no control over its - reverse-map), then Alice may delegate to a public key by domain name. - - --------------------------------------------------------------------- - - - X-IPsec-Server(P)=@FQDN KEY - - Figure 3: Format of reverse delegation record (FQDN version) - - --------------------------------------------------------------------- - - P: Is as above. - - FQDN: Specifies the FQDN that the Security Gateway will identify - itself with. - - KEY: Is the encoded RSA Public key of the Security Gateway. - - If there is more than one such TXT record with strongest (lowest - numbered) precedence, one Security Gateway is picked arbitrarily from - those specified in the strongest-preference records. - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 25] - -Internet-Draft opportunistic May 2003 - - -5.2.1 Long TXT records - - When packed into transport format, TXT records which are longer than - 255 characters are divided into smaller <character-strings>. (See - [13] section 3.3 and 3.3.14.) These MUST be reassembled into a single - string for processing. Whitespace characters in the base64 encoding - are to be ignored. - -5.2.2 Choice of TXT record - - It has been suggested to use the KEY, OPT, CERT, or KX records - instead of a TXT record. None is satisfactory. - - The KEY RR has a protocol field which could be used to indicate a new - protocol, and an algorithm field which could be used to indicate - different contents in the key data. However, the KEY record is - clearly not intended for storing what are really authorizations, it - is just for identities. Other uses have been discouraged. - - OPT resource records, as defined in [14] are not intended to be used - for storage of information. They are not to be loaded, cached or - forwarded. They are, therefore, inappropriate for use here. - - CERT records [18] can encode almost any set of information. A custom - type code could be used permitting any suitable encoding to be - stored, not just X.509. According to the RFC, the certificate RRs - are to be signed internally which may add undesirable and unnecessary - bulk. Larger DNS records may require TCP instead of UDP transfers. - - At the time of protocol design, the CERT RR was not widely deployed - and could not be counted upon. Use of CERT records will be - investigated, and may be proposed in a future revision of this - document. - - KX records are ideally suited for use instead of TXT records, but had - not been deployed at the time of implementation. - -5.3 Use of FQDN IDs - - Unfortunately, not every administrator has control over the contents - of the reverse-map. Where the initiator (SG-A) has no suitable - reverse-map, the authorization record present in the reverse-map of - Alice may refer to a FQDN instead of an IP address. - - In this case, the client's TXT record gives the fully qualified - domain name (FQDN) in place of its security gateway's IP address. - The initiator should use the ID_FQDN ID-payload in phase 1. A - forward lookup for a KEY record on the FQDN must yield the - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 26] - -Internet-Draft opportunistic May 2003 - - - initiator's public key. - - This method can also be used when the external address of SG-A is - dynamic. - - If SG-A is acting on behalf of Alice, then Alice must still delegate - authority for SG-A to do so in her reverse-map. When Alice and SG-A - are one and the same (i.e. Alice is acting as an end-node) then - there is no need for this when initiating only. - - However, Alice must still delegate to herself if she wishes others - to initiate OE to her. See Figure 3. - -5.4 Key roll-over - - Good cryptographic hygiene says that one should replace public/ - private key pairs periodically. Some administrators may wish to do - this as often as daily. Typical DNS propagation delays are - determined by the SOA Resource Record MINIMUM parameter, which - controls how long DNS replies may be cached. For reasonable - operation of DNS servers, administrators usually want this value to - be at least several hours, sometimes as a long as a day. This - presents a problem - a new key MUST not be used prior to it - propagating through DNS. - - This problem is dealt with by having the Security Gateway generate a - new public/private key pair at least MINIMUM seconds in advance of - using it. It then adds this key to the DNS (both as a second KEY - record and in additional TXT delegation records) at key generation - time. Note: only one key is allowed in each TXT record. - - When authenticating, all gateways MUST have available all public keys - that are found in DNS for this entity. This permits the - authenticating end to check both the key for "today" and the key for - "tomorrow". Note that it is the end which is creating the signature - (possesses the private key) that determines which key is to be used. - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 27] - -Internet-Draft opportunistic May 2003 - - -6. Network address translation interaction - - There are no fundamentally new issues for implementing opportunistic - encryption in the presence of network address translation. Rather - there are only the regular IPsec issues with NAT traversal. - - There are several situations to consider for NAT. - -6.1 Co-located NAT/NAPT - - If SG-A is also performing network address translation on behalf of - Alice, then the packet should be translated prior to being subjected - to opportunistic encryption. This is in contrast to typically - configured tunnels which often exist to bridge islands of private - network address space. SG-A will use the translated source address - for phase 2, and so SG-B will look up that address to confirm SG-A's - authorization. - - In the case of NAT (1:1), the address space into which the - translation is done MUST be globally unique, and control over the - reverse-map is assumed. Placing of TXT records is possible. - - In the case of NAPT (m:1), the address will be SG-A. The ability to - get KEY and TXT records in place will again depend upon whether or - not there is administrative control over the reverse-map. This is - identical to situations involving a single host acting on behalf of - itself. FQDN style can be used to get around a lack of a reverse-map - for initiators only. - -6.2 SG-A behind NAT/NAPT - - If there is a NAT or NAPT between SG-A and SG-B, then normal IPsec - NAT traversal rules apply. In addition to the transport problem - which may be solved by other mechanisms, there is the issue of what - phase 1 and phase 2 IDs to use. While FQDN could be used during - phase 1 for SG-A, there is no appropriate ID for phase 2 that permits - SG-B to determine that SG-A is in fact authorized to speak for Alice. - -6.3 Bob is behind a NAT/NAPT - - If Bob is behind a NAT (perhaps SG-B), then there is, in fact, no way - for Alice to address a packet to Bob. Not only is opportunistic - encryption impossible, but it is also impossible for Alice to - initiate any communication to Bob. It may be possible for Bob to - initiate in such a situation. This creates an asymmetry, but this is - common for NAPT. - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 28] - -Internet-Draft opportunistic May 2003 - - -7. Host implementations - - When Alice and SG-A are components of the same system, they are - considered to be a host implementation. The packet sequence scenario - remains unchanged. - - Components marked Alice are the upper layers (TCP, UDP, the - application), and SG-A is the IP layer. - - Note that tunnel mode is still required. - - As Alice and SG-A are acting on behalf of themselves, no TXT based - delegation record is necessary for Alice to initiate. She can rely - on FQDN in a forward map. This is particularly attractive to mobile - nodes such as notebook computers at conferences. To respond, Alice/ - SG-A will still need an entry in Alice's reverse-map. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 29] - -Internet-Draft opportunistic May 2003 - - -8. Multi-homing - - If there are multiple paths between Alice and Bob (as illustrated in - the diagram with SG-D), then additional DNS records are required to - establish authorization. - - In Figure 1, Alice has two ways to exit her network: SG-A and SG-D. - Previously SG-D has been ignored. Postulate that there are routers - between Alice and her set of security gateways (denoted by the + - signs and the marking of an autonomous system number for Alice's - network). Datagrams may, therefore, travel to either SG-A or SG-D en - route to Bob. - - As long as all network connections are in good order, it does not - matter how datagrams exit Alice's network. When they reach either - security gateway, the security gateway will find the TXT delegation - record in Bob's reverse-map, and establish an SA with SG-B. - - SG-B has no problem establishing that either of SG-A or SG-D may - speak for Alice, because Alice has published two equally weighted TXT - delegation records: - - --------------------------------------------------------------------- - - - X-IPsec-Server(10)=192.1.1.5 AQMM...3s1Q== - X-IPsec-Server(10)=192.1.1.6 AAJN...j8r9== - - Figure 4: Multiple gateway delegation example for Alice - - --------------------------------------------------------------------- - - Alice's routers can now do any kind of load sharing needed. Both SG- - A and SG-D send datagrams addressed to Bob through their tunnel to - SG-B. - - Alice's use of non-equal weight delegation records to show preference - of one gateway over another, has relevance only when SG-B is - initiating to Alice. - - If the precedences are the same, then SG-B has a more difficult time. - It must decide which of the two tunnels to use. SG-B has no - information about which link is less loaded, nor which security - gateway has more cryptographic resources available. SG-B, in fact, - has no knowledge of whether both gateways are even reachable. - - The Public Internet's default-free zone may well know a good route to - Alice, but the datagrams that SG-B creates must be addressed to - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 30] - -Internet-Draft opportunistic May 2003 - - - either SG-A or SG-D; they can not be addressed to Alice directly. - - SG-B may make a number of choices: - - 1. It can ignore the problem and round robin among the tunnels. - This causes losses during times when one or the other security - gateway is unreachable. If this worries Alice, she can change - the weights in her TXT delegation records. - - 2. It can send to the gateway from which it most recently received - datagrams. This assumes that routing and reachability are - symmetrical. - - 3. It can listen to BGP information from the Internet to decide - which system is currently up. This is clearly much more - complicated, but if SG-B is already participating in the BGP - peering system to announce Bob, the results data may already be - available to it. - - 4. It can refuse to negotiate the second tunnel. (It is unclear - whether or not this is even an option.) - - 5. It can silently replace the outgoing portion of the first tunnel - with the second one while still retaining the incoming portions - of both. SG-B can, thus, accept datagrams from either SG-A or - SG-D, but send only to the gateway that most recently re-keyed - with it. - - Local policy determines which choice SG-B makes. Note that even if - SG-B has perfect knowledge about the reachability of SG-A and SG-D, - Alice may not be reachable from either of these security gateways - because of internal reachability issues. - - FreeS/WAN implements option 5. Implementing a different option is - being considered. The multi-homing aspects of OE are not well - developed and may be the subject of a future document. - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 31] - -Internet-Draft opportunistic May 2003 - - -9. Failure modes - -9.1 DNS failures - - If a DNS server fails to respond, local policy decides whether or not - to permit communication in the clear as embodied in the connection - classes in Section 3.2. It is easy to mount a denial of service - attack on the DNS server responsible for a particular network's - reverse-map. Such an attack may cause all communication with that - network to go in the clear if the policy is permissive, or fail - completely if the policy is paranoid. Please note that this is an - active attack. - - There are still many networks that do not have properly configured - reverse-maps. Further, if the policy is not to communicate, the - above denial of service attack isolates the target network. - Therefore, the decision of whether or not to permit communication in - the clear MUST be a matter of local policy. - -9.2 DNS configured, IKE failures - - DNS records claim that opportunistic encryption should occur, but the - target gateway either does not respond on port 500, or refuses the - proposal. This may be because of a crash or reboot, a faulty - configuration, or a firewall filtering port 500. - - The receipt of ICMP port, host or network unreachable messages - indicates a potential problem, but MUST NOT cause communication to - fail immediately. ICMP messages are easily forged by attackers. If - such a forgery caused immediate failure, then an active attacker - could easily prevent any encryption from ever occurring, possibly - preventing all communication. - - In these situations a clear log should be produced and local policy - should dictate if communication is then permitted in the clear. - -9.3 System reboots - - Tunnels sometimes go down because the remote end crashes, - disconnects, or has a network link break. In general there is no - notification of this. Even in the event of a crash and successful - reboot, other SGs don't hear about it unless the rebooted SG has - specific reason to talk to them immediately. Over-quick response to - temporary network outages is undesirable. Note that a tunnel can be - torn down and then re-established without any effect visible to the - user except a pause in traffic. On the other hand, if one end - reboots, the other end can't get datagrams to it at all (except via - IKE) until the situation is noticed. So a bias toward quick response - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 32] - -Internet-Draft opportunistic May 2003 - - - is appropriate even at the cost of occasional false alarms. - - A mechanism for recovery after reboot is a topic of current research - and is not specified in this document. - - A deliberate shutdown should include an attempt, using deletes, to - notify all other SGs currently connected by phase 1 SAs that - communication is about to fail. Again, a remote SG will assume this - is a teardown. Attempts by the remote SGs to negotiate new tunnels - as replacements should be ignored. When possible, SGs should attempt - to preserve information about currently-connected SGs in non-volatile - storage, so that after a crash, an Initial-Contact can be sent to - previous partners to indicate loss of all previously established - connections. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 33] - -Internet-Draft opportunistic May 2003 - - -10. Unresolved issues - -10.1 Control of reverse DNS - - The method of obtaining information by reverse DNS lookup causes - problems for people who cannot control their reverse DNS bindings. - This is an unresolved problem in this version, and is out of scope. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 34] - -Internet-Draft opportunistic May 2003 - - -11. Examples - -11.1 Clear-text usage (permit policy) - - Two example scenarios follow. In the first example GW-A (Gateway A) - and GW-B (Gateway B) have always-clear-text policies, and in the - second example they have an OE policy. - - --------------------------------------------------------------------- - - - Alice SG-A DNS SG-B Bob - (1) - ------(2)--------------> - <-----(3)--------------- - (4)----(5)-----> - ----------(6)------> - ------(7)-----> - <------(8)------ - <----------(9)------ - <----(10)----- - (11)-----------> - ----------(12)-----> - --------------> - <--------------- - <------------------- - <------------- - - Figure 5: Timing of regular transaction - - --------------------------------------------------------------------- - - Alice wants to communicate with Bob. Perhaps she wants to retrieve a - web page from Bob's web server. In the absence of opportunistic - encryptors, the following events occur: - - (1) Human or application 'clicks' with a name. - - (2) Application looks up name in DNS to get IP address. - - (3) Resolver returns A record to application. - - (4) Application starts a TCP session or UDP session and OS sends - datagram. - - (5) Datagram is seen at first gateway from Alice (SG-A). (SG-A makes - a transition through Empty connection to always-clear connection - and instantiates a pass-through policy at the forwarding plane.) - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 35] - -Internet-Draft opportunistic May 2003 - - - (6) Datagram is seen at last gateway before Bob (SG-B). - - (7) First datagram from Alice is seen by Bob. - - (8) First return datagram is sent by Bob. - - (9) Datagram is seen at Bob's gateway. (SG-B makes a transition - through Empty connection to always-clear connection and - instantiates a pass-through policy at the forwarding plane.) - - (10) Datagram is seen at Alice's gateway. - - (11) OS hands datagram to application. Alice sends another datagram. - - (12) A second datagram traverses the Internet. - - -11.2 Opportunistic encryption - - In the presence of properly configured opportunistic encryptors, the - event list is extended. - - --------------------------------------------------------------------- - - - Alice SG-A DNS SG-B Bob - (1) - ------(2)--------------> - <-----(3)--------------- - (4)----(5)----->+ - ----(5B)-> - <---(5C)-- - ~~~~~~~~~~~~~(5D)~~~> - <~~~~~~~~~~~~(5E1)~~~ - ~~~~~~~~~~~~~(5E2)~~> - <~~~~~~~~~~~~(5E3)~~~ - #############(5E4)##> - <############(5E5)### - <----(5F1)-- - -----(5F2)-> - #############(5G1)##> - <----(5H1)-- - -----(5H2)-> - <############(5G2)### - #############(5G3)##> - ============(6)====> - ------(7)-----> - <------(8)------ - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 36] - -Internet-Draft opportunistic May 2003 - - - <==========(9)====== - <-----(10)---- - (11)-----------> - ==========(12)=====> - --------------> - <--------------- - <=================== - <------------- - - Figure 6: Timing of opportunistic encryption transaction - - --------------------------------------------------------------------- - - (1) Human or application clicks with a name. - - (2) Application initiates DNS mapping. - - (3) Resolver returns A record to application. - - (4) Application starts a TCP session or UDP. - - (5) SG-A (host or SG) sees datagram to target, and buffers it. - - (5B) SG-A asks DNS for TXT record. - - (5C) DNS returns TXT record(s). - - (5D) Initial IKE Main Mode Packet goes out. - - (5E) IKE ISAKMP phase 1 succeeds. - - (5F) SG-B asks DNS for TXT record to prove SG-A is an agent for - Alice. - - (5G) IKE phase 2 negotiation. - - (5H) DNS lookup by responder (SG-B). - - (6) Buffered datagram is sent by SG-A. - - (7) Datagram is received by SG-B, decrypted, and sent to Bob. - - (8) Bob replies, and datagram is seen by SG-B. - - (9) SG-B already has tunnel up with SG-A, and uses it. - - (10) SG-A decrypts datagram and gives it to Alice. - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 37] - -Internet-Draft opportunistic May 2003 - - - (11) Alice receives datagram. Sends new packet to Bob. - - (12) SG-A gets second datagram, sees that tunnel is up, and uses it. - - For the purposes of this section, we will describe only the changes - that occur between Figure 5 and Figure 6. This corresponds to time - points 5, 6, 7, 9 and 10 on the list above. - -11.2.1 (5) IPsec datagram interception - - At point (5), SG-A intercepts the datagram because this source/ - destination pair lacks a policy (the non-existent policy state). SG- - A creates a hold policy, and buffers the datagram. SG-A requests - keys from the keying daemon. - -11.2.2 (5B) DNS lookup for TXT record - - SG-A's IKE daemon, having looked up the source/destination pair in - the connection class list, creates a new Potential OE connection - instance. SG-A starts DNS queries. - -11.2.3 (5C) DNS returns TXT record(s) - - DNS returns properly formed TXT delegation records, and SG-A's IKE - daemon causes this instance to make a transition from Potential OE - connection to Pending OE connection. - - Using the example above, the returned record might contain: - - --------------------------------------------------------------------- - - - X-IPsec-Server(10)=192.1.1.5 AQMM...3s1Q== - - Figure 7: Example of reverse delegation record for Bob - - --------------------------------------------------------------------- - - with SG-B's IP address and public key listed. - -11.2.4 (5D) Initial IKE main mode packet goes out - - Upon entering Pending OE connection, SG-A sends the initial ISAKMP - message with proposals. See Section 4.6.1. - -11.2.5 (5E1) Message 2 of phase 1 exchange - - SG-B receives the message. A new connection instance is created in - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 38] - -Internet-Draft opportunistic May 2003 - - - the unauthenticated OE peer state. - -11.2.6 (5E2) Message 3 of phase 1 exchange - - SG-A sends a Diffie-Hellman exponent. This is an internal state of - the keying daemon. - -11.2.7 (5E3) Message 4 of phase 1 exchange - - SG-B responds with a Diffie-Hellman exponent. This is an internal - state of the keying protocol. - -11.2.8 (5E4) Message 5 of phase 1 exchange - - SG-A uses the phase 1 SA to send its identity under encryption. The - choice of identity is discussed in Section 4.6.1. This is an - internal state of the keying protocol. - -11.2.9 (5F1) Responder lookup of initiator key - - SG-B asks DNS for the public key of the initiator. DNS looks for a - KEY record by IP address in the reverse-map. That is, a KEY resource - record is queried for 4.1.1.192.in-addr.arpa (recall that SG-A's - external address is 192.1.1.4). SG-B uses the resulting public key - to authenticate the initiator. See Section 5.1 for further details. - -11.2.10 (5F2) DNS replies with public key of initiator - - Upon successfully authenticating the peer, the connection instance - makes a transition to authenticated OE peer on SG-B. - - The format of the TXT record returned is described in Section 5.2. - -11.2.11 (5E5) Responder replies with ID and authentication - - SG-B sends its ID along with authentication material. This is an - internal state for the keying protocol. - -11.2.12 (5G) IKE phase 2 - -11.2.12.1 (5G1) Initiator proposes tunnel - - Having established mutually agreeable authentications (via KEY) and - authorizations (via TXT), SG-A proposes to create an IPsec tunnel for - datagrams transiting from Alice to Bob. This tunnel is established - only for the Alice/Bob combination, not for any subnets that may be - behind SG-A and SG-B. - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 39] - -Internet-Draft opportunistic May 2003 - - -11.2.12.2 (5H1) Responder determines initiator's authority - - While the identity of SG-A has been established, its authority to - speak for Alice has not yet been confirmed. SG-B does a reverse - lookup on Alice's address for a TXT record. - - Upon receiving this specific proposal, SG-B's connection instance - makes a transition into the potential OE connection state. SG-B may - already have an instance, and the check is made as described above. - -11.2.12.3 (5H2) DNS replies with TXT record(s) - - The returned key and IP address should match that of SG-A. - -11.2.12.4 (5G2) Responder agrees to proposal - - Should additional communication occur between, for instance, Dave and - Bob using SG-A and SG-B, a new tunnel (phase 2 SA) would be - established. The phase 1 SA may be reusable. - - SG-A, having successfully keyed the tunnel, now makes a transition - from Pending OE connection to Keyed OE connection. - - The responder MUST setup the inbound IPsec SAs before sending its - reply. - -11.2.12.5 (5G3) Final acknowledgment from initiator - - The initiator agrees with the responder's choice and sets up the - tunnel. The initiator sets up the inbound and outbound IPsec SAs. - - The proper authorization returned with keys prompts SG-B to make a - transition to the keyed OE connection state. - - Upon receipt of this message, the responder may now setup the - outbound IPsec SAs. - -11.2.13 (6) IPsec succeeds, and sets up tunnel for communication between - Alice and Bob - - SG-A sends the datagram saved at step (5) through the newly created - tunnel to SG-B, where it gets decrypted and forwarded. Bob receives - it at (7) and replies at (8). - -11.2.14 (9) SG-B already has tunnel up with G1 and uses it - - At (9), SG-B has already established an SPD entry mapping Bob->Alice - via a tunnel, so this tunnel is simply applied. The datagram is - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 40] - -Internet-Draft opportunistic May 2003 - - - encrypted to SG-A, decrypted by SG-A and passed to Alice at (10). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 41] - -Internet-Draft opportunistic May 2003 - - -12. Security considerations - -12.1 Configured vs opportunistic tunnels - - Configured tunnels are those which are setup using bilateral - mechanisms: exchanging public keys (raw RSA, DSA, PKIX), pre-shared - secrets, or by referencing keys that are in known places - (distinguished name from LDAP, DNS). These keys are then used to - configure a specific tunnel. - - A pre-configured tunnel may be on all the time, or may be keyed only - when needed. The end points of the tunnel are not necessarily - static: many mobile applications (road warrior) are considered to be - configured tunnels. - - The primary characteristic is that configured tunnels are assigned - specific security properties. They may be trusted in different ways - relating to exceptions to firewall rules, exceptions to NAT - processing, and to bandwidth or other quality of service - restrictions. - - Opportunistic tunnels are not inherently trusted in any strong way. - They are created without prior arrangement. As the two parties are - strangers, there MUST be no confusion of datagrams that arrive from - opportunistic peers and those that arrive from configured tunnels. A - security gateway MUST take care that an opportunistic peer can not - impersonate a configured peer. - - Ingress filtering MUST be used to make sure that only datagrams - authorized by negotiation (and the concomitant authentication and - authorization) are accepted from a tunnel. This is to prevent one - peer from impersonating another. - - An implementation suggestion is to treat opportunistic tunnel - datagrams as if they arrive on a logical interface distinct from - other configured tunnels. As the number of opportunistic tunnels - that may be created automatically on a system is potentially very - high, careful attention to scaling should be taken into account. - - As with any IKE negotiation, opportunistic encryption cannot be - secure without authentication. Opportunistic encryption relies on - DNS for its authentication information and, therefore, cannot be - fully secure without a secure DNS. Without secure DNS, opportunistic - encryption can protect against passive eavesdropping but not against - active man-in-the-middle attacks. - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 42] - -Internet-Draft opportunistic May 2003 - - -12.2 Firewalls versus Opportunistic Tunnels - - Typical usage of per datagram access control lists is to implement - various kinds of security gateways. These are typically called - "firewalls". - - Typical usage of a virtual private network (VPN) within a firewall is - to bypass all or part of the access controls between two networks. - Additional trust (as outlined in the previous section) is given to - datagrams that arrive in the VPN. - - Datagrams that arrive via opportunistically configured tunnels MUST - not be trusted. Any security policy that would apply to a datagram - arriving in the clear SHOULD also be applied to datagrams arriving - opportunistically. - -12.3 Denial of service - - There are several different forms of denial of service that an - implementor should concern themselves with. Most of these problems - are shared with security gateways that have large numbers of mobile - peers (road warriors). - - The design of ISAKMP/IKE, and its use of cookies, defend against many - kinds of denial of service. Opportunism changes the assumption that - if the phase 1 (ISAKMP) SA is authenticated, that it was worthwhile - creating. Because the gateway will communicate with any machine, it - is possible to form phase 1 SAs with any machine on the Internet. - - - - - - - - - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 43] - -Internet-Draft opportunistic May 2003 - - -13. IANA Considerations - - There are no known numbers which IANA will need to manage. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 44] - -Internet-Draft opportunistic May 2003 - - -14. Acknowledgments - - Substantive portions of this document are based upon previous work by - Henry Spencer. - - Thanks to Tero Kivinen, Sandy Harris, Wes Hardarker, Robert - Moskowitz, Jakob Schlyter, Bill Sommerfeld, John Gilmore and John - Denker for their comments and constructive criticism. - - Sandra Hoffman and Bill Dickie did the detailed proof reading and - editing. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 45] - -Internet-Draft opportunistic May 2003 - - -Normative references - - [1] Redelmeier, D. and H. Spencer, "Opportunistic Encryption", - paper http://www.freeswan.org/freeswan_trees/freeswan-1.91/doc/ - opportunism.spec, May 2001. - - [2] Defense Advanced Research Projects Agency (DARPA), Information - Processing Techniques Office and University of Southern - California (USC)/Information Sciences Institute, "Internet - Protocol", STD 5, RFC 791, September 1981. - - [3] Braden, R. and J. Postel, "Requirements for Internet gateways", - RFC 1009, June 1987. - - [4] IAB, IESG, Carpenter, B. and F. Baker, "IAB and IESG Statement - on Cryptographic Technology and the Internet", RFC 1984, August - 1996. - - [5] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - [6] McDonald, D., Metz, C. and B. Phan, "PF_KEY Key Management API, - Version 2", RFC 2367, July 1998. - - [7] Kent, S. and R. Atkinson, "Security Architecture for the - Internet Protocol", RFC 2401, November 1998. - - [8] Piper, D., "The Internet IP Security Domain of Interpretation - for ISAKMP", RFC 2407, November 1998. - - [9] Maughan, D., Schneider, M. and M. Schertler, "Internet Security - Association and Key Management Protocol (ISAKMP)", RFC 2408, - November 1998. - - [10] Harkins, D. and D. Carrel, "The Internet Key Exchange (IKE)", - RFC 2409, November 1998. - - [11] Kivinen, T. and M. Kojo, "More MODP Diffie-Hellman groups for - IKE", RFC 3526, March 2003. - - [12] Mockapetris, P., "Domain names - concepts and facilities", STD - 13, RFC 1034, November 1987. - - [13] Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - [14] Vixie, P., "Extension Mechanisms for DNS (EDNS0)", RFC 2671, - August 1999. - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 46] - -Internet-Draft opportunistic May 2003 - - - [15] Rosenbaum, R., "Using the Domain Name System To Store Arbitrary - String Attributes", RFC 1464, May 1993. - - [16] Eastlake, D., "Domain Name System Security Extensions", RFC - 2535, March 1999. - - [17] Eastlake, D., "RSA/SHA-1 SIGs and RSA KEYs in the Domain Name - System (DNS)", RFC 3110, May 2001. - - [18] Eastlake, D. and O. Gudmundsson, "Storing Certificates in the - Domain Name System (DNS)", RFC 2538, March 1999. - - [19] Durham, D., Boyle, J., Cohen, R., Herzog, S., Rajan, R. and A. - Sastry, "The COPS (Common Open Policy Service) Protocol", RFC - 2748, January 2000. - - [20] Srisuresh, P. and M. Holdrege, "IP Network Address Translator - (NAT) Terminology and Considerations", RFC 2663, August 1999. - - -Authors' Addresses - - Michael C. Richardson - Sandelman Software Works - 470 Dawson Avenue - Ottawa, ON K1Z 5V7 - CA - - EMail: mcr@sandelman.ottawa.on.ca - URI: http://www.sandelman.ottawa.on.ca/ - - - D. Hugh Redelmeier - Mimosa - Toronto, ON - CA - - EMail: hugh@mimosa.com - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 47] - -Internet-Draft opportunistic May 2003 - - -Full Copyright Statement - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - -Richardson & Redelmeier Expires November 19, 2003 [Page 48] - diff --git a/doc/draft-richardson-ipsec-rr.txt b/doc/draft-richardson-ipsec-rr.txt deleted file mode 100644 index 7c229b8e1..000000000 --- a/doc/draft-richardson-ipsec-rr.txt +++ /dev/null @@ -1,840 +0,0 @@ - - -IPSECKEY WG M. Richardson -Internet-Draft SSW -Expires: March 4, 2004 September 4, 2003 - - - A method for storing IPsec keying material in DNS. - draft-ietf-ipseckey-rr-07.txt - -Status of this Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at http:// - www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on March 4, 2004. - -Copyright Notice - - Copyright (C) The Internet Society (2003). All Rights Reserved. - -Abstract - - This document describes a new resource record for DNS. This record - may be used to store public keys for use in IPsec systems. - - This record replaces the functionality of the sub-type #1 of the KEY - Resource Record, which has been obsoleted by RFC3445. - - - - - - - - - - -Richardson Expires March 4, 2004 [Page 1] - -Internet-Draft ipsecrr September 2003 - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 1.2 Usage Criteria . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. Storage formats . . . . . . . . . . . . . . . . . . . . . . . 4 - 2.1 IPSECKEY RDATA format . . . . . . . . . . . . . . . . . . . . 4 - 2.2 RDATA format - precedence . . . . . . . . . . . . . . . . . . 4 - 2.3 RDATA format - algorithm type . . . . . . . . . . . . . . . . 4 - 2.4 RDATA format - gateway type . . . . . . . . . . . . . . . . . 4 - 2.5 RDATA format - gateway . . . . . . . . . . . . . . . . . . . . 5 - 2.6 RDATA format - public keys . . . . . . . . . . . . . . . . . . 5 - 3. Presentation formats . . . . . . . . . . . . . . . . . . . . . 7 - 3.1 Representation of IPSECKEY RRs . . . . . . . . . . . . . . . . 7 - 3.2 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 - 4. Security Considerations . . . . . . . . . . . . . . . . . . . 9 - 4.1 Active attacks against unsecured IPSECKEY resource records . . 9 - 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 11 - 6. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 12 - Normative references . . . . . . . . . . . . . . . . . . . . . 13 - Non-normative references . . . . . . . . . . . . . . . . . . . 14 - Author's Address . . . . . . . . . . . . . . . . . . . . . . . 14 - Full Copyright Statement . . . . . . . . . . . . . . . . . . . 15 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson Expires March 4, 2004 [Page 2] - -Internet-Draft ipsecrr September 2003 - - -1. Introduction - - The type number for the IPSECKEY RR is TBD. - -1.1 Overview - - The IPSECKEY resource record (RR) is used to publish a public key - that is to be associated with a Domain Name System (DNS) name for use - with the IPsec protocol suite. This can be the public key of a - host, network, or application (in the case of per-port keying). - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in RFC2119 [8]. - -1.2 Usage Criteria - - An IPSECKEY resource record SHOULD be used in combination with DNSSEC - unless some other means of authenticating the IPSECKEY resource - record is available. - - It is expected that there will often be multiple IPSECKEY resource - records at the same name. This will be due to the presence of - multiple gateways and the need to rollover keys. - - This resource record is class independent. - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson Expires March 4, 2004 [Page 3] - -Internet-Draft ipsecrr September 2003 - - -2. Storage formats - -2.1 IPSECKEY RDATA format - - The RDATA for an IPSECKEY RR consists of a precedence value, a public - key, algorithm type, and an optional gateway address. - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | precedence | gateway type | algorithm | gateway | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------+ + - ~ gateway ~ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | / - / public key / - / / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| - - -2.2 RDATA format - precedence - - This is an 8-bit precedence for this record. This is interpreted in - the same way as the PREFERENCE field described in section 3.3.9 of - RFC1035 [2]. - - Gateways listed in IPSECKEY records with lower precedence are to be - attempted first. Where there is a tie in precedence, the order - should be non-deterministic. - -2.3 RDATA format - algorithm type - - The algorithm type field identifies the public key's cryptographic - algorithm and determines the format of the public key field. - - A value of 0 indicates that no key is present. - - The following values are defined: - - 1 A DSA key is present, in the format defined in RFC2536 [11] - - 2 A RSA key is present, in the format defined in RFC3110 [12] - - -2.4 RDATA format - gateway type - - The gateway type field indicates the format of the information that - is stored in the gateway field. - - - -Richardson Expires March 4, 2004 [Page 4] - -Internet-Draft ipsecrr September 2003 - - - The following values are defined: - - 0 No gateway is present - - 1 A 4-byte IPv4 address is present - - 2 A 16-byte IPv6 address is present - - 3 A wire-encoded domain name is present. The wire-encoded format is - self-describing, so the length is implicit. The domain name MUST - NOT be compressed. - - -2.5 RDATA format - gateway - - The gateway field indicates a gateway to which an IPsec tunnel may be - created in order to reach the entity named by this resource record. - - There are three formats: - - A 32-bit IPv4 address is present in the gateway field. The data - portion is an IPv4 address as described in section 3.4.1 of RFC1035 - [2]. This is a 32-bit number in network byte order. - - A 128-bit IPv6 address is present in the gateway field. The data - portion is an IPv6 address as described in section 2.2 of RFC1886 - [7]. This is a 128-bit number in network byte order. - - The gateway field is a normal wire-encoded domain name, as described - in section 3.3 of RFC1035 [2]. Compression MUST NOT be used. - -2.6 RDATA format - public keys - - Both of the public key types defined in this document (RSA and DSA) - inherit their public key formats from the corresponding KEY RR - formats. Specifically, the public key field contains the algorithm- - specific portion of the KEY RR RDATA, which is all of the KEY RR DATA - after the first four octets. This is the same portion of the KEY RR - that must be specified by documents that define a DNSSEC algorithm. - Those documents also specify a message digest to be used for - generation of SIG RRs; that specification is not relevant for - IPSECKEY RR. - - Future algorithms, if they are to be used by both DNSSEC (in the KEY - RR) and IPSECKEY, are likely to use the same public key encodings in - both records. Unless otherwise specified, the IPSECKEY public key - field will contain the algorithm-specific portion of the KEY RR RDATA - for the corresponding algorithm. The algorithm must still be - - - -Richardson Expires March 4, 2004 [Page 5] - -Internet-Draft ipsecrr September 2003 - - - designated for use by IPSECKEY, and an IPSECKEY algorithm type number - (which might be different than the DNSSEC algorithm number) must be - assigned to it. - - The DSA key format is defined in RFC2536 [11] - - The RSA key format is defined in RFC3110 [12], with the following - changes: - - The earlier definition of RSA/MD5 in RFC2065 limited the exponent and - modulus to 2552 bits in length. RFC3110 extended that limit to 4096 - bits for RSA/SHA1 keys. The IPSECKEY RR imposes no length limit on - RSA public keys, other than the 65535 octet limit imposed by the two- - octet length encoding. This length extension is applicable only to - IPSECKEY and not to KEY RRs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson Expires March 4, 2004 [Page 6] - -Internet-Draft ipsecrr September 2003 - - -3. Presentation formats - -3.1 Representation of IPSECKEY RRs - - IPSECKEY RRs may appear in a zone data master file. The precedence, - gateway type and algorithm and gateway fields are REQUIRED. The - base64 encoded public key block is OPTIONAL; if not present, then the - public key field of the resource record MUST be construed as being - zero octets in length. - - The algorithm field is an unsigned integer. No mnemonics are - defined. - - If no gateway is to be indicated, then the gateway type field MUST be - zero, and the gateway field MUST be "." - - The Public Key field is represented as a Base64 encoding of the - Public Key. Whitespace is allowed within the Base64 text. For a - definition of Base64 encoding, see RFC1521 [3] Section 5.2. - - The general presentation for the record as as follows: - - IN IPSECKEY ( precedence gateway-type algorithm - gateway base64-encoded-public-key ) - - -3.2 Examples - - An example of a node 192.0.2.38 that will accept IPsec tunnels on its - own behalf. - - 38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 - 192.0.2.38 - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) - - An example of a node, 192.0.2.38 that has published its key only. - - 38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 0 2 - . - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) - - An example of a node, 192.0.2.38 that has delegated authority to the - node 192.0.2.3. - - 38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 - 192.0.2.3 - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) - - - - -Richardson Expires March 4, 2004 [Page 7] - -Internet-Draft ipsecrr September 2003 - - - An example of a node, 192.0.1.38 that has delegated authority to the - node with the identity "mygateway.example.com". - - 38.1.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 3 2 - mygateway.example.com. - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) - - An example of a node, 2001:0DB8:0200:1:210:f3ff:fe03:4d0 that has - delegated authority to the node 2001:0DB8:c000:0200:2::1 - - $ORIGIN 1.0.0.0.0.0.2.8.B.D.0.1.0.0.2.ip6.int. - 0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0 7200 IN IPSECKEY ( 10 2 2 - 2001:0DB8:0:8002::2000:1 - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson Expires March 4, 2004 [Page 8] - -Internet-Draft ipsecrr September 2003 - - -4. Security Considerations - - This entire memo pertains to the provision of public keying material - for use by key management protocols such as ISAKMP/IKE (RFC2407) [9]. - - The IPSECKEY resource record contains information that SHOULD be - communicated to the end client in an integral fashion - i.e. free - from modification. The form of this channel is up to the consumer of - the data - there must be a trust relationship between the end - consumer of this resource record and the server. This relationship - may be end-to-end DNSSEC validation, a TSIG or SIG(0) channel to - another secure source, a secure local channel on the host, or some - combination of the above. - - The keying material provided by the IPSECKEY resource record is not - sensitive to passive attacks. The keying material may be freely - disclosed to any party without any impact on the security properties - of the resulting IPsec session: IPsec and IKE provide for defense - against both active and passive attacks. - - Any user of this resource record MUST carefully document their trust - model, and why the trust model of DNSSEC is appropriate, if that is - the secure channel used. - -4.1 Active attacks against unsecured IPSECKEY resource records - - This section deals with active attacks against the DNS. These - attacks require that DNS requests and responses be intercepted and - changed. DNSSEC is designed to defend against attacks of this kind. - - The first kind of active attack is when the attacker replaces the - keying material with either a key under its control or with garbage. - - If the attacker is not able to mount a subsequent man-in-the-middle - attack on the IKE negotiation after replacing the public key, then - this will result in a denial of service, as the authenticator used by - IKE would fail. - - If the attacker is able to both to mount active attacks against DNS - and is also in a position to perform a man-in-the-middle attack on - IKE and IPsec negotiations, then the attacker will be in a position - to compromise the resulting IPsec channel. Note that an attacker - must be able to perform active DNS attacks on both sides of the IKE - negotiation in order for this to succeed. - - The second kind of active attack is one in which the attacker - replaces the the gateway address to point to a node under the - attacker's control. The attacker can then either replace the public - - - -Richardson Expires March 4, 2004 [Page 9] - -Internet-Draft ipsecrr September 2003 - - - key or remove it, thus providing an IPSECKEY record of its own to - match the gateway address. - - This later form creates a simple man-in-the-middle since the attacker - can then create a second tunnel to the real destination. Note that, - as before, this requires that the attacker also mount an active - attack against the responder. - - Note that the man-in-the-middle can not just forward cleartext - packets to the original destination. While the destination may be - willing to speak in the clear, replying to the original sender, the - sender will have already created a policy expecting ciphertext. - Thus, the attacker will need to intercept traffic from both sides. - In some cases, the attacker may be able to accomplish the full - intercept by use of Network Addresss/Port Translation (NAT/NAPT) - technology. - - Note that the danger here only applies to cases where the gateway - field of the IPSECKEY RR indicates a different entity than the owner - name of the IPSECKEY RR. In cases where the end-to-end integrity of - the IPSECKEY RR is suspect, the end client MUST restrict its use of - the IPSECKEY RR to cases where the RR owner name matches the content - of the gateway field. - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson Expires March 4, 2004 [Page 10] - -Internet-Draft ipsecrr September 2003 - - -5. IANA Considerations - - This document updates the IANA Registry for DNS Resource Record Types - by assigning type X to the IPSECKEY record. - - This document creates an IANA registry for the algorithm type field. - - Values 0, 1 and 2 are defined in Section 2.3. Algorithm numbers 3 - through 255 can be assigned by IETF Consensus (see RFC2434 [6]). - - This document creates an IANA registry for the gateway type field. - - Values 0, 1, 2 and 3 are defined in Section 2.4. Algorithm numbers 4 - through 255 can be assigned by Standards Action (see RFC2434 [6]). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson Expires March 4, 2004 [Page 11] - -Internet-Draft ipsecrr September 2003 - - -6. Acknowledgments - - My thanks to Paul Hoffman, Sam Weiler, Jean-Jacques Puig, Rob - Austein, and Olafur Gurmundsson who reviewed this document carefully. - Additional thanks to Olafur Gurmundsson for a reference - implementation. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson Expires March 4, 2004 [Page 12] - -Internet-Draft ipsecrr September 2003 - - -Normative references - - [1] Mockapetris, P., "Domain names - concepts and facilities", STD - 13, RFC 1034, November 1987. - - [2] Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - [3] Borenstein, N. and N. Freed, "MIME (Multipurpose Internet Mail - Extensions) Part One: Mechanisms for Specifying and Describing - the Format of Internet Message Bodies", RFC 1521, September - 1993. - - [4] Bradner, S., "The Internet Standards Process -- Revision 3", BCP - 9, RFC 2026, October 1996. - - [5] Eastlake, D. and C. Kaufman, "Domain Name System Security - Extensions", RFC 2065, January 1997. - - [6] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA - Considerations Section in RFCs", BCP 26, RFC 2434, October 1998. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Richardson Expires March 4, 2004 [Page 13] - -Internet-Draft ipsecrr September 2003 - - -Non-normative references - - [7] Thomson, S. and C. Huitema, "DNS Extensions to support IP - version 6", RFC 1886, December 1995. - - [8] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - [9] Piper, D., "The Internet IP Security Domain of Interpretation - for ISAKMP", RFC 2407, November 1998. - - [10] Eastlake, D., "Domain Name System Security Extensions", RFC - 2535, March 1999. - - [11] Eastlake, D., "DSA KEYs and SIGs in the Domain Name System - (DNS)", RFC 2536, March 1999. - - [12] Eastlake, D., "RSA/SHA-1 SIGs and RSA KEYs in the Domain Name - System (DNS)", RFC 3110, May 2001. - - [13] Massey, D. and S. Rose, "Limiting the Scope of the KEY Resource - Record (RR)", RFC 3445, December 2002. - - -Author's Address - - Michael C. Richardson - Sandelman Software Works - 470 Dawson Avenue - Ottawa, ON K1Z 5V7 - CA - - EMail: mcr@sandelman.ottawa.on.ca - URI: http://www.sandelman.ottawa.on.ca/ - - - - - - - - - - - - - - - - - -Richardson Expires March 4, 2004 [Page 14] - -Internet-Draft ipsecrr September 2003 - - -Full Copyright Statement - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - -Richardson Expires March 4, 2004 [Page 15] - diff --git a/doc/draft-spencer-ipsec-ike-implementation.nr b/doc/draft-spencer-ipsec-ike-implementation.nr deleted file mode 100644 index 5b5776e22..000000000 --- a/doc/draft-spencer-ipsec-ike-implementation.nr +++ /dev/null @@ -1,1203 +0,0 @@ -.\" date, expiry date, copyright year, and revision -.DA "26 Feb 2002" -.ds e "26 Aug 2002 -.ds c 2002 -.ds r 02 -.\" boilerplate -.pl 10i -.nr PL 10i -.po 0 -.nr PO 0 -.ll 7.2i -.nr LL 7.2i -.lt 7.2i -.nr LT 7.2i -.hy 0 -.nr HY 0 -.ad l -.nr PD 1v -.\" macros for paragraph, section header, reference, TOC -.de P -.br -.LP -.in 3 -.. -.de H -.br -.ne 5 -.LP -.in 0 -.. -.de R -.IP " [\\$1]" 14 -.. -.de T -.ie \\$1=1 \{\ -.nf -.ta \n(LLu-3nR -.\} -.el \{\ -.fi -.\} -.. -.de S -.ie '\\$1'' \\$2 \a \\$3 -.el \\$1. \\$2 \a \\$3 -.. -.\" headers/footers -.ds LH "Internet Draft -.ds CH "IKE Implementation Issues -.ds RH "\*(DY -.ds LF "Spencer & Redelmeier -.ds CF " -.ds RF "[Page %] -.\" and let's get started -.RT -.nf -.tl 'Network Working Group''Henry Spencer' -.tl 'Internet Draft''SP Systems' -.tl 'Expires: \*e''D. Hugh Redelmeier' -.tl '''Mimosa Systems' -.tl '''\*(DY' -.sp -.ce 99 -IKE Implementation Issues -<draft-spencer-ipsec-ike-implementation-\*r.txt> -.ce 0 -.H -Status of this Memo -.P -This document is an Internet-Draft and is in full conformance with -all provisions of Section 10 of RFC2026. -.P -(If approved as an Informational RFC...) -This memo provides information for the Internet community. -This memo does not specify an Internet standard of any kind. -.P -Distribution of this memo is unlimited. -.P -Internet-Drafts are working documents of the Internet Engineering -Task Force (IETF), its areas, and its working groups. -Note that -other groups may also distribute working documents as Internet-Drafts. -.P -Internet-Drafts are draft documents valid for a maximum of six months -and may be updated, replaced, or obsoleted by other documents at any -time. -It is inappropriate to use Internet-Drafts as reference -material or to cite them other than as "work in progress." -.P -The list of current Internet-Drafts can be accessed at -http://www.ietf.org/ietf/1id-abstracts.txt. -.P -The list of Internet-Draft Shadow Directories can be accessed at -http://www.ietf.org/shadow.html. -.P -This Internet-Draft will expire on \*e. -.H -Copyright Notice -.P -Copyright (C) The Internet Society \*c. All Rights Reserved. -.bp -.H -Table of Contents -.P -.T 1 -.S "1" "Introduction" "3" -.S "2" "Lower-level Background and Notes" "4" -.S "2.1" "Packet Handling" "4" -.S "2.2" "Ciphers" "5" -.S "2.3" "Interfaces" "5" -.S "3" "IKE Infrastructural Issues" "5" -.S "3.1" "Continuous Channel" "5" -.S "3.2" "Retransmission" "5" -.S "3.3" "Replay Prevention" "6" -.S "4" "Basic Keying and Rekeying" "7" -.S "4.1" "When to Create SAs" "7" -.S "4.2" "When to Rekey" "8" -.S "4.3" "Choosing an SA" "9" -.S "4.4" "Why to Rekey" "9" -.S "4.5" "Rekeying ISAKMP SAs" "10" -.S "4.6" "Bulk Negotiation" "10" -.S "5" "Deletions, Teardowns, Crashes" "11" -.S "5.1" "Deletions" "11" -.S "5.2" "Teardowns and Shutdowns" "12" -.S "5.3" "Crashes" "13" -.S "5.4" "Network Partitions" "13" -.S "5.5" "Unknown SAs" "14" -.S "6" "Misc. IKE Issues" "16" -.S "6.1" "Groups 1 and 5" "16" -.S "6.2" "To PFS Or Not To PFS" "16" -.S "6.3" "Debugging Tools, Lack Thereof" "16" -.S "6.4" "Terminology, Vagueness Thereof" "17" -.S "6.5" "A Question of Identity" "17" -.S "6.6" "Opportunistic Encryption" "17" -.S "6.7" "Authentication and RSA Keys" "17" -.S "6.8" "Misc. Snags" "18" -.S "7" "Security Considerations" "19" -.S "8" "References" "19" -.S "" "Authors' Addresses" "20" -.S "" "Full Copyright Statement" "21" -.T 0 -.bp -.H -Abstract -.P -The current IPsec specifications for key exchange and connection management, -RFCs 2408 [ISAKMP] and 2409 [IKE], -leave many aspects of connection management unspecified, -most prominently rekeying practices. -Pending clarifications in future revisions of the specifications, -this document sets down some successful experiences, -to minimize the extent to which new implementors have to rely -on unwritten folklore. -.P -The Linux FreeS/WAN implementation of IPsec interoperates -with almost every other IPsec implementation. -This document describes how the FreeS/WAN project has resolved -some of the gaps in the IPsec specifications -(and plans to resolve some others), -and what difficulties have been encountered, -in hopes that this generally-successful experience -might be informative to new implementors. -.P -This is offered as an Informational RFC. -.P -This -\*r revision mainly: -discusses ISAKMP SA expiry during IPsec-SA rekeying (4.5), -revises the discussion of bidirectional Deletes (5.1), -suggests remembering the parameters of successful negotiations -for later use (4.2, 5.3), -notes an unsuccessful negotiation from the other end as a hint of a possibly -broken connection (5.5), -and adds sections on network partitions (5.4), -authentication methods and the subtleties of RSA public keys (6.7), -and miscellaneous interoperability concerns (6.8). -.H -1. Introduction -.P -The current IPsec specifications for key exchange and connection management, -RFCs 2408 [ISAKMP] and 2409 [IKE], -leave many aspects of connection management unspecified, -most prominently rekeying practices. -This is a cryptic puzzle which -each group of implementors has to struggle with, -and differences in how the ambiguities and gaps are resolved are -potentially a fruitful source of interoperability problems. -We can hope that future revisions of the specifications will clear this up. -Meanwhile, it seems useful to set down some successful experiences, -to minimize the extent to which new implementors have to rely -on unwritten folklore. -.P -The Linux FreeS/WAN implementation of IPsec interoperates -with almost every other IPsec implementation, -and because of its free nature, -it also sees some use as a reference implementation by other implementors. -The high degree of interoperability is noteworthy -given its organizers' strong minimalist bias, -which has caused them to implement only -a small subset of the full glory of IPsec. -This document describes how the FreeS/WAN project has resolved -some of the gaps in the IPsec specifications -(and plans to resolve some others), -and what difficulties have been encountered, -in hopes that this generally-successful experience -might be informative to new implementors. -.P -One small caution about applicability: -this experience may not be relevant -to severely resource-constrained implementations. -FreeS/WAN's target environment is previous-generation PCs, -now available at trivial cost (often, -within an organization, at no cost), -which have quite impressive CPU power and memory by the standards -of only a few years ago. -Some of the approaches discussed here may be inapplicable to -implementations with severe external constraints which prevent them -from taking advantage of modern hardware technology. -.H -2. Lower-level Background and Notes -.H -2.1. Packet Handling -.P -FreeS/WAN implements ESP [ESP] and AH [AH] straightforwardly, -although AH sees little use among our users. -Our ESP/AH implementation cannot currently handle packets -with IP options; -somewhat surprisingly, this has caused little difficulty. -We insist on encryption and do not support authentication-only -connections, and this has not caused significant difficulty either. -.P -MTU and fragmentation issues, by contrast, have been a constant headache. -We will not describe the details of our current approach to them, -because it still needs work. -One difficulty we have encountered is that many combinations of -packet source and packet destination -apparently cannot cope with an "interior minimum" in the path MTU, -e.g. where an IPsec tunnel intervenes and its headers reduce the MTU -for an intermediate link. -This is particularly prevalent when using common PC software to -connect to large well-known web sites; -we think it is largely due to -misconfigured firewalls which do not pass ICMP -Fragmentation Required messages. -The only solution we have yet found is to lie about the MTU of the tunnel, -accepting the (undesirable) fragmentation of the ESP packets -for the sake of preserving connectivity. -.P -We currently zero out the TOS field of ESP packets, -rather than copying it from the inner header, -on the grounds that it lends itself too well to traffic analysis -and covert channels. -We provide an option to restore RFC 2401 [IPSEC] copying behavior, -but this appears to see little use. -.H -2.2. Ciphers -.P -We initially implemented both DES [DES] and 3DES [CIPHERS] for both -IKE and ESP, -but after the Deep Crack effort [CRACK] demonstrated its inherent insecurity, -we dropped support for DES. -Somewhat surprisingly, -our insistence on 3DES has caused almost no interoperability problems, -despite DES being officially mandatory. -A very few other systems either do not support 3DES or support it only -as an optional upgrade, -which inconveniences a few would-be users. -There have also been one or two cases of systems -which don't quite seem to know the difference! -.P -See also section 6.1 for a consequence of our insistence on 3DES. -.H -2.3. Interfaces -.P -We currently employ PF_KEY version 2 [PFKEY], -plus various non-standard extensions, -as our interface between keying and ESP. -This has not proven entirely satisfactory. -Our feeling now is that keying issues and policy issues -do not really lend -themselves to the clean separation that PF_KEY envisions. -.H -3. IKE Infrastructural Issues -.P -A number of problems in IPsec connection management become easier if -some attention is first paid to providing an infrastructure -to support solving them. -.H -3.1. Continuous Channel -.P -FreeS/WAN uses an approximation to the "continuous channel" model, -in which ISAKMP SAs are maintained between IKEs -so long as any IPsec SAs are open between the two systems. -The resource consumption of this is minor: -the only substantial overhead is occasional rekeying. -IPsec SA management becomes significantly simpler if there is always -a channel for transmission of control messages. -We suggest (although we do not yet fully implement this) that -inability to maintain (e.g., to rekey) this control path -should be grounds for tearing down the IPsec SAs as well. -.P -As a corollary of this, -there is one and only one ISAKMP SA maintained between a pair of IKEs -(although see sections 5.3 and 6.5 for minor complications). -.H -3.2. Retransmission -.P -The unreliable nature of UDP transmission is a nuisance. -IKE implementations should always be prepared to retransmit the most recent -message they sent on an ISAKMP SA, -since there is some possibility that the other end did not get it. -This means, in particular, -that the system sending the supposedly-last message of an exchange -cannot relax and assume that the exchange is complete, -at least not until a significant timeout has elapsed. -.P -Systems must also retain information about the message most recently received -in an exchange, -so that a duplicate of it can be detected -(and possibly interpreted as a NACK for the response). -.P -The retransmission rules FreeS/WAN follows are: -(1) if a reply is expected, retransmit only if it does not appear -before a timeout; -and (2) if a reply is not expected (last message of the exchange), -retransmit only on receiving a retransmission of the previous message. -Notably, in case (1) we do NOT retransmit on receiving a retransmission, -which avoids possible congestion problems arising from packet duplication, -at the price of slowing response to packet loss. -The timeout for case (1) is 10 seconds for the first retry, -20 seconds for the second, and 40 seconds for all subsequent -retries (normally only one, -except when -configuration settings call for persistence and the message is -the first message of Main Mode with a new peer). -These retransmission rules have been entirely successful. -.P -(Michael Thomas of Cisco has pointed out that the retry timeouts should -include some random jitter, to de-synchronize hosts which are -initially synchronized by, e.g., a power outage. -We already jitter our rekeying times, -as noted in section 4.2, -but that does not help with initial startup. -We're implementing jittered retries, -but cannot yet report on experience with this.) -.P -There is a deeper problem, of course, when an entire "exchange" consists -of a single message, -e.g. the ISAKMP Informational Exchange. -Then there is no way to decide whether or when a retransmission is -warranted at all. -This seems like poor design, to put it mildly -(and there is now talk of fixing it). -We have no experience in dealing with this problem at this time, -although it is part of the reason why we have delayed implementing -Notification messages. -.H -3.3. Replay Prevention -.P -The unsequenced nature of UDP transmission is also troublesome, -because it means that higher levels must consider the possibility -of replay attacks. -FreeS/WAN takes the position that systematically eliminating this -possibility at a low level is strongly preferable to forcing careful -consideration of possible impacts at every step of an exchange. -RFC 2408 [ISAKMP] section 3.1 states that the Message ID of an -ISAKMP message must be "unique". -FreeS/WAN interprets this literally, -as forbidding duplication of Message IDs -within the set of all messages sent via a single ISAKMP SA. -.P -This requires remembering all Message IDs until the ISAKMP SA is -superseded by rekeying, -but that is not costly (four bytes per sent or received message), -and it ELIMINATES replay attacks from consideration; -we believe this investment of resources is well worthwhile. -If the resource consumption becomes excessive\(emin our experience -it has not\(emthe ISAKMP SA can be rekeyed early to collect the garbage. -.P -There is theoretically an interoperability problem when talking to -implementations which interpret "unique" more loosely -and may re-use Message IDs, -but it has not been encountered in practice. -This approach appears to be completely interoperable. -.P -The proposal by -Andrew Krywaniuk [REPLAY], -which advocates turning the Message ID into an anti-replay counter, -would achieve the same goal without the minor per-message memory overhead. -This may be preferable, -although it means an actual protocol change and more study is needed. -.H -4. Basic Keying and Rekeying -.H -4.1. When to Create SAs -.P -As Tim Jenkins [REKEY] pointed out, -there is a potential race condition in Quick Mode: -a fast lightly-loaded Initiator might start using IPsec SAs very -shortly after sending QM3 (the third and last message of Quick Mode), -while a slow heavily-loaded Responder might -not be ready to receive them until after spending -a significant amount of time creating its inbound SAs. -The problem is even worse if QM3 gets delayed or lost. -.P -FreeS/WAN's approach to this is what Jenkins called "Responder Pre-Setup": -the Responder creates its inbound IPsec SAs before it sends QM2, -so they are always ready and waiting -when the Initiator sends QM3 and begins sending traffic. -This approach is simple and reliable, -and in our experience it interoperates with everybody. -(There is potentially still a problem if FreeS/WAN is the Initiator -and the Responder does not use Responder Pre-Setup, -but no such problems have been seen.) -The only real weakness of Responder Pre-Setup -is the possibility of replay attacks, -which we have eliminated by other means (see section 3.3). -.P -With this approach, the Commit Bit is useless, -and we ignore it. -In fact, until quite recently we discarded any IKE message containing it, -and this caused surprisingly few interoperability problems; -apparently it is not widely used. -We have recently been persuaded that simply ignoring it is preferable; -preliminary experience with this indicates that the result is successful -interoperation with implementations which set it. -.H -4.2. When to Rekey -.P -To preserve connectivity for user traffic, -rekeying of a connection -(that is, creation of new IPsec SAs to supersede the current ones) -must begin before its current IPsec SAs expire. -Preferably one end should predictably start rekeying negotiations first, -to avoid the extra overhead of two simultaneous negotiations, -although either end should be prepared to rekey if the other does not. -There is also a problem with "convoys" of keying negotiations: -for example, a "hub" gateway with many IPsec connections -can be inundated with rekeying negotiations -exactly one connection-expiry time after it reboots, -and the massive overload this induces tends to make this -situation self-perpetuating, -so it recurs regularly. -(Convoys can also evolve gradually from initially-unsynchronized negotiations.) -.P -FreeS/WAN has the concept of a "rekeying margin", measured in seconds. -If FreeS/WAN was the Initiator for the previous rekeying -(or the startup, if none) of the connection, -it nominally starts rekeying negotiations at expiry time -minus one rekeying margin. -Some random jitter is added to break up convoys: -rather than starting rekeying exactly at minus one margin, -it starts at a random time between minus one margin -and minus two margins. -(The randomness here need not be cryptographic in quality, -so long as it varies over time and between hosts. -We use an ordinary PRNG seeded with a few bytes from a cryptographic -randomness source. -The seeding mostly just ensures that the PRNG sequence is different -for different hosts, even if they start up simultaneously.) -.P -If FreeS/WAN was the Responder for the previous rekeying/startup, -and nothing has been heard from the previous Initiator -at expiry time minus one-half the rekeying margin, -FreeS/WAN will initiate rekeying negotiations. -No jitter is applied; -we now believe that it should be jittered, -say between minus one-half margin and minus one-quarter margin. -.P -Having the Initiator lead the way is an obvious way of deciding -who should speak first, -since there is already an Initiator/Responder asymmetry in the connection. -Moreover, our experience has been that Initiator lead gives a significantly -higher probability of successful negotiation! -The negotiation process itself is asymmetric, -because the Initiator must make a few specific proposals which the Responder -can only accept or reject, -so the Initiator must try to guess where its "acceptable" region -(in parameter space) -might overlap with the Responder's. -We have seen situations where negotiations would succeed or fail -depending on which end initiated them, -because one end was making better guesses. -Given an existing connection, -we KNOW that the previous Initiator WAS able to initiate a successful -negotiation, -so it should (if at all possible) take the lead again. -Also, the Responder should remember the Initiator's successful proposal, -and start from that -rather than from his own default proposals if he must take the lead; -we don't currently implement this completely but plan to. -.P -FreeS/WAN defaults the rekeying margin to 9 minutes, -although this can be changed by configuration. -There is also -a configuration option to alter the permissible range of jitter. -The defaults were chosen somewhat arbitrarily, -but they work extremely well -and the configuration options are rarely used. -.H -4.3. Choosing an SA -.P -Once rekeying has occurred, -both old and new IPsec SAs for the connection exist, -at least momentarily. -FreeS/WAN accepts incoming traffic -on either old or new inbound SAs, -but sends outgoing traffic only on the new outbound ones. -This approach appears to be significantly more robust than -using the old ones until they expire, -notably in cases where renegotiation has occurred because something has -gone wrong on the other end. -It avoids having to pay meticulous attention to the state of the other end, -state which is difficult to learn reliably given the limitations of IKE. -.P -This approach has interoperated successfully with ALMOST all other -implementations. -The only (well-characterized) problem cases have been implementations -which rely on receiving a Delete message for the old SAs to tell them -to switch over to the new ones. -Since delivery of Delete is unreliable, -and support for Delete is optional, -this reliance seems like a serious mistake. -This is all the more true because Delete -announces that the deletion has -already occurred [ISAKMP, section 3.15], not that it is about to occur, -so packets already in transit in the other direction could be lost. -Delete should be used for resource cleanup, not for switchover control. -(These matters are discussed further in section 5.) -.H -4.4. Why to Rekey -.P -FreeS/WAN currently implements only time-based expiry (life in seconds), -although we are working toward -supporting volume-based expiry (life in kilobytes) as well. -The lack of volume-based expiry has not been an interoperability -problem so far. -.P -Volume-based expiry does add some minor complications. -In particular, it makes explicit Delete of now-disused SAs more important, -because once an SA stops being used, -it might not expire on its own. -We believe this lacks robustness and is generally unwise, -especially given the lack of a reliable Delete, -and expect to use volume-based expiry only as a supplement -to time-based expiry. -However, Delete support (see section 5) does seem advisable -for use with volume-based expiry. -.P -We do not believe that volume-based expiry alters the desirability -of switching immediately to the new SAs after rekeying. -Rekeying margins are normally a small fraction of the total life of an SA, -so we feel there is no great need to "use it all up". -.H -4.5. Rekeying ISAKMP SAs -.P -The above discussion has focused on rekeying for IPsec SAs, -but FreeS/WAN applies the same approaches to rekeying for ISAKMP SAs, -with similar success. -.P -One issue which we have noticed, but not explicitly dealt with, -is that difficulties may ensue if an IPsec-SA rekeying negotiation -is in progress at the time when the relevant ISAKMP SA gets rekeyed. -The IKE specification [IKE] hints, but does not actually say, -that a Quick Mode negotiation should remain on a single ISAKMP SA throughout. -.P -A reasonable rekeying margin will generally -prevent the old ISAKMP SA from actually expiring during a negotiation. -Some attention may be needed to prevent in-progress negotiations from -being switched to the new ISAKMP SA. -Any attempt at pre-expiry deletion of the ISAKMP SA must be postponed -until after such dangling negotiations are completed, -and there should be enough delay between ISAKMP-SA rekeying and a -deletion attempt to (more or less) -ensure that there are no negotiation-starting packets still in transit -from before the rekeying. -.P -At present, FreeS/WAN does none of this, -and we don't KNOW of any resulting trouble. -With normal lifetimes, the problem should be uncommon, -and we speculate that an occasional disrupted negotiation simply gets retried. -.H -4.6. Bulk Negotiation -.P -Quick Mode nominally provides for negotiating possibly-large numbers of -similar but unrelated IPsec SAs simultaneously -[IKE, section 9]. -Nobody appears to do this. -FreeS/WAN does not support it, and its absence has caused no problems. -.H -5. Deletions, Teardowns, Crashes -.P -FreeS/WAN currently ignores all Notifications and Deletes, -and never generates them. -This has caused little difficulty in interoperability, -which shouldn't be surprising (since Notification and Delete support is -officially entirely optional) but does seem to surprise some people. -Nevertheless, we do plan some changes to this approach -based on past experience. -.H -5.1. Deletions -.P -As hinted at above, -we plan to implement Delete support, done as follows. -Shortly after rekeying of IPsec SAs, -the Responder issues a Delete for its old inbound SAs -(but does not actually delete them yet). -The Responder initiates this because the Initiator started using the -new SAs on sending QM3, while the Responder started using them only -on (or somewhat after) receiving QM3, -so there is less chance of old-SA packets still being in transit from -the Initiator. -The Initiator issues an unsolicited Delete only if it does not hear one -from the Responder after a longer delay. -.P -Either party, on receiving a Delete -for one or more of the old outbound SAs of a connection, -deletes ALL the connection's SAs, -and acknowledges with a Delete for the old inbound SAs. -A Delete for nonexistent SAs -(e.g., SAs which have already been expired or deleted) is ignored. -There is no retransmission of unacknowledged Deletes. -.P -In the normal case, -with prompt reliable transmission (except possibly for loss of the -Responder's initial Delete) -and conforming implementations -on both ends, this results in three Deletes being transmitted, -resembling the classic three-way handshake. -Loss of a Delete after the first, or multiple losses, -will cause the SAs not to be deleted on at least one end. -It appears difficult to do much better without at least -a distinction between request and acknowledgement. -.P -RFC 2409 section 9 "strongly suggests" that there be no response to -informational messages such as Deletes, -but the only rationale offered is prevention of infinite loops -endlessly exchanging "I don't understand you" informationals. -Since Deletes cannot lead to such a loop -(and in any case, the nonexistent-SA rule prevents more than one -acknowledgement for the same connection), -we believe this recommendation is inapplicable here. -.P -As noted in section 4.3, these Deletes are intended for -resource cleanup, not to control switching between SAs. -But we expect that they will improve interoperability -with some broken implementations. -.P -We believe strongly that connections need to be considered as a whole, -rather than treating each SA as an independent entity. -We will issue Deletes only for the full set of inbound SAs of -a connection, -and will treat a Delete for any outbound SA as equivalent to deletion -of all the outbound SAs for the associated connection. -.P -The above is phrased in terms of IPsec SAs, -but essentially the same approach can be applied to ISAKMP SAs -(the Deletes for the old ISAKMP SA should be sent via the new one). -.H -5.2. Teardowns and Shutdowns -.P -When a connection is not intended to be up permanently, -there is a need to coordinate teardown, -so that both ends are aware that the connection is down. -This is both for recovery of resources, -and to avoid routing packets through -dangling SAs which can no longer deliver them. -.P -Connection teardown will use the same bidirectional exchange of Deletes -as discussed in section 5.1: -a Delete received for current IPsec SAs (not yet obsoleted by rekeying) -indicates that the other host wishes to tear down the associated connection. -.P -A Delete received for a current ISAKMP SA indicates that the other host -wishes to tear down not only the ISAKMP SA but also all IPsec SAs -currently under the supervision of that ISAKMP SA. -The 5.1 bidirectional exchange might seem impossible in this case, -since reception of an ISAKMP-SA Delete indicates that the other end -will ignore further traffic on that ISAKMP SA. -We suggest using the same tactic discussed in 5.1 for IPsec SAs: -the first Delete is sent without actually doing the deletion, -and the response to receiving a Delete is to do the deletion and reply -with another Delete. -If there is no response to the first Delete, -retry a small number of times and then give up and do the deletion; -apart from being robust against packet loss, -this also maximizes the probability that an implementation which does -not do the bidirectional Delete will receive at least one of the Deletes. -.P -When a host with current connections knows that it is about to shut down, -it will issue Deletes for all SAs involved (both IPsec and ISAKMP), -advising its peers (as per the meaning of Delete [ISAKMP, section 3.15]) -that the SAs have become useless. -It will ignore attempts at rekeying or connection startup thereafter, -until it shuts down. -.P -It would be better to have a Final-Contact notification, -analogous to Initial-Contact but indicating that no new negotiations -should be attempted until further notice. -Initial-Contact actually could be used for shutdown notification (!), -but in networks where connections are intended to exist permanently, -it seems likely to provoke unwanted attempts -to renegotiate the lost connections. -.H -5.3. Crashes -.P -Systems sometimes crash. -Coping with the resulting loss of information is easily the most -difficult problem we have found in implementing robust IPsec systems. -.P -When connections are intended to be permanent, -it is simple to specify renegotiation on reboot. -With our approach to SA selection (see section 4.3), -this handles such cases robustly and well. -We do have to tell users that BOTH hosts should be set this way. -In cases where crashes are synchronized (e.g. by power interruptions), -this may result in simultaneous negotiations at reboot. -We currently allow both negotiations to proceed to completion, -but our use-newest selection method -effectively ignores one connection or the other, -and when one of them rekeys, -we notice that the new SAs replace those of both old connections, -and we then refrain from rekeying the other. -(This duplicate detection is desirable in any event, for robustness, -to ensure that the system converges on a reasonable state eventually -after it is perturbed by difficulties or bugs.) -.P -When connections are not permanent, the situation is less happy. -One particular situation in which we see problems is when a number of -"Road Warrior" hosts occasionally call in to a central server. -The server is normally configured not to initiate such connections, -since it does not know when the Road Warrior is available (or what IP -address it is using). -Unfortunately, if the server crashes and reboots, -any Road Warriors then connected have a problem: -they don't know that the server has crashed, -so they can't renegotiate, -and the server has forgotten both the connections and -their (transient) IP addresses, -so it cannot renegotiate. -.P -We believe that the simplest answer to this problem is what John Denker -has dubbed "address inertia": -the server makes a best-effort attempt to remember (in nonvolatile storage) -which connections were active and what the far-end addresses were -(and what the successful proposal's parameters were), -so that it can attempt renegotiation on reboot. -We have not implemented this yet, but intend to; -Denker has implemented it himself, -although in a somewhat messy way, -and reports excellent results. -.H -5.4. Network Partitions -.P -A network partition, making the two ends unable to reach each other, -has many of the same characteristics as having the other end crash... until -the network reconnects. -It is desirable that recovery from this be automatic. -.P -If the network reconnects before any rekeying attempts -or other IKE activities occurred, -recovery is fully transparent, -because the IKEs have no idea that there was any problem. -(Complaints such as ICMP Host Unreachable messages are unauthenticated -and hence cannot be given much weight.) -This fits the general mold of TCP/IP: -if nobody wanted to send any traffic, a network outage doesn't matter. -.P -If IKE activity did occur, -the IKE implementation will discover that the other end doesn't seem -to be responding. -The preferred response to this depends on the nature of the connection. -If it was intended to be ephemeral (e.g. opportunistic encryption [OE]), -closing it down after a few retries is reasonable. -If the other end is expected to sometimes drop the connection without -warning, it may not be desirable to retry at all. -(We support both these forms of configurability, -and indeed we also have a configuration option to suppress -rekeying entirely on one end.) -.P -If the connection was intended to be permanent, however, -then persistent attempts to re-establish it are appropriate. -Some degree of backoff is appropriate here, -so that retries get less frequent as the outage gets prolonged. -Backoff should be limited, -so that re-established connectivity is not followed by a long delay -before a retry. -Finally, after many retries (say 24 hours' worth), -it may be preferable to just declare the connection down and rely -on manual intervention to re-establish it, -should this be desirable. -We do not yet fully support all this. -.H -5.5. Unknown SAs -.P -A more complete solution to crashes -would be for an IPsec host to note the arrival -of ESP packets on an unknown IPsec SA, -and report it somehow to the other host, which can then decide to renegotiate. -This arguably might be preferable in any case\(emif -the non-rebooted host has no traffic to send, -it does not care whether the connection is intact\(embut -delays and packet loss will be reduced -if the connection is renegotiated BEFORE there is traffic for it. -So unknown-SA detection is best reserved as a fallback method, -with address inertia used to deal with most such cases. -.P -A difficulty with unknown-SA detection is, -just HOW should the other host be notified? -IKE provides no good way to do the notification: -Notification payloads (e.g., Initial-Contact) are unauthenticated -unless they are sent under protection of an ISAKMP SA. -A "Security Failures - Bad SPI" ICMP message [SECFAIL] -is an interesting alternative, -but has the disadvantage of likewise being unauthenticated. -It's fundamentally unlikely that there is a simple solution to this, -given that almost any way of arranging or checking authentication for such a -notification is costly. -.P -We think the best answer to this is a two-step approach. -An unauthenticated Initial-Contact or -Security Failures - Bad SPI cannot be taken as a reliable -report of a problem, -but can be taken as a hint that a problem MIGHT exist. -Then there needs to be some reliable way of checking such hints, -subject to rate limiting since the checks are likely to be costly -(and checking the same connection repeatedly at short intervals is unlikely -to be worthwhile anyway). -So the rebooted host sends the notification, -and the non-rebooted host\(emwhich still thinks it has a connection\(emchecks -whether the connection still works, -and renegotiates if not. -.P -Also, if an IPsec host which believes it has a connection to another host -sees an unsuccessful attempt by that host to negotiate a new one, -that is also a hint of possible problems, -justifying a check and possible renegotiation. -("Unsuccessful" here means a negotiation failure due to lack of a -satisfactory proposal. -A failure due to authentication failure -suggests a denial-of-service attack by a third party, -rather than a genuine problem on the legitimate other end.) -As noted in section 4.2, -it is possible for negotiations to succeed or fail based on which -end initiates them, and some robustness against that is desirable. -.P -We have not yet decided what form the notification should take. -IKE Initial-Contact is an obvious possibility, -but has some disadvantages. -It does not specify which connection has had difficulties. -Also, the specification [IKE section 4.6.3.3] -refers to "remote system" and "sending system" -without clearly specifying just what "system" means; -in the case of a multi-homed host using multiple forms of identification, -the question is not trivial. -Initial-Contact does have the fairly-decisive advantage -that it is likely to convey the right general -meaning even to an implementation which does not do things -exactly the way ours does. -.P -A more fundamental difficulty is what form the reliable check takes. -What is wanted is an "IKE ping", -verifying that the ISAKMP SA is still intact -(it being unlikely that IPsec SAs have been lost while the ISAKMP SA has not). -The lack of such a facility is a serious failing of IKE. -An acknowledged Notification of some sort would be ideal, -but there is none at present. -Some existing implementations are known -to use the private Notification values 30000 as ping -and 30002 as ping reply, -and that seems the most attractive choice at present. -If it is not recognized, there will probably be no reply, -and the result will be an unnecessary renegotiation, -so this needs strict rate limiting. -(Also, when a new connection is set up, -it's probably worth determining by experiment whether the other end -supports IKE ping, and remembering that.) -.P -While we think this facility is desirable, -and is about the best that can be done with the poor tools available, -we have not gotten very far in implementation and cannot comment -intelligently about how well it works or interoperates. -.H -6. Misc. IKE Issues -.H -6.1. Groups 1 and 5 -.P -We have dropped support for the first Oakley Group (group 1), -despite it being officially mandatory, -on the grounds that it is -grossly too weak to provide enough randomness for 3DES. -There have been some interoperability problems, -mostly quite minor: -ALMOST everyone supports group 2 as well, -although sometimes it has to be explicitly configured. -.P -We also support the quasi-standard group 5 [GROUPS]. -This has not been seriously exercised yet, -because historically -we offered group 2 first and almost everyone accepted it. -We have recently changed to offering group 5 first, -and no difficulties have been reported. -.H -6.2. To PFS Or Not To PFS -.P -A persistent small interoperability problem is that -the presence or absence of PFS (for keys [IKE, section 5.5]) -is neither negotiated nor announced. -We have it enabled by default, -and successful interoperation often requires having -the other end turn it on in their implementation, -or having the FreeS/WAN end disable it. -Almost everyone supports it, but it's usually not the default, -and interoperability is often impossible unless the two ends -somehow reach prior agreement on it. -.P -We do not explicitly support the other flavor of PFS, -for identities [IKE, section 8], -and this has caused no interoperability problems. -.H -6.3. Debugging Tools, Lack Thereof -.P -We find IKE lacking in basic debugging tools. -Section 5.4, above, -notes that an IKE ping would be useful for connectivity verification. -It would also be extremely helpful for determining that UDP/500 -packets get back and forth successfully between the two ends, -which is often an important first step in debugging. -.P -It's also quite common to have IKE negotiate a connection successfully, -but to have some firewall along the way blocking ESP. -Users find this mysterious and difficult to diagnose. -We have no immediate suggestions on what could be done about it. -.H -6.4. Terminology, Vagueness Thereof -.P -The terminology of IPsec needs work. -We feel that both the specifications and user-oriented -documentation would be greatly clarified by concise, intelligible names for -certain concepts. -.P -We semi-consistently use "group" for the set of IPsec SAs which are -established in one direction -by a single Quick Mode negotiation and are used together -to process a packet (e.g., an ESP SA plus an AH SA), -"connection" for the logical packet path provided -by a succession of pairs of groups -(each rekeying providing a new pair, one group in each direction), -and "keying channel" for the corresponding supervisory path provided -by a sequence of ISAKMP SAs. -.P -We think it's a botch that "PFS" is used to refer to two very different things, -but we have no specific new terms to suggest, since we only implement -one kind of PFS and thus can just ignore the other. -.H -6.5. A Question of Identity -.P -One specification problem deserves note: -exactly when can an existing phase 1 negotiation -be re-used for a new phase 2 negotiation, -as IKE [IKE, section 4] specifies? -Presumably, -when it connects the same two "parties"... but exactly what is a "party"? -.P -As noted in section 5.4, -in cases involving multi-homing and multiple identities, -it's not clear exactly what criteria are used for deciding -whether the intended far end for a new negotiation is the same one -as for a previous negotiation. -Is it by Identification Payload? -By IP address? -Or what? -.P -We currently use a somewhat-vague notion of "identity", -basically what gets sent in Identification Payloads, -for this, and this seems to be successful, -but we think this needs better specification. -.H -6.6. Opportunistic Encryption -.P -Further IKE challenges appear in the context of Opportunistic Encryption -[OE], -but operational experience with it is too limited as yet for us -to comment usefully right now. -.H -6.7. Authentication and RSA Keys -.P -We provide two IKE authentication methods: -shared secrets ("pre-shared keys") -and RSA digital signatures. -(A user-provided add-on package generalizes the latter to limited -support for certificates; -we have not worked extensively with it ourselves yet and cannot comment -on it yet.) -.P -Shared secrets, despite their administrative difficulties, -see considerable use, -and are also the method of last resort for interoperability problems. -.P -For digital signatures, -we have taken the somewhat unorthodox approach of using "bare" RSA public keys, -either supplied in configuration files or fetched from DNS, -rather than getting involved in the complexity of certificates. -We encode our RSA public keys using the DNS KEY encoding [DNSRSA] -(aka "RFC 2537", although that RFC is now outdated), -which has given us no difficulties and which we highly recommend. -We have seen two difficulties in connection with RSA keys, however. -.P -First, -while a number of IPsec implementations are able to take "bare" RSA public keys, -each one seems to have its own idea of what format should be used -for transporting them. -We've had little success with interoperability here, -mostly because of key-format issues; -the implementations generally WILL interoperate successfully if you can -somehow get an RSA key into them at all, but that's hard. -X.509 certificates seem to be the lowest (!) -common denominator for key transfer. -.P -Second, -although the content of RSA public keys has been stable, -there has been a small but subtle change over time in the content -of RSA private keys. -The "internal modulus", -used to compute the private exponent "d" from the public exponent "e" -(or vice-versa) -was originally [RSA] [PKCS1v1] [SCHNEIER] specified to be (p-1)*(q-1), -where p and q are the two primes. -However, more recent definitions [PKCS1v2] call it -"lambda(n)" and define it to be lcm(p-1,\ q-1); -this appears to be a minor optimization. -The result is that private keys generated with the new definition -often fail consistency checks in implementations using the old definition. -Fortunately, it is seldom necessary to move private keys around. -Our software now consistently uses the new definition -(and thus will accept keys generated with either definition), -but our key generator also has an option to generate old-definition keys, -for the benefit of users who upgrade their networks incrementally. -.H -6.8. Misc. Snags -.P -Nonce size is another characteristic that is neither negotiated nor announced -but that the two ends must somehow be able to agree on. -Our software accepts anything between 8 and 256, and defaults to 16. -These numbers were chosen rather arbitrarily, -but we have seen no interoperability failures here. -.P -Nothing in the ISAKMP [ISAKMP] or IKE [IKE] specifications says -explicitly that a normal Message ID must be non-zero, -but a zero Message ID in fact causes failures. -.P -Similarly, there is nothing in the specs which says that ISAKMP cookies -must be non-zero, but zero cookies will in fact cause trouble. -.H -7. Security Considerations -.P -Since this document discusses aspects of building robust and -interoperable IPsec implementations, -security considerations permeate it. -.H -8. References -.R AH -Kent, S., and Atkinson, R., -"IP Authentication Header", -RFC 2402, -Nov 1998. -.R CIPHERS -Pereira, R., and Adams, R., -"The ESP CBC-Mode Cipher Algorithms", -RFC 2451, -Nov 1998. -.R CRACK -Electronic Frontier Foundation, -"Cracking DES: -Secrets of Encryption Research, Wiretap Politics and Chip Design", -O'Reilly 1998, -ISBN 1-56592-520-3. -.R DES -Madson, C., and Doraswamy, N., -"The ESP DES-CBC Cipher Algorithm", -RFC 2405, -Nov 1998. -.R DNSRSA -D. Eastlake 3rd, -"RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)", -RFC 3110, -May 2001. -.R ESP -Kent, S., and Atkinson, R., -"IP Encapsulating Security Payload (ESP)", -RFC 2406, -Nov 1998. -.R GROUPS -Kivinen, T., and Kojo, M., -"More MODP Diffie-Hellman groups for IKE", -<draft-ietf-ipsec-ike-modp-groups-04.txt>, -13 Dec 2001 (work in progress). -.R IKE -Harkins, D., and Carrel, D., -"The Internet Key Exchange (IKE)", -RFC 2409, Nov 1998. -.R IPSEC -Kent, S., and Atkinson, R., -"Security Architecture for the Internet Protocol", -RFC 2401, Nov 1998. -.R ISAKMP -Maughan, D., Schertler, M., Schneider, M., and Turner, J., -"Internet Security Association and Key Management Protocol (ISAKMP)", -RFC 2408, Nov 1998. -.R OE -Richardson, M., Redelmeier, D. H., and Spencer, H., -"A method for doing opportunistic encryption with IKE", -<draft-richardson-ipsec-opportunistic-06.txt>, -21 Feb 2002 (work in progress). -.R PKCS1v1 -Kaliski, B., -"PKCS #1: RSA Encryption, Version 1.5", -RFC 2313, March 1998. -.R PKCS1v2 -Kaliski, B., and Staddon, J., -"PKCS #1: RSA Cryptography Specifications, Version 2.0", -RFC 2437, Oct 1998. -.R PFKEY -McDonald, D., Metz, C., and Phan, B., -"PF_KEY Key Management API, Version 2", -RFC 2367, July 1998. -.R REKEY -Tim Jenkins, "IPsec Re-keying Issues", -<draft-jenkins-ipsec-rekeying-06.txt>, -2 May 2000 (draft expired, work no longer in progress). -.R REPLAY -Krywaniuk, A., -"Using Isakmp Message Ids for Replay Protection", -<draft-krywaniuk-ipsec-antireplay-00.txt>, -9 July 2001 -(work in progress). -.R RSA -Rivest, R.L., Shamir, A., and Adleman, L., -"A Method for Obtaining Digital Signatures and Public-Key -Cryptosystems", -Communications of the ACM v21n2, Feb 1978, p. 120. -.R SCHNEIER -Bruce Schneier, "Applied Cryptography", 2nd ed., -Wiley 1996, ISBN 0-471-11709-9. -.R SECFAIL -Karn, P., and Simpson, W., -"ICMP Security Failures Messages", -RFC 2521, -March 1999. -.H -Authors' Addresses -.P -.nf -.ne 8 -Henry Spencer -SP Systems -Box 280 Stn. A -Toronto, Ont. M5W1B2 -Canada - -henry@spsystems.net -416-690-6561 -.ne 8 -.sp 2 -D. Hugh Redelmeier -Mimosa Systems Inc. -29 Donino Ave. -Toronto, Ont. M4N2W6 -Canada - -hugh@mimosa.com -416-482-8253 -.bp -.H -Full Copyright Statement -.P -Copyright (C) The Internet Society \*c. All Rights -Reserved. - -This document and translations of it may be copied and -furnished to others, and derivative works that comment on or -otherwise explain it or assist in its implmentation may be -prepared, copied, published and distributed, in whole or in -part, without restriction of any kind, provided that the above -copyright notice and this paragraph are included on all such -copies and derivative works. However, this document itself may -not be modified in any way, such as by removing the copyright -notice or references to the Internet Society or other Internet -organizations, except as needed for the purpose of developing -Internet standards in which case the procedures for copyrights -defined in the Internet Standards process must be followed, or -as required to translate it into languages other than English. - -The limited permissions granted above are perpetual and will -not be revoked by the Internet Society or its successors or -assigns. - -This document and the information contained herein is provided -on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET -ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE -OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY -IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A -PARTICULAR PURPOSE. diff --git a/doc/draft-spencer-ipsec-ike-implementation.txt b/doc/draft-spencer-ipsec-ike-implementation.txt deleted file mode 100644 index 145c00ba8..000000000 --- a/doc/draft-spencer-ipsec-ike-implementation.txt +++ /dev/null @@ -1,1232 +0,0 @@ - - - -Network Working Group Henry Spencer -Internet Draft SP Systems -Expires: 26 Aug 2002 D. Hugh Redelmeier - Mimosa Systems - 26 Feb 2002 - - IKE Implementation Issues - <draft-spencer-ipsec-ike-implementation-02.txt> - -Status of this Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026. - - (If approved as an Informational RFC...) This memo provides - information for the Internet community. This memo does not specify - an Internet standard of any kind. - - Distribution of this memo is unlimited. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on 26 Aug 2002. - -Copyright Notice - - Copyright (C) The Internet Society 2002. All Rights Reserved. - - - - - - - - - - -Spencer & Redelmeier [Page 1] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - -Table of Contents - - 1. Introduction ................................................... 3 - 2. Lower-level Background and Notes ............................... 4 - 2.1. Packet Handling .............................................. 4 - 2.2. Ciphers ...................................................... 5 - 2.3. Interfaces ................................................... 5 - 3. IKE Infrastructural Issues ..................................... 5 - 3.1. Continuous Channel ........................................... 5 - 3.2. Retransmission ............................................... 5 - 3.3. Replay Prevention ............................................ 6 - 4. Basic Keying and Rekeying ...................................... 7 - 4.1. When to Create SAs ........................................... 7 - 4.2. When to Rekey ................................................ 8 - 4.3. Choosing an SA ............................................... 9 - 4.4. Why to Rekey ................................................. 9 - 4.5. Rekeying ISAKMP SAs ......................................... 10 - 4.6. Bulk Negotiation ............................................ 10 - 5. Deletions, Teardowns, Crashes ................................. 11 - 5.1. Deletions ................................................... 11 - 5.2. Teardowns and Shutdowns ..................................... 12 - 5.3. Crashes ..................................................... 13 - 5.4. Network Partitions .......................................... 13 - 5.5. Unknown SAs ................................................. 14 - 6. Misc. IKE Issues .............................................. 16 - 6.1. Groups 1 and 5 .............................................. 16 - 6.2. To PFS Or Not To PFS ........................................ 16 - 6.3. Debugging Tools, Lack Thereof ............................... 16 - 6.4. Terminology, Vagueness Thereof .............................. 17 - 6.5. A Question of Identity ...................................... 17 - 6.6. Opportunistic Encryption .................................... 17 - 6.7. Authentication and RSA Keys ................................. 17 - 6.8. Misc. Snags ................................................. 18 - 7. Security Considerations ....................................... 19 - 8. References .................................................... 19 - Authors' Addresses ............................................... 20 - Full Copyright Statement ......................................... 21 - - - - - - - - - - - - - - -Spencer & Redelmeier [Page 2] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - -Abstract - - The current IPsec specifications for key exchange and connection - management, RFCs 2408 [ISAKMP] and 2409 [IKE], leave many aspects of - connection management unspecified, most prominently rekeying - practices. Pending clarifications in future revisions of the - specifications, this document sets down some successful experiences, - to minimize the extent to which new implementors have to rely on - unwritten folklore. - - The Linux FreeS/WAN implementation of IPsec interoperates with almost - every other IPsec implementation. This document describes how the - FreeS/WAN project has resolved some of the gaps in the IPsec - specifications (and plans to resolve some others), and what - difficulties have been encountered, in hopes that this generally- - successful experience might be informative to new implementors. - - This is offered as an Informational RFC. - - This -02 revision mainly: discusses ISAKMP SA expiry during IPsec-SA - rekeying (4.5), revises the discussion of bidirectional Deletes - (5.1), suggests remembering the parameters of successful negotiations - for later use (4.2, 5.3), notes an unsuccessful negotiation from the - other end as a hint of a possibly broken connection (5.5), and adds - sections on network partitions (5.4), authentication methods and the - subtleties of RSA public keys (6.7), and miscellaneous - interoperability concerns (6.8). - -1. Introduction - - The current IPsec specifications for key exchange and connection - management, RFCs 2408 [ISAKMP] and 2409 [IKE], leave many aspects of - connection management unspecified, most prominently rekeying - practices. This is a cryptic puzzle which each group of implementors - has to struggle with, and differences in how the ambiguities and gaps - are resolved are potentially a fruitful source of interoperability - problems. We can hope that future revisions of the specifications - will clear this up. Meanwhile, it seems useful to set down some - successful experiences, to minimize the extent to which new - implementors have to rely on unwritten folklore. - - The Linux FreeS/WAN implementation of IPsec interoperates with almost - every other IPsec implementation, and because of its free nature, it - also sees some use as a reference implementation by other - implementors. The high degree of interoperability is noteworthy - given its organizers' strong minimalist bias, which has caused them - to implement only a small subset of the full glory of IPsec. This - document describes how the FreeS/WAN project has resolved some of the - - - -Spencer & Redelmeier [Page 3] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - gaps in the IPsec specifications (and plans to resolve some others), - and what difficulties have been encountered, in hopes that this - generally-successful experience might be informative to new - implementors. - - One small caution about applicability: this experience may not be - relevant to severely resource-constrained implementations. - FreeS/WAN's target environment is previous-generation PCs, now - available at trivial cost (often, within an organization, at no - cost), which have quite impressive CPU power and memory by the - standards of only a few years ago. Some of the approaches discussed - here may be inapplicable to implementations with severe external - constraints which prevent them from taking advantage of modern - hardware technology. - -2. Lower-level Background and Notes - -2.1. Packet Handling - - FreeS/WAN implements ESP [ESP] and AH [AH] straightforwardly, - although AH sees little use among our users. Our ESP/AH - implementation cannot currently handle packets with IP options; - somewhat surprisingly, this has caused little difficulty. We insist - on encryption and do not support authentication-only connections, and - this has not caused significant difficulty either. - - MTU and fragmentation issues, by contrast, have been a constant - headache. We will not describe the details of our current approach - to them, because it still needs work. One difficulty we have - encountered is that many combinations of packet source and packet - destination apparently cannot cope with an "interior minimum" in the - path MTU, e.g. where an IPsec tunnel intervenes and its headers - reduce the MTU for an intermediate link. This is particularly - prevalent when using common PC software to connect to large well- - known web sites; we think it is largely due to misconfigured - firewalls which do not pass ICMP Fragmentation Required messages. - The only solution we have yet found is to lie about the MTU of the - tunnel, accepting the (undesirable) fragmentation of the ESP packets - for the sake of preserving connectivity. - - We currently zero out the TOS field of ESP packets, rather than - copying it from the inner header, on the grounds that it lends itself - too well to traffic analysis and covert channels. We provide an - option to restore RFC 2401 [IPSEC] copying behavior, but this appears - to see little use. - - - - - - -Spencer & Redelmeier [Page 4] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - -2.2. Ciphers - - We initially implemented both DES [DES] and 3DES [CIPHERS] for both - IKE and ESP, but after the Deep Crack effort [CRACK] demonstrated its - inherent insecurity, we dropped support for DES. Somewhat - surprisingly, our insistence on 3DES has caused almost no - interoperability problems, despite DES being officially mandatory. A - very few other systems either do not support 3DES or support it only - as an optional upgrade, which inconveniences a few would-be users. - There have also been one or two cases of systems which don't quite - seem to know the difference! - - See also section 6.1 for a consequence of our insistence on 3DES. - -2.3. Interfaces - - We currently employ PF_KEY version 2 [PFKEY], plus various non- - standard extensions, as our interface between keying and ESP. This - has not proven entirely satisfactory. Our feeling now is that keying - issues and policy issues do not really lend themselves to the clean - separation that PF_KEY envisions. - -3. IKE Infrastructural Issues - - A number of problems in IPsec connection management become easier if - some attention is first paid to providing an infrastructure to - support solving them. - -3.1. Continuous Channel - - FreeS/WAN uses an approximation to the "continuous channel" model, in - which ISAKMP SAs are maintained between IKEs so long as any IPsec SAs - are open between the two systems. The resource consumption of this - is minor: the only substantial overhead is occasional rekeying. - IPsec SA management becomes significantly simpler if there is always - a channel for transmission of control messages. We suggest (although - we do not yet fully implement this) that inability to maintain (e.g., - to rekey) this control path should be grounds for tearing down the - IPsec SAs as well. - - As a corollary of this, there is one and only one ISAKMP SA - maintained between a pair of IKEs (although see sections 5.3 and 6.5 - for minor complications). - -3.2. Retransmission - - The unreliable nature of UDP transmission is a nuisance. IKE - implementations should always be prepared to retransmit the most - - - -Spencer & Redelmeier [Page 5] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - recent message they sent on an ISAKMP SA, since there is some - possibility that the other end did not get it. This means, in - particular, that the system sending the supposedly-last message of an - exchange cannot relax and assume that the exchange is complete, at - least not until a significant timeout has elapsed. - - Systems must also retain information about the message most recently - received in an exchange, so that a duplicate of it can be detected - (and possibly interpreted as a NACK for the response). - - The retransmission rules FreeS/WAN follows are: (1) if a reply is - expected, retransmit only if it does not appear before a timeout; and - (2) if a reply is not expected (last message of the exchange), - retransmit only on receiving a retransmission of the previous - message. Notably, in case (1) we do NOT retransmit on receiving a - retransmission, which avoids possible congestion problems arising - from packet duplication, at the price of slowing response to packet - loss. The timeout for case (1) is 10 seconds for the first retry, 20 - seconds for the second, and 40 seconds for all subsequent retries - (normally only one, except when configuration settings call for - persistence and the message is the first message of Main Mode with a - new peer). These retransmission rules have been entirely successful. - - (Michael Thomas of Cisco has pointed out that the retry timeouts - should include some random jitter, to de-synchronize hosts which are - initially synchronized by, e.g., a power outage. We already jitter - our rekeying times, as noted in section 4.2, but that does not help - with initial startup. We're implementing jittered retries, but - cannot yet report on experience with this.) - - There is a deeper problem, of course, when an entire "exchange" - consists of a single message, e.g. the ISAKMP Informational Exchange. - Then there is no way to decide whether or when a retransmission is - warranted at all. This seems like poor design, to put it mildly (and - there is now talk of fixing it). We have no experience in dealing - with this problem at this time, although it is part of the reason why - we have delayed implementing Notification messages. - -3.3. Replay Prevention - - The unsequenced nature of UDP transmission is also troublesome, - because it means that higher levels must consider the possibility of - replay attacks. FreeS/WAN takes the position that systematically - eliminating this possibility at a low level is strongly preferable to - forcing careful consideration of possible impacts at every step of an - exchange. RFC 2408 [ISAKMP] section 3.1 states that the Message ID - of an ISAKMP message must be "unique". FreeS/WAN interprets this - literally, as forbidding duplication of Message IDs within the set of - - - -Spencer & Redelmeier [Page 6] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - all messages sent via a single ISAKMP SA. - - This requires remembering all Message IDs until the ISAKMP SA is - superseded by rekeying, but that is not costly (four bytes per sent - or received message), and it ELIMINATES replay attacks from - consideration; we believe this investment of resources is well - worthwhile. If the resource consumption becomes excessive--in our - experience it has not--the ISAKMP SA can be rekeyed early to collect - the garbage. - - There is theoretically an interoperability problem when talking to - implementations which interpret "unique" more loosely and may re-use - Message IDs, but it has not been encountered in practice. This - approach appears to be completely interoperable. - - The proposal by Andrew Krywaniuk [REPLAY], which advocates turning - the Message ID into an anti-replay counter, would achieve the same - goal without the minor per-message memory overhead. This may be - preferable, although it means an actual protocol change and more - study is needed. - -4. Basic Keying and Rekeying - -4.1. When to Create SAs - - As Tim Jenkins [REKEY] pointed out, there is a potential race - condition in Quick Mode: a fast lightly-loaded Initiator might start - using IPsec SAs very shortly after sending QM3 (the third and last - message of Quick Mode), while a slow heavily-loaded Responder might - not be ready to receive them until after spending a significant - amount of time creating its inbound SAs. The problem is even worse - if QM3 gets delayed or lost. - - FreeS/WAN's approach to this is what Jenkins called "Responder Pre- - Setup": the Responder creates its inbound IPsec SAs before it sends - QM2, so they are always ready and waiting when the Initiator sends - QM3 and begins sending traffic. This approach is simple and - reliable, and in our experience it interoperates with everybody. - (There is potentially still a problem if FreeS/WAN is the Initiator - and the Responder does not use Responder Pre-Setup, but no such - problems have been seen.) The only real weakness of Responder Pre- - Setup is the possibility of replay attacks, which we have eliminated - by other means (see section 3.3). - - With this approach, the Commit Bit is useless, and we ignore it. In - fact, until quite recently we discarded any IKE message containing - it, and this caused surprisingly few interoperability problems; - apparently it is not widely used. We have recently been persuaded - - - -Spencer & Redelmeier [Page 7] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - that simply ignoring it is preferable; preliminary experience with - this indicates that the result is successful interoperation with - implementations which set it. - -4.2. When to Rekey - - To preserve connectivity for user traffic, rekeying of a connection - (that is, creation of new IPsec SAs to supersede the current ones) - must begin before its current IPsec SAs expire. Preferably one end - should predictably start rekeying negotiations first, to avoid the - extra overhead of two simultaneous negotiations, although either end - should be prepared to rekey if the other does not. There is also a - problem with "convoys" of keying negotiations: for example, a "hub" - gateway with many IPsec connections can be inundated with rekeying - negotiations exactly one connection-expiry time after it reboots, and - the massive overload this induces tends to make this situation self- - perpetuating, so it recurs regularly. (Convoys can also evolve - gradually from initially-unsynchronized negotiations.) - - FreeS/WAN has the concept of a "rekeying margin", measured in - seconds. If FreeS/WAN was the Initiator for the previous rekeying - (or the startup, if none) of the connection, it nominally starts - rekeying negotiations at expiry time minus one rekeying margin. Some - random jitter is added to break up convoys: rather than starting - rekeying exactly at minus one margin, it starts at a random time - between minus one margin and minus two margins. (The randomness here - need not be cryptographic in quality, so long as it varies over time - and between hosts. We use an ordinary PRNG seeded with a few bytes - from a cryptographic randomness source. The seeding mostly just - ensures that the PRNG sequence is different for different hosts, even - if they start up simultaneously.) - - If FreeS/WAN was the Responder for the previous rekeying/startup, and - nothing has been heard from the previous Initiator at expiry time - minus one-half the rekeying margin, FreeS/WAN will initiate rekeying - negotiations. No jitter is applied; we now believe that it should be - jittered, say between minus one-half margin and minus one-quarter - margin. - - Having the Initiator lead the way is an obvious way of deciding who - should speak first, since there is already an Initiator/Responder - asymmetry in the connection. Moreover, our experience has been that - Initiator lead gives a significantly higher probability of successful - negotiation! The negotiation process itself is asymmetric, because - the Initiator must make a few specific proposals which the Responder - can only accept or reject, so the Initiator must try to guess where - its "acceptable" region (in parameter space) might overlap with the - Responder's. We have seen situations where negotiations would - - - -Spencer & Redelmeier [Page 8] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - succeed or fail depending on which end initiated them, because one - end was making better guesses. Given an existing connection, we KNOW - that the previous Initiator WAS able to initiate a successful - negotiation, so it should (if at all possible) take the lead again. - Also, the Responder should remember the Initiator's successful - proposal, and start from that rather than from his own default - proposals if he must take the lead; we don't currently implement this - completely but plan to. - - FreeS/WAN defaults the rekeying margin to 9 minutes, although this - can be changed by configuration. There is also a configuration - option to alter the permissible range of jitter. The defaults were - chosen somewhat arbitrarily, but they work extremely well and the - configuration options are rarely used. - -4.3. Choosing an SA - - Once rekeying has occurred, both old and new IPsec SAs for the - connection exist, at least momentarily. FreeS/WAN accepts incoming - traffic on either old or new inbound SAs, but sends outgoing traffic - only on the new outbound ones. This approach appears to be - significantly more robust than using the old ones until they expire, - notably in cases where renegotiation has occurred because something - has gone wrong on the other end. It avoids having to pay meticulous - attention to the state of the other end, state which is difficult to - learn reliably given the limitations of IKE. - - This approach has interoperated successfully with ALMOST all other - implementations. The only (well-characterized) problem cases have - been implementations which rely on receiving a Delete message for the - old SAs to tell them to switch over to the new ones. Since delivery - of Delete is unreliable, and support for Delete is optional, this - reliance seems like a serious mistake. This is all the more true - because Delete announces that the deletion has already occurred - [ISAKMP, section 3.15], not that it is about to occur, so packets - already in transit in the other direction could be lost. Delete - should be used for resource cleanup, not for switchover control. - (These matters are discussed further in section 5.) - -4.4. Why to Rekey - - FreeS/WAN currently implements only time-based expiry (life in - seconds), although we are working toward supporting volume-based - expiry (life in kilobytes) as well. The lack of volume-based expiry - has not been an interoperability problem so far. - - Volume-based expiry does add some minor complications. In - particular, it makes explicit Delete of now-disused SAs more - - - -Spencer & Redelmeier [Page 9] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - important, because once an SA stops being used, it might not expire - on its own. We believe this lacks robustness and is generally - unwise, especially given the lack of a reliable Delete, and expect to - use volume-based expiry only as a supplement to time-based expiry. - However, Delete support (see section 5) does seem advisable for use - with volume-based expiry. - - We do not believe that volume-based expiry alters the desirability of - switching immediately to the new SAs after rekeying. Rekeying - margins are normally a small fraction of the total life of an SA, so - we feel there is no great need to "use it all up". - -4.5. Rekeying ISAKMP SAs - - The above discussion has focused on rekeying for IPsec SAs, but - FreeS/WAN applies the same approaches to rekeying for ISAKMP SAs, - with similar success. - - One issue which we have noticed, but not explicitly dealt with, is - that difficulties may ensue if an IPsec-SA rekeying negotiation is in - progress at the time when the relevant ISAKMP SA gets rekeyed. The - IKE specification [IKE] hints, but does not actually say, that a - Quick Mode negotiation should remain on a single ISAKMP SA - throughout. - - A reasonable rekeying margin will generally prevent the old ISAKMP SA - from actually expiring during a negotiation. Some attention may be - needed to prevent in-progress negotiations from being switched to the - new ISAKMP SA. Any attempt at pre-expiry deletion of the ISAKMP SA - must be postponed until after such dangling negotiations are - completed, and there should be enough delay between ISAKMP-SA - rekeying and a deletion attempt to (more or less) ensure that there - are no negotiation-starting packets still in transit from before the - rekeying. - - At present, FreeS/WAN does none of this, and we don't KNOW of any - resulting trouble. With normal lifetimes, the problem should be - uncommon, and we speculate that an occasional disrupted negotiation - simply gets retried. - -4.6. Bulk Negotiation - - Quick Mode nominally provides for negotiating possibly-large numbers - of similar but unrelated IPsec SAs simultaneously [IKE, section 9]. - Nobody appears to do this. FreeS/WAN does not support it, and its - absence has caused no problems. - - - - - -Spencer & Redelmeier [Page 10] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - -5. Deletions, Teardowns, Crashes - - FreeS/WAN currently ignores all Notifications and Deletes, and never - generates them. This has caused little difficulty in - interoperability, which shouldn't be surprising (since Notification - and Delete support is officially entirely optional) but does seem to - surprise some people. Nevertheless, we do plan some changes to this - approach based on past experience. - -5.1. Deletions - - As hinted at above, we plan to implement Delete support, done as - follows. Shortly after rekeying of IPsec SAs, the Responder issues a - Delete for its old inbound SAs (but does not actually delete them - yet). The Responder initiates this because the Initiator started - using the new SAs on sending QM3, while the Responder started using - them only on (or somewhat after) receiving QM3, so there is less - chance of old-SA packets still being in transit from the Initiator. - The Initiator issues an unsolicited Delete only if it does not hear - one from the Responder after a longer delay. - - Either party, on receiving a Delete for one or more of the old - outbound SAs of a connection, deletes ALL the connection's SAs, and - acknowledges with a Delete for the old inbound SAs. A Delete for - nonexistent SAs (e.g., SAs which have already been expired or - deleted) is ignored. There is no retransmission of unacknowledged - Deletes. - - In the normal case, with prompt reliable transmission (except - possibly for loss of the Responder's initial Delete) and conforming - implementations on both ends, this results in three Deletes being - transmitted, resembling the classic three-way handshake. Loss of a - Delete after the first, or multiple losses, will cause the SAs not to - be deleted on at least one end. It appears difficult to do much - better without at least a distinction between request and - acknowledgement. - - RFC 2409 section 9 "strongly suggests" that there be no response to - informational messages such as Deletes, but the only rationale - offered is prevention of infinite loops endlessly exchanging "I don't - understand you" informationals. Since Deletes cannot lead to such a - loop (and in any case, the nonexistent-SA rule prevents more than one - acknowledgement for the same connection), we believe this - recommendation is inapplicable here. - - As noted in section 4.3, these Deletes are intended for resource - cleanup, not to control switching between SAs. But we expect that - they will improve interoperability with some broken implementations. - - - -Spencer & Redelmeier [Page 11] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - We believe strongly that connections need to be considered as a - whole, rather than treating each SA as an independent entity. We - will issue Deletes only for the full set of inbound SAs of a - connection, and will treat a Delete for any outbound SA as equivalent - to deletion of all the outbound SAs for the associated connection. - - The above is phrased in terms of IPsec SAs, but essentially the same - approach can be applied to ISAKMP SAs (the Deletes for the old ISAKMP - SA should be sent via the new one). - -5.2. Teardowns and Shutdowns - - When a connection is not intended to be up permanently, there is a - need to coordinate teardown, so that both ends are aware that the - connection is down. This is both for recovery of resources, and to - avoid routing packets through dangling SAs which can no longer - deliver them. - - Connection teardown will use the same bidirectional exchange of - Deletes as discussed in section 5.1: a Delete received for current - IPsec SAs (not yet obsoleted by rekeying) indicates that the other - host wishes to tear down the associated connection. - - A Delete received for a current ISAKMP SA indicates that the other - host wishes to tear down not only the ISAKMP SA but also all IPsec - SAs currently under the supervision of that ISAKMP SA. The 5.1 - bidirectional exchange might seem impossible in this case, since - reception of an ISAKMP-SA Delete indicates that the other end will - ignore further traffic on that ISAKMP SA. We suggest using the same - tactic discussed in 5.1 for IPsec SAs: the first Delete is sent - without actually doing the deletion, and the response to receiving a - Delete is to do the deletion and reply with another Delete. If there - is no response to the first Delete, retry a small number of times and - then give up and do the deletion; apart from being robust against - packet loss, this also maximizes the probability that an - implementation which does not do the bidirectional Delete will - receive at least one of the Deletes. - - When a host with current connections knows that it is about to shut - down, it will issue Deletes for all SAs involved (both IPsec and - ISAKMP), advising its peers (as per the meaning of Delete [ISAKMP, - section 3.15]) that the SAs have become useless. It will ignore - attempts at rekeying or connection startup thereafter, until it shuts - down. - - It would be better to have a Final-Contact notification, analogous to - Initial-Contact but indicating that no new negotiations should be - attempted until further notice. Initial-Contact actually could be - - - -Spencer & Redelmeier [Page 12] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - used for shutdown notification (!), but in networks where connections - are intended to exist permanently, it seems likely to provoke - unwanted attempts to renegotiate the lost connections. - -5.3. Crashes - - Systems sometimes crash. Coping with the resulting loss of - information is easily the most difficult problem we have found in - implementing robust IPsec systems. - - When connections are intended to be permanent, it is simple to - specify renegotiation on reboot. With our approach to SA selection - (see section 4.3), this handles such cases robustly and well. We do - have to tell users that BOTH hosts should be set this way. In cases - where crashes are synchronized (e.g. by power interruptions), this - may result in simultaneous negotiations at reboot. We currently - allow both negotiations to proceed to completion, but our use-newest - selection method effectively ignores one connection or the other, and - when one of them rekeys, we notice that the new SAs replace those of - both old connections, and we then refrain from rekeying the other. - (This duplicate detection is desirable in any event, for robustness, - to ensure that the system converges on a reasonable state eventually - after it is perturbed by difficulties or bugs.) - - When connections are not permanent, the situation is less happy. One - particular situation in which we see problems is when a number of - "Road Warrior" hosts occasionally call in to a central server. The - server is normally configured not to initiate such connections, since - it does not know when the Road Warrior is available (or what IP - address it is using). Unfortunately, if the server crashes and - reboots, any Road Warriors then connected have a problem: they don't - know that the server has crashed, so they can't renegotiate, and the - server has forgotten both the connections and their (transient) IP - addresses, so it cannot renegotiate. - - We believe that the simplest answer to this problem is what John - Denker has dubbed "address inertia": the server makes a best-effort - attempt to remember (in nonvolatile storage) which connections were - active and what the far-end addresses were (and what the successful - proposal's parameters were), so that it can attempt renegotiation on - reboot. We have not implemented this yet, but intend to; Denker has - implemented it himself, although in a somewhat messy way, and reports - excellent results. - -5.4. Network Partitions - - A network partition, making the two ends unable to reach each other, - has many of the same characteristics as having the other end crash... - - - -Spencer & Redelmeier [Page 13] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - until the network reconnects. It is desirable that recovery from - this be automatic. - - If the network reconnects before any rekeying attempts or other IKE - activities occurred, recovery is fully transparent, because the IKEs - have no idea that there was any problem. (Complaints such as ICMP - Host Unreachable messages are unauthenticated and hence cannot be - given much weight.) This fits the general mold of TCP/IP: if nobody - wanted to send any traffic, a network outage doesn't matter. - - If IKE activity did occur, the IKE implementation will discover that - the other end doesn't seem to be responding. The preferred response - to this depends on the nature of the connection. If it was intended - to be ephemeral (e.g. opportunistic encryption [OE]), closing it down - after a few retries is reasonable. If the other end is expected to - sometimes drop the connection without warning, it may not be - desirable to retry at all. (We support both these forms of - configurability, and indeed we also have a configuration option to - suppress rekeying entirely on one end.) - - If the connection was intended to be permanent, however, then - persistent attempts to re-establish it are appropriate. Some degree - of backoff is appropriate here, so that retries get less frequent as - the outage gets prolonged. Backoff should be limited, so that re- - established connectivity is not followed by a long delay before a - retry. Finally, after many retries (say 24 hours' worth), it may be - preferable to just declare the connection down and rely on manual - intervention to re-establish it, should this be desirable. We do not - yet fully support all this. - -5.5. Unknown SAs - - A more complete solution to crashes would be for an IPsec host to - note the arrival of ESP packets on an unknown IPsec SA, and report it - somehow to the other host, which can then decide to renegotiate. - This arguably might be preferable in any case--if the non-rebooted - host has no traffic to send, it does not care whether the connection - is intact--but delays and packet loss will be reduced if the - connection is renegotiated BEFORE there is traffic for it. So - unknown-SA detection is best reserved as a fallback method, with - address inertia used to deal with most such cases. - - A difficulty with unknown-SA detection is, just HOW should the other - host be notified? IKE provides no good way to do the notification: - Notification payloads (e.g., Initial-Contact) are unauthenticated - unless they are sent under protection of an ISAKMP SA. A "Security - Failures - Bad SPI" ICMP message [SECFAIL] is an interesting - alternative, but has the disadvantage of likewise being - - - -Spencer & Redelmeier [Page 14] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - unauthenticated. It's fundamentally unlikely that there is a simple - solution to this, given that almost any way of arranging or checking - authentication for such a notification is costly. - - We think the best answer to this is a two-step approach. An - unauthenticated Initial-Contact or Security Failures - Bad SPI cannot - be taken as a reliable report of a problem, but can be taken as a - hint that a problem MIGHT exist. Then there needs to be some - reliable way of checking such hints, subject to rate limiting since - the checks are likely to be costly (and checking the same connection - repeatedly at short intervals is unlikely to be worthwhile anyway). - So the rebooted host sends the notification, and the non-rebooted - host--which still thinks it has a connection--checks whether the - connection still works, and renegotiates if not. - - Also, if an IPsec host which believes it has a connection to another - host sees an unsuccessful attempt by that host to negotiate a new - one, that is also a hint of possible problems, justifying a check and - possible renegotiation. ("Unsuccessful" here means a negotiation - failure due to lack of a satisfactory proposal. A failure due to - authentication failure suggests a denial-of-service attack by a third - party, rather than a genuine problem on the legitimate other end.) - As noted in section 4.2, it is possible for negotiations to succeed - or fail based on which end initiates them, and some robustness - against that is desirable. - - We have not yet decided what form the notification should take. IKE - Initial-Contact is an obvious possibility, but has some - disadvantages. It does not specify which connection has had - difficulties. Also, the specification [IKE section 4.6.3.3] refers - to "remote system" and "sending system" without clearly specifying - just what "system" means; in the case of a multi-homed host using - multiple forms of identification, the question is not trivial. - Initial-Contact does have the fairly-decisive advantage that it is - likely to convey the right general meaning even to an implementation - which does not do things exactly the way ours does. - - A more fundamental difficulty is what form the reliable check takes. - What is wanted is an "IKE ping", verifying that the ISAKMP SA is - still intact (it being unlikely that IPsec SAs have been lost while - the ISAKMP SA has not). The lack of such a facility is a serious - failing of IKE. An acknowledged Notification of some sort would be - ideal, but there is none at present. Some existing implementations - are known to use the private Notification values 30000 as ping and - 30002 as ping reply, and that seems the most attractive choice at - present. If it is not recognized, there will probably be no reply, - and the result will be an unnecessary renegotiation, so this needs - strict rate limiting. (Also, when a new connection is set up, it's - - - -Spencer & Redelmeier [Page 15] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - probably worth determining by experiment whether the other end - supports IKE ping, and remembering that.) - - While we think this facility is desirable, and is about the best that - can be done with the poor tools available, we have not gotten very - far in implementation and cannot comment intelligently about how well - it works or interoperates. - -6. Misc. IKE Issues - -6.1. Groups 1 and 5 - - We have dropped support for the first Oakley Group (group 1), despite - it being officially mandatory, on the grounds that it is grossly too - weak to provide enough randomness for 3DES. There have been some - interoperability problems, mostly quite minor: ALMOST everyone - supports group 2 as well, although sometimes it has to be explicitly - configured. - - We also support the quasi-standard group 5 [GROUPS]. This has not - been seriously exercised yet, because historically we offered group 2 - first and almost everyone accepted it. We have recently changed to - offering group 5 first, and no difficulties have been reported. - -6.2. To PFS Or Not To PFS - - A persistent small interoperability problem is that the presence or - absence of PFS (for keys [IKE, section 5.5]) is neither negotiated - nor announced. We have it enabled by default, and successful - interoperation often requires having the other end turn it on in - their implementation, or having the FreeS/WAN end disable it. Almost - everyone supports it, but it's usually not the default, and - interoperability is often impossible unless the two ends somehow - reach prior agreement on it. - - We do not explicitly support the other flavor of PFS, for identities - [IKE, section 8], and this has caused no interoperability problems. - -6.3. Debugging Tools, Lack Thereof - - We find IKE lacking in basic debugging tools. Section 5.4, above, - notes that an IKE ping would be useful for connectivity verification. - It would also be extremely helpful for determining that UDP/500 - packets get back and forth successfully between the two ends, which - is often an important first step in debugging. - - It's also quite common to have IKE negotiate a connection - successfully, but to have some firewall along the way blocking ESP. - - - -Spencer & Redelmeier [Page 16] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - Users find this mysterious and difficult to diagnose. We have no - immediate suggestions on what could be done about it. - -6.4. Terminology, Vagueness Thereof - - The terminology of IPsec needs work. We feel that both the - specifications and user-oriented documentation would be greatly - clarified by concise, intelligible names for certain concepts. - - We semi-consistently use "group" for the set of IPsec SAs which are - established in one direction by a single Quick Mode negotiation and - are used together to process a packet (e.g., an ESP SA plus an AH - SA), "connection" for the logical packet path provided by a - succession of pairs of groups (each rekeying providing a new pair, - one group in each direction), and "keying channel" for the - corresponding supervisory path provided by a sequence of ISAKMP SAs. - - We think it's a botch that "PFS" is used to refer to two very - different things, but we have no specific new terms to suggest, since - we only implement one kind of PFS and thus can just ignore the other. - -6.5. A Question of Identity - - One specification problem deserves note: exactly when can an existing - phase 1 negotiation be re-used for a new phase 2 negotiation, as IKE - [IKE, section 4] specifies? Presumably, when it connects the same - two "parties"... but exactly what is a "party"? - - As noted in section 5.4, in cases involving multi-homing and multiple - identities, it's not clear exactly what criteria are used for - deciding whether the intended far end for a new negotiation is the - same one as for a previous negotiation. Is it by Identification - Payload? By IP address? Or what? - - We currently use a somewhat-vague notion of "identity", basically - what gets sent in Identification Payloads, for this, and this seems - to be successful, but we think this needs better specification. - -6.6. Opportunistic Encryption - - Further IKE challenges appear in the context of Opportunistic - Encryption [OE], but operational experience with it is too limited as - yet for us to comment usefully right now. - -6.7. Authentication and RSA Keys - - We provide two IKE authentication methods: shared secrets ("pre- - shared keys") and RSA digital signatures. (A user-provided add-on - - - -Spencer & Redelmeier [Page 17] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - package generalizes the latter to limited support for certificates; - we have not worked extensively with it ourselves yet and cannot - comment on it yet.) - - Shared secrets, despite their administrative difficulties, see - considerable use, and are also the method of last resort for - interoperability problems. - - For digital signatures, we have taken the somewhat unorthodox - approach of using "bare" RSA public keys, either supplied in - configuration files or fetched from DNS, rather than getting involved - in the complexity of certificates. We encode our RSA public keys - using the DNS KEY encoding [DNSRSA] (aka "RFC 2537", although that - RFC is now outdated), which has given us no difficulties and which we - highly recommend. We have seen two difficulties in connection with - RSA keys, however. - - First, while a number of IPsec implementations are able to take - "bare" RSA public keys, each one seems to have its own idea of what - format should be used for transporting them. We've had little - success with interoperability here, mostly because of key-format - issues; the implementations generally WILL interoperate successfully - if you can somehow get an RSA key into them at all, but that's hard. - X.509 certificates seem to be the lowest (!) common denominator for - key transfer. - - Second, although the content of RSA public keys has been stable, - there has been a small but subtle change over time in the content of - RSA private keys. The "internal modulus", used to compute the - private exponent "d" from the public exponent "e" (or vice-versa) was - originally [RSA] [PKCS1v1] [SCHNEIER] specified to be (p-1)*(q-1), - where p and q are the two primes. However, more recent definitions - [PKCS1v2] call it "lambda(n)" and define it to be lcm(p-1, q-1); this - appears to be a minor optimization. The result is that private keys - generated with the new definition often fail consistency checks in - implementations using the old definition. Fortunately, it is seldom - necessary to move private keys around. Our software now consistently - uses the new definition (and thus will accept keys generated with - either definition), but our key generator also has an option to - generate old-definition keys, for the benefit of users who upgrade - their networks incrementally. - -6.8. Misc. Snags - - Nonce size is another characteristic that is neither negotiated nor - announced but that the two ends must somehow be able to agree on. - Our software accepts anything between 8 and 256, and defaults to 16. - These numbers were chosen rather arbitrarily, but we have seen no - - - -Spencer & Redelmeier [Page 18] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - interoperability failures here. - - Nothing in the ISAKMP [ISAKMP] or IKE [IKE] specifications says - explicitly that a normal Message ID must be non-zero, but a zero - Message ID in fact causes failures. - - Similarly, there is nothing in the specs which says that ISAKMP - cookies must be non-zero, but zero cookies will in fact cause - trouble. - -7. Security Considerations - - Since this document discusses aspects of building robust and - interoperable IPsec implementations, security considerations permeate - it. - -8. References - - [AH] Kent, S., and Atkinson, R., "IP Authentication Header", - RFC 2402, Nov 1998. - - [CIPHERS] Pereira, R., and Adams, R., "The ESP CBC-Mode Cipher - Algorithms", RFC 2451, Nov 1998. - - [CRACK] Electronic Frontier Foundation, "Cracking DES: Secrets of - Encryption Research, Wiretap Politics and Chip Design", - O'Reilly 1998, ISBN 1-56592-520-3. - - [DES] Madson, C., and Doraswamy, N., "The ESP DES-CBC Cipher - Algorithm", RFC 2405, Nov 1998. - - [DNSRSA] D. Eastlake 3rd, "RSA/SHA-1 SIGs and RSA KEYs in the - Domain Name System (DNS)", RFC 3110, May 2001. - - [ESP] Kent, S., and Atkinson, R., "IP Encapsulating Security - Payload (ESP)", RFC 2406, Nov 1998. - - [GROUPS] Kivinen, T., and Kojo, M., "More MODP Diffie-Hellman - groups for IKE", <draft-ietf-ipsec-ike-modp- - groups-04.txt>, 13 Dec 2001 (work in progress). - - [IKE] Harkins, D., and Carrel, D., "The Internet Key Exchange - (IKE)", RFC 2409, Nov 1998. - - [IPSEC] Kent, S., and Atkinson, R., "Security Architecture for the - Internet Protocol", RFC 2401, Nov 1998. - - - - - -Spencer & Redelmeier [Page 19] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - [ISAKMP] Maughan, D., Schertler, M., Schneider, M., and Turner, J., - "Internet Security Association and Key Management Protocol - (ISAKMP)", RFC 2408, Nov 1998. - - [OE] Richardson, M., Redelmeier, D. H., and Spencer, H., "A - method for doing opportunistic encryption with IKE", - <draft-richardson-ipsec-opportunistic-06.txt>, 21 Feb 2002 - (work in progress). - - [PKCS1v1] Kaliski, B., "PKCS #1: RSA Encryption, Version 1.5", RFC - 2313, March 1998. - - [PKCS1v2] Kaliski, B., and Staddon, J., "PKCS #1: RSA Cryptography - Specifications, Version 2.0", RFC 2437, Oct 1998. - - [PFKEY] McDonald, D., Metz, C., and Phan, B., "PF_KEY Key - Management API, Version 2", RFC 2367, July 1998. - - [REKEY] Tim Jenkins, "IPsec Re-keying Issues", <draft-jenkins- - ipsec-rekeying-06.txt>, 2 May 2000 (draft expired, work no - longer in progress). - - [REPLAY] Krywaniuk, A., "Using Isakmp Message Ids for Replay - Protection", <draft-krywaniuk-ipsec-antireplay-00.txt>, 9 - July 2001 (work in progress). - - [RSA] Rivest, R.L., Shamir, A., and Adleman, L., "A Method for - Obtaining Digital Signatures and Public-Key - Cryptosystems", Communications of the ACM v21n2, Feb 1978, - p. 120. - - [SCHNEIER] Bruce Schneier, "Applied Cryptography", 2nd ed., Wiley - 1996, ISBN 0-471-11709-9. - - [SECFAIL] Karn, P., and Simpson, W., "ICMP Security Failures - Messages", RFC 2521, March 1999. - -Authors' Addresses - - Henry Spencer - SP Systems - Box 280 Stn. A - Toronto, Ont. M5W1B2 - Canada - - henry@spsystems.net - 416-690-6561 - - - - -Spencer & Redelmeier [Page 20] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - - D. Hugh Redelmeier - Mimosa Systems Inc. - 29 Donino Ave. - Toronto, Ont. M4N2W6 - Canada - - hugh@mimosa.com - 416-482-8253 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Spencer & Redelmeier [Page 21] - -Internet Draft IKE Implementation Issues 26 Feb 2002 - - -Full Copyright Statement - - Copyright (C) The Internet Society 2002. All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implmentation may be prepared, copied, published and - distributed, in whole or in part, without restriction of any kind, - provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - -Spencer & Redelmeier [Page 22] - diff --git a/doc/manpage.d/ipsec.8.html b/doc/manpage.d/ipsec.8.html deleted file mode 100644 index ff9b7ca39..000000000 --- a/doc/manpage.d/ipsec.8.html +++ /dev/null @@ -1,215 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC</TITLE> -</HEAD><BODY> -<H1>IPSEC</H1> -Section: Maintenance Commands (8)<BR>Updated: 26 March 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec - invoke IPsec utilities -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -command [ argument ...] -<P> -<B>ipsec</B> - -<B>--help</B> - -<BR> - -<B>ipsec</B> - -<B>--version</B> - -<BR> - -<B>ipsec</B> - -<B>--versioncode</B> - -<BR> - -<B>ipsec</B> - -<B>--copyright</B> - -<BR> - -<B>ipsec</B> - -<B>--directory</B> - -<BR> - -<B>ipsec</B> - -<B>--confdir</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ipsec</I> - -invokes any of several utilities involved in controlling the IPsec -encryption/authentication system, -running the specified -<I>command</I> - -with the specified -<I>argument</I>s - -as if it had been invoked directly. -This largely eliminates possible name collisions with other software, -and also permits some centralized services. -<P> - -In particular, -<I>ipsec</I> - -supplies the invoked -<I>command</I> - -with a suitable PATH environment variable, -and also provides IPSEC_DIR, -IPSEC_CONFS, and IPSEC_VERSION environment variables, -containing respectively -the full pathname of the directory where the IPsec utilities are stored, -the full pathname of the directory where the configuration files live, -and the IPsec version number. -<P> - -<B>ipsec --help</B> - -lists the available commands. -Most have their own manual pages, e.g. -<I><A HREF="ipsec_auto.8.html">ipsec_auto</A></I>(8) - -for -<I>auto</I>. - -<P> - -<B>ipsec --version</B> - -outputs version information about Linux FreeS/WAN. -A version code of the form ``U<I>xxx</I>/K<I>yyy</I>'' -indicates that the user-level utilities are version <I>xxx</I> -but the kernel portion appears to be version <I>yyy</I> -(this form is used only if the two disagree). -<P> - -<B>ipsec --versioncode</B> - -outputs <I>just</I> the version code, -with none of -<B>--version</B>'s - -supporting information, -for use by scripts. -<P> - -<B>ipsec --copyright</B> - -supplies boring copyright details. -<P> - -<B>ipsec --directory</B> - -reports where -<I>ipsec</I> - -thinks the IPsec utilities are stored. -<P> - -<B>ipsec --confdir</B> - -reports where -<I>ipsec</I> - -thinks the IPsec configuration files are stored. -<A NAME="lbAE"> </A> -<H2>FILES</H2> - -/usr/local/lib/ipsec<TT> </TT>usual utilities directory<BR> -<A NAME="lbAF"> </A> -<H2>ENVIRONMENT</H2> - -<P> - -The following environment variables control where FreeS/WAN finds its -components. -The -<B>ipsec</B> - -command sets them if they are not already set. -<PRE> -IPSEC_EXECDIR directory containing published commands -IPSEC_LIBDIR directory containing internal executables -IPSEC_SBINDIR directory containing <B>ipsec</B> command -IPSEC_CONFS directory containing configuration files -</PRE> - -<A NAME="lbAG"> </A> -<H2>SEE ALSO</H2> - - - -<A HREF="ipsec.conf.5.html">ipsec.conf</A>(5), <A HREF="ipsec.secrets.5.html">ipsec.secrets</A>(5), -<A HREF="ipsec_auto.8.html">ipsec_auto</A>(8), -<A HREF="ipsec_barf.8.html">ipsec_barf</A>(8), -<A HREF="ipsec_setup.8.html">ipsec_setup</A>(8), -<A HREF="ipsec_showdefaults.8.html">ipsec_showdefaults</A>(8), -<A HREF="ipsec_showhostkey.8.html">ipsec_showhostkey</A>(8) - - -<P> - -HTML documentation shipped with the release, starting with -<I>doc/index.html</I>. - -<I><<A HREF="http://www.freeswan.org/doc.html">http://www.freeswan.org/doc.html</A>></I> - -may also be of use. -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for Linux FreeS/WAN -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Henry Spencer. -<A NAME="lbAI"> </A> -<H2>BUGS</H2> - -The provision of centralized services, -while convenient, -does compromise the original concept of making the utilities -invocable directly as well as via -<I>ipsec</I>. - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">ENVIRONMENT</A><DD> -<DT><A HREF="#lbAG">SEE ALSO</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -<DT><A HREF="#lbAI">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec.conf.5.html b/doc/manpage.d/ipsec.conf.5.html deleted file mode 100644 index 36e0452ef..000000000 --- a/doc/manpage.d/ipsec.conf.5.html +++ /dev/null @@ -1,1830 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC.CONF</TITLE> -</HEAD><BODY> -<H1>IPSEC.CONF</H1> -Section: File Formats (5)<BR>Updated: 26 Nov 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec.conf - IPsec configuration and connections -<A NAME="lbAC"> </A> -<H2>DESCRIPTION</H2> - -The optional -<I>ipsec.conf</I> - -file -specifies most configuration and control information for the -FreeS/WAN IPsec subsystem. -(The major exception is secrets for authentication; -see -<I><A HREF="ipsec.secrets.5.html">ipsec.secrets</A></I>(5).) - -Its contents are not security-sensitive -<I>unless</I> - -manual keying is being done for more than just testing, -in which case the encryption/authentication keys in the -descriptions for the manually-keyed connections are very sensitive -(and those connection descriptions -are probably best kept in a separate file, -via the include facility described below). -<P> - -The file is a text file, consisting of one or more -<I>sections</I>. - -White space followed by -<B>#</B> - -followed by anything to the end of the line -is a comment and is ignored, -as are empty lines which are not within a section. -<P> - -A line which contains -<B>include</B> - -and a file name, separated by white space, -is replaced by the contents of that file, -preceded and followed by empty lines. -If the file name is not a full pathname, -it is considered to be relative to the directory containing the -including file. -Such inclusions can be nested. -Only a single filename may be supplied, and it may not contain white space, -but it may include shell wildcards (see -<I><A HREF="sh.1.html">sh</A></I>(1)); - -for example: -<P> - -<B>include</B> - -<B>ipsec.*.conf</B> - -<P> - -The intention of the include facility is mostly to permit keeping -information on connections, or sets of connections, -separate from the main configuration file. -This permits such connection descriptions to be changed, -copied to the other security gateways involved, etc., -without having to constantly extract them from the configuration -file and then insert them back into it. -Note also the -<B>also</B> - -and -<B>alsoflip</B> - -parameters (described below) which permit splitting a single logical section -(e.g. a connection description) into several actual sections. -<P> - -The first significant line of the file must specify the version -of this specification that it conforms to: -<P> - -<B>version 2</B> -<P> - -A section -begins with a line of the form: -<P> - -<I>type</I> - -<I>name</I> - -<P> - -where -<I>type</I> - -indicates what type of section follows, and -<I>name</I> - -is an arbitrary name which distinguishes the section from others -of the same type. -(Names must start with a letter and may contain only -letters, digits, periods, underscores, and hyphens.) -All subsequent non-empty lines -which begin with white space are part of the section; -comments within a section must begin with white space too. -There may be only one section of a given type with a given name. -<P> - -Lines within the section are generally of the form -<P> - - <I>parameter</I><B>=</B><I>value</I> -<P> - -(note the mandatory preceding white space). -There can be white space on either side of the -<B>=</B>. - -Parameter names follow the same syntax as section names, -and are specific to a section type. -Unless otherwise explicitly specified, -no parameter name may appear more than once in a section. -<P> - -An empty -<I>value</I> - -stands for the system default value (if any) of the parameter, -i.e. it is roughly equivalent to omitting the parameter line entirely. -A -<I>value</I> - -may contain white space only if the entire -<I>value</I> - -is enclosed in double quotes (<B>"</B>); -a -<I>value</I> - -cannot itself contain a double quote, -nor may it be continued across more than one line. -<P> - -Numeric values are specified to be either an ``integer'' -(a sequence of digits) or a ``decimal number'' -(sequence of digits optionally followed by `.' and another sequence of digits). -<P> - -There is currently one parameter which is available in any type of -section: -<DL COMPACT> -<DT><B>also</B> - -<DD> -the value is a section name; -the parameters of that section are appended to this section, -as if they had been written as part of it. -The specified section must exist, must follow the current one, -and must have the same section type. -(Nesting is permitted, -and there may be more than one -<B>also</B> - -in a single section, -although it is forbidden to append the same section more than once.) -This allows, for example, keeping the encryption keys -for a connection in a separate file -from the rest of the description, by using both an -<B>also</B> - -parameter and an -<B>include</B> - -line. -(Caution, see BUGS below for some restrictions.) -<DT><B>alsoflip</B> - -<DD> -can be used in a -<B>conn</B> - -section. -It acts like an -<B>also</B> - -that flips the referenced section's entries left-for-right. -</DL> -<P> - -Parameter names beginning with -<B>x-</B> - -(or -<B>X-</B>, - -or -<B>x_</B>, - -or -<B>X_</B>) - -are reserved for user extensions and will never be assigned meanings -by IPsec. -Parameters with such names must still observe the syntax rules -(limits on characters used in the name; -no white space in a non-quoted value; -no newlines or double quotes within the value). -All other as-yet-unused parameter names are reserved for future IPsec -improvements. -<P> - -A section with name -<B>%default</B> - -specifies defaults for sections of the same type. -For each parameter in it, -any section of that type which does not have a parameter of the same name -gets a copy of the one from the -<B>%default</B> - -section. -There may be multiple -<B>%default</B> - -sections of a given type, -but only one default may be supplied for any specific parameter name, -and all -<B>%default</B> - -sections of a given type must precede all non-<B>%default</B> - -sections of that type. -<B>%default</B> - -sections may not contain -<B>also</B> - -or -<B>alsoflip</B> - -parameters. -<P> - -Currently there are two types of section: -a -<B>config</B> - -section specifies general configuration information for IPsec, -while a -<B>conn</B> - -section specifies an IPsec connection. -<A NAME="lbAD"> </A> -<H2>CONN SECTIONS</H2> - -A -<B>conn</B> - -section contains a -<I>connection specification</I>, - -defining a network connection to be made using IPsec. -The name given is arbitrary, and is used to identify the connection to -<I><A HREF="ipsec_auto.8.html">ipsec_auto</A></I>(8) - -and -<I><A HREF="ipsec_manual.8.html">ipsec_manual</A></I>(8). - -Here's a simple example: -<P> - - -<PRE> -<B> -conn snt - left=10.11.11.1 - leftsubnet=10.0.1.0/24 - leftnexthop=172.16.55.66 - right=192.168.22.1 - rightsubnet=10.0.2.0/24 - rightnexthop=172.16.88.99 - keyingtries=%forever -</B></PRE> - -<P> - -A note on terminology... -In automatic keying, there are two kinds of communications going on: -transmission of user IP packets, and gateway-to-gateway negotiations for -keying, rekeying, and general control. -The data path (a set of ``IPsec SAs'') used for user packets is herein -referred to as the ``connection''; -the path used for negotiations (built with ``ISAKMP SAs'') is referred to as -the ``keying channel''. -<P> - -To avoid trivial editing of the configuration file to suit it to each system -involved in a connection, -connection specifications are written in terms of -<I>left</I> - -and -<I>right</I> - -participants, -rather than in terms of local and remote. -Which participant is considered -<I>left</I> - -or -<I>right</I> - -is arbitrary; -IPsec figures out which one it is being run on based on internal information. -This permits using identical connection specifications on both ends. -There are cases where there is no symmetry; a good convention is to -use -<I>left</I> - -for the local side and -<I>right</I> - -for the remote side (the first letters are a good mnemonic). -<P> - -Many of the parameters relate to one participant or the other; -only the ones for -<I>left</I> - -are listed here, but every parameter whose name begins with -<B>left</B> - -has a -<B>right</B> - -counterpart, -whose description is the same but with -<B>left</B> - -and -<B>right</B> - -reversed. -<P> - -Parameters are optional unless marked ``(required)''; -a parameter required for manual keying need not be included for -a connection which will use only automatic keying, and vice versa. -<A NAME="lbAE"> </A> -<H3>CONN PARAMETERS: GENERAL</H3> - -The following parameters are relevant to both automatic and manual keying. -Unless otherwise noted, -for a connection to work, -in general it is necessary for the two ends to agree exactly -on the values of these parameters. -<DL COMPACT> -<DT><B>type</B> - -<DD> -the type of the connection; currently the accepted values -are -<B>tunnel</B> - -(the default) -signifying a host-to-host, host-to-subnet, or subnet-to-subnet tunnel; -<B>transport</B>, - -signifying host-to-host transport mode; -<B>passthrough</B>, - -signifying that no IPsec processing should be done at all; -<B>drop</B>, - -signifying that packets should be discarded; and -<B>reject</B>, - -signifying that packets should be discarded and a diagnostic ICMP returned. -<DT><B>left</B> - -<DD> -(required) -the IP address of the left participant's public-network interface, -in any form accepted by -<I><A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A></I>(3) - -or one of several magic values. -If it is -<B>%defaultroute</B>, - -and -the -<B>config</B> - -<B>setup</B> - -section's, -<B>interfaces</B> - -specification contains -<B>%defaultroute,</B> - -<B>left</B> - -will be filled in automatically with the local address -of the default-route interface (as determined at IPsec startup time); -this also overrides any value supplied for -<B>leftnexthop</B>. - -(Either -<B>left</B> - -or -<B>right</B> - -may be -<B>%defaultroute</B>, - -but not both.) -The value -<B>%any</B> - -signifies an address to be filled in (by automatic keying) during -negotiation. -The value -<B>%opportunistic</B> - -signifies that both -<B>left</B> - -and -<B>leftnexthop</B> - -are to be filled in (by automatic keying) from DNS data for -<B>left</B>'s - -client. -The values -<B>%group</B> - -and -<B>%opportunisticgroup</B> - -makes this a policy group conn: one that will be instantiated -into a regular or opportunistic conn for each CIDR block listed in the -policy group file with the same name as the conn. -<DT><B>leftsubnet</B> - -<DD> -private subnet behind the left participant, expressed as -<I>network</I><B>/</B><I>netmask</I> -(actually, any form acceptable to -<I><A HREF="ipsec_ttosubnet.3.html">ipsec_ttosubnet</A></I>(3)); - -if omitted, essentially assumed to be <I>left</I><B>/32</B>, -signifying that the left end of the connection goes to the left participant only -<DT><B>leftnexthop</B> - -<DD> -next-hop gateway IP address for the left participant's connection -to the public network; -defaults to -<B>%direct</B> - -(meaning -<I>right</I>). - -If the value is to be overridden by the -<B>left=%defaultroute</B> - -method (see above), -an explicit value must -<I>not</I> - -be given. -If that method is not being used, -but -<B>leftnexthop</B> - -is -<B>%defaultroute</B>, - -and -<B>interfaces=%defaultroute</B> - -is used in the -<B>config</B> - -<B>setup</B> - -section, -the next-hop gateway address of the default-route interface -will be used. -The magic value -<B>%direct</B> - -signifies a value to be filled in (by automatic keying) -with the peer's address. -Relevant only locally, other end need not agree on it. -<DT><B>leftupdown</B> - -<DD> -what ``updown'' script to run to adjust routing and/or firewalling -when the status of the connection -changes (default -<B>ipsec _updown</B>). - -May include positional parameters separated by white space -(although this requires enclosing the whole string in quotes); -including shell metacharacters is unwise. -See -<I><A HREF="ipsec_pluto.8.html">ipsec_pluto</A></I>(8) - -for details. -Relevant only locally, other end need not agree on it. -<DT><B>leftfirewall</B> - -<DD> -whether the left participant is doing forwarding-firewalling -(including masquerading) for traffic from <I>leftsubnet</I>, -which should be turned off (for traffic to the other subnet) -once the connection is established; -acceptable values are -<B>yes</B> - -and (the default) -<B>no</B>. - -May not be used in the same connection description with -<B>leftupdown</B>. - -Implemented as a parameter to the default -<I>updown</I> - -script. -See notes below. -Relevant only locally, other end need not agree on it. -</DL> -<P> - -If one or both security gateways are doing forwarding firewalling -(possibly including masquerading), -and this is specified using the firewall parameters, -tunnels established with IPsec are exempted from it -so that packets can flow unchanged through the tunnels. -(This means that all subnets connected in this manner must have -distinct, non-overlapping subnet address blocks.) -This is done by the default -<I>updown</I> - -script (see -<I><A HREF="ipsec_pluto.8.html">ipsec_pluto</A></I>(8)). - -<P> - -The implementation of this makes certain assumptions about firewall setup, -notably the use of the old -<I>ipfwadm</I> - -interface to the firewall. -In situations calling for more control, -it may be preferable for the user to supply his own -<I>updown</I> - -script, -which makes the appropriate adjustments for his system. -<A NAME="lbAF"> </A> -<H3>CONN PARAMETERS: AUTOMATIC KEYING</H3> - -The following parameters are relevant only to automatic keying, -and are ignored in manual keying. -Unless otherwise noted, -for a connection to work, -in general it is necessary for the two ends to agree exactly -on the values of these parameters. -<DL COMPACT> -<DT><B>keyexchange</B> - -<DD> -method of key exchange; -the default and currently the only accepted value is -<B>ike</B> - -<DT><B>auto</B> - -<DD> -what operation, if any, should be done automatically at IPsec startup; -currently-accepted values are -<B>add</B> - -(signifying an -<B>ipsec auto</B> - -<B>--add</B>), - -<B>route</B> - -(signifying that plus an -<B>ipsec auto</B> - -<B>--route</B>), - -<B>start</B> - -(signifying that plus an -<B>ipsec auto</B> - -<B>--up</B>), - -<B>manual</B> - -(signifying an -<B>ipsec</B> - -<B>manual</B> - -<B>--up</B>), - -and -<B>ignore</B> - -(also the default) (signifying no automatic startup operation). -See the -<B>config</B> - -<B>setup</B> - -discussion below. -Relevant only locally, other end need not agree on it -(but in general, for an intended-to-be-permanent connection, -both ends should use -<B>auto=start</B> - -to ensure that any reboot causes immediate renegotiation). -<DT><B>auth</B> - -<DD> -whether authentication should be done as part of -ESP encryption, or separately using the AH protocol; -acceptable values are -<B>esp</B> - -(the default) and -<B>ah</B>. - -<DT><B>authby</B> - -<DD> -how the two security gateways should authenticate each other; -acceptable values are -<B>secret</B> - -for shared secrets, -<B>rsasig</B> - -for RSA digital signatures (the default), -<B>secret|rsasig</B> - -for either, and -<B>never</B> - -if negotiation is never to be attempted or accepted (useful for shunt-only conns). -Digital signatures are superior in every way to shared secrets. -<DT><B>leftid</B> - -<DD> -how -the left participant -should be identified for authentication; -defaults to -<B>left</B>. - -Can be an IP address (in any -<I><A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A></I>(3) - -syntax) -or a fully-qualified domain name preceded by -<B>@</B> - -(which is used as a literal string and not resolved). -The magic value -<B>%myid</B> - -stands for the current setting of <I>myid</I>. -This is set in <B>config setup</B> or by <I><A HREF="ipsec_whack.8.html">ipsec_whack</A></I>(8)), or, if not set, -it is the IP address in <B>%defaultroute</B> (if that is supported by a TXT record in its reverse domain), or otherwise -it is the system's hostname (if that is supported by a TXT record in its forward domain), or otherwise it is undefined. -<DT><B>leftrsasigkey</B> - -<DD> -the left participant's -public key for RSA signature authentication, -in RFC 2537 format using -<I><A HREF="ipsec_ttodata.3.html">ipsec_ttodata</A></I>(3) - -encoding. -The magic value -<B>%none</B> - -means the same as not specifying a value (useful to override a default). -The value -<B>%dnsondemand</B> - -(the default) -means the key is to be fetched from DNS at the time it is needed. -The value -<B>%dnsonload</B> - -means the key is to be fetched from DNS at the time -the connection description is read from -<I>ipsec.conf</I>; - -currently this will be treated as -<B>%none</B> - -if -<B>right=%any</B> - -or -<B>right=%opportunistic</B>. - -The value -<B>%dns</B> - -is currently treated as -<B>%dnsonload</B> - -but will change to -<B>%dnsondemand</B> - -in the future. -The identity used for the left participant -must be a specific host, not -<B>%any</B> - -or another magic value. -<B>Caution:</B> - -if two connection descriptions -specify different public keys for the same -<B>leftid</B>, - -confusion and madness will ensue. -<DT><B>leftrsasigkey2</B> - -<DD> -if present, a second public key. -Either key can authenticate the signature, allowing for key rollover. -<DT><B>pfs</B> - -<DD> -whether Perfect Forward Secrecy of keys is desired on the connection's -keying channel -(with PFS, penetration of the key-exchange protocol -does not compromise keys negotiated earlier); -acceptable values are -<B>yes</B> - -(the default) -and -<B>no</B>. - -<DT><B>keylife</B> - -<DD> -how long a particular instance of a connection -(a set of encryption/authentication keys for user packets) should last, -from successful negotiation to expiry; -acceptable values are an integer optionally followed by -<B>s</B> - -(a time in seconds) -or a decimal number followed by -<B>m</B>, - -<B>h</B>, - -or -<B>d</B> - -(a time -in minutes, hours, or days respectively) -(default -<B>8.0h</B>, - -maximum -<B>24h</B>). - -Normally, the connection is renegotiated (via the keying channel) -before it expires. -The two ends need not exactly agree on -<B>keylife</B>, - -although if they do not, -there will be some clutter of superseded connections on the end -which thinks the lifetime is longer. -<DT><B>rekey</B> - -<DD> -whether a connection should be renegotiated when it is about to expire; -acceptable values are -<B>yes</B> - -(the default) -and -<B>no</B>. - -The two ends need not agree, -but while a value of -<B>no</B> - -prevents Pluto from requesting renegotiation, -it does not prevent responding to renegotiation requested from the other end, -so -<B>no</B> - -will be largely ineffective unless both ends agree on it. -<DT><B>rekeymargin</B> - -<DD> -how long before connection expiry or keying-channel expiry -should attempts to -negotiate a replacement -begin; acceptable values as for -<B>keylife</B> - -(default -<B>9m</B>). - -Relevant only locally, other end need not agree on it. -<DT><B>rekeyfuzz</B> - -<DD> -maximum percentage by which -<B>rekeymargin</B> - -should be randomly increased to randomize rekeying intervals -(important for hosts with many connections); -acceptable values are an integer, -which may exceed 100, -followed by a `%' -(default set by -<I><A HREF="ipsec_pluto.8.html">ipsec_pluto</A></I>(8), - -currently -<B>100%</B>). - -The value of -<B>rekeymargin</B>, - -after this random increase, -must not exceed -<B>keylife</B>. - -The value -<B>0%</B> - -will suppress time randomization. -Relevant only locally, other end need not agree on it. -<DT><B>keyingtries</B> - -<DD> -how many attempts (a whole number or <B>%forever</B>) should be made to -negotiate a connection, or a replacement for one, before giving up -(default -<B>%forever</B>). - -The value <B>%forever</B> -means ``never give up'' (obsolete: this can be written <B>0</B>). -Relevant only locally, other end need not agree on it. -<DT><B>ikelifetime</B> - -<DD> -how long the keying channel of a connection (buzzphrase: ``ISAKMP SA'') -should last before being renegotiated; -acceptable values as for -<B>keylife</B> - -(default set by -<I><A HREF="ipsec_pluto.8.html">ipsec_pluto</A></I>(8), - -currently -<B>1h</B>, - -maximum -<B>8h</B>). - -The two-ends-disagree case is similar to that of -<B>keylife</B>. - -<DT><B>compress</B> - -<DD> -whether IPComp compression of content is proposed on the connection -(link-level compression does not work on encrypted data, -so to be effective, compression must be done <I>before</I> encryption); -acceptable values are -<B>yes</B> - -and -<B>no</B> - -(the default). -The two ends need not agree. -A value of -<B>yes</B> - -causes IPsec to propose both compressed and uncompressed, -and prefer compressed. -A value of -<B>no</B> - -prevents IPsec from proposing compression; -a proposal to compress will still be accepted. -<DT><B>disablearrivalcheck</B> - -<DD> -whether KLIPS's normal tunnel-exit check -(that a packet emerging from a tunnel has plausible addresses in its header) -should be disabled; -acceptable values are -<B>yes</B> - -and -<B>no</B> - -(the default). -Tunnel-exit checks improve security and do not break any normal configuration. -Relevant only locally, other end need not agree on it. -<DT><B>failureshunt</B> - -<DD> -what to do with packets when negotiation fails. -The default is -<B>none</B>: - -no shunt; -<B>passthrough</B>, - -<B>drop</B>, - -and -<B>reject</B> - -have the obvious meanings. -</DL> -<A NAME="lbAG"> </A> -<H3>CONN PARAMETERS: MANUAL KEYING</H3> - -The following parameters are relevant only to manual keying, -and are ignored in automatic keying. -Unless otherwise noted, -for a connection to work, -in general it is necessary for the two ends to agree exactly -on the values of these parameters. -A manually-keyed -connection must specify at least one of AH or ESP. -<DL COMPACT> -<DT><B>spi</B> - -<DD> -(this or -<B>spibase</B> - -required for manual keying) -the SPI number to be used for the connection (see -<I><A HREF="ipsec_manual.8.html">ipsec_manual</A></I>(8)); - -must be of the form <B>0x</B><I>hex</I><B></B>, -where -<I>hex</I> - -is one or more hexadecimal digits -(note, it will generally be necessary to make -<I>spi</I> - -at least -<B>0x100</B> - -to be acceptable to KLIPS, -and use of SPIs in the range -<B>0x100</B>-<B>0xfff</B> - -is recommended) -<DT><B>spibase</B> - -<DD> -(this or -<B>spi</B> - -required for manual keying) -the base number for the SPIs to be used for the connection (see -<I><A HREF="ipsec_manual.8.html">ipsec_manual</A></I>(8)); - -must be of the form <B>0x</B><I>hex</I><B>0</B>, -where -<I>hex</I> - -is one or more hexadecimal digits -(note, it will generally be necessary to make -<I>spibase</I> - -at least -<B>0x100</B> - -for the resulting SPIs -to be acceptable to KLIPS, -and use of numbers in the range -<B>0x100</B>-<B>0xff0</B> - -is recommended) -<DT><B>esp</B> - -<DD> -ESP encryption/authentication algorithm to be used -for the connection, e.g. -<B>3des-md5-96</B> - -(must be suitable as a value of -<I><A HREF="ipsec_spi.8.html">ipsec_spi</A></I>(8)'s - -<B>--esp</B> - -option); -default is not to use ESP -<DT><B>espenckey</B> - -<DD> -ESP encryption key -(must be suitable as a value of -<I><A HREF="ipsec_spi.8.html">ipsec_spi</A></I>(8)'s - -<B>--enckey</B> - -option) -(may be specified separately for each direction using -<B>leftespenckey</B> - -(leftward SA) -and -<B>rightespenckey</B> - -parameters) -<DT><B>espauthkey</B> - -<DD> -ESP authentication key -(must be suitable as a value of -<I><A HREF="ipsec_spi.8.html">ipsec_spi</A></I>(8)'s - -<B>--authkey</B> - -option) -(may be specified separately for each direction using -<B>leftespauthkey</B> - -(leftward SA) -and -<B>rightespauthkey</B> - -parameters) -<DT><B>espreplay_window</B> - -<DD> -ESP replay-window setting, -an integer from -<B>0</B> - -(the -<I>ipsec_manual</I> - -default, which turns off replay protection) to -<B>64</B>; - -relevant only if ESP authentication is being used -<DT><B>leftespspi</B> - -<DD> -SPI to be used for the leftward ESP SA, overriding -automatic assignment using -<B>spi</B> - -or -<B>spibase</B>; - -typically a hexadecimal number beginning with -<B>0x</B> - -<DT><B>ah</B> - -<DD> -AH authentication algorithm to be used -for the connection, e.g. -<B>hmac-md5-96</B> - -(must be suitable as a value of -<I><A HREF="ipsec_spi.8.html">ipsec_spi</A></I>(8)'s - -<B>--ah</B> - -option); -default is not to use AH -<DT><B>ahkey</B> - -<DD> -(required if -<B>ah</B> - -is present) AH authentication key -(must be suitable as a value of -<I><A HREF="ipsec_spi.8.html">ipsec_spi</A></I>(8)'s - -<B>--authkey</B> - -option) -(may be specified separately for each direction using -<B>leftahkey</B> - -(leftward SA) -and -<B>rightahkey</B> - -parameters) -<DT><B>ahreplay_window</B> - -<DD> -AH replay-window setting, -an integer from -<B>0</B> - -(the -<I>ipsec_manual</I> - -default, which turns off replay protection) to -<B>64</B> - -<DT><B>leftahspi</B> - -<DD> -SPI to be used for the leftward AH SA, overriding -automatic assignment using -<B>spi</B> - -or -<B>spibase</B>; - -typically a hexadecimal number beginning with -<B>0x</B> - -</DL> -<A NAME="lbAH"> </A> -<H2>CONFIG SECTIONS</H2> - -At present, the only -<B>config</B> - -section known to the IPsec software is the one named -<B>setup</B>, - -which contains information used when the software is being started -(see -<I><A HREF="ipsec_setup.8.html">ipsec_setup</A></I>(8)). - -Here's an example: -<P> - - -<PRE> -<B> -config setup - interfaces="ipsec0=eth1 ipsec1=ppp0" - klipsdebug=none - plutodebug=all - manualstart= -</B></PRE> - -<P> - -Parameters are optional unless marked ``(required)''. -The currently-accepted -<I>parameter</I> - -names in a -<B>config</B> - -<B>setup</B> - -section are: -<DL COMPACT> -<DT><B>myid</B> - -<DD> -the identity to be used for -<B>%myid</B>. - -<B>%myid</B> - -is used in the implicit policy group conns and can be used as -an identity in explicit conns. -If unspecified, -<B>%myid</B> - -is set to the IP address in <B>%defaultroute</B> (if that is supported by a TXT record in its reverse domain), or otherwise -the system's hostname (if that is supported by a TXT record in its forward domain), or otherwise it is undefined. -An explicit value generally starts with ``<B>@</B>''. -<DT><B>interfaces</B> - -<DD> -virtual and physical interfaces for IPsec to use: -a single -<I>virtual</I><B>=</B><I>physical</I> pair, a (quoted!) list of pairs separated -by white space, or -<B>%none</B>. - -One of the pairs may be written as -<B>%defaultroute</B>, - -which means: find the interface <I>d</I> that the default route points to, -and then act as if the value was ``<B>ipsec0=</B><I>d</I>''. -<B>%defaultroute</B> - -is the default; -<B>%none</B> - -must be used to denote no interfaces. -If -<B>%defaultroute</B> - -is used (implicitly or explicitly) -information about the default route and its interface is noted for -use by -<I><A HREF="ipsec_manual.8.html">ipsec_manual</A></I>(8) - -and -<I><A HREF="ipsec_auto.8.html">ipsec_auto</A></I>(8).) - -<DT><B>forwardcontrol</B> - -<DD> -whether -<I>setup</I> - -should turn IP forwarding on -(if it's not already on) as IPsec is started, -and turn it off again (if it was off) as IPsec is stopped; -acceptable values are -<B>yes</B> - -and (the default) -<B>no</B>. - -For this to have full effect, forwarding must be -disabled before the hardware interfaces are brought -up (e.g., -<B>net.ipv4.ip_forward = 0</B> - -in Red Hat 6.x -<I>/etc/sysctl.conf</I>), - -because IPsec doesn't get control early enough to do that. -<DT><B>rp_filter</B> - -<DD> -whether and how -<I>setup</I> - -should adjust the reverse path filtering mechanism for the -physical devices to be used. -Values are <B>%unchanged</B> (to leave it alone) -or <B>0</B>, <B>1</B>, <B>2</B> (values to set it to). -<I>/proc/sys/net/ipv4/conf/PHYS/rp_filter</I> -is badly documented; it must be <B>0</B> in many cases -for ipsec to function. -The default value for the parameter is <B>0</B>. -<DT><B>syslog</B> - -<DD> -the -<I><A HREF="syslog.2.html">syslog</A></I>(2) - -``facility'' name and priority to use for -startup/shutdown log messages, -default -<B>daemon.error</B>. - -<DT><B>klipsdebug</B> - -<DD> -how much KLIPS debugging output should be logged. -An empty value, -or the magic value -<B>none</B>, - -means no debugging output (the default). -The magic value -<B>all</B> - -means full output. -Otherwise only the specified types of output -(a quoted list, names separated by white space) are enabled; -for details on available debugging types, see -<I><A HREF="ipsec_klipsdebug.8.html">ipsec_klipsdebug</A></I>(8). - -<DT><B>plutodebug</B> - -<DD> -how much Pluto debugging output should be logged. -An empty value, -or the magic value -<B>none</B>, - -means no debugging output (the default). -The magic value -<B>all</B> - -means full output. -Otherwise only the specified types of output -(a quoted list, names without the -<B>--debug-</B> - -prefix, -separated by white space) are enabled; -for details on available debugging types, see -<I><A HREF="ipsec_pluto.8.html">ipsec_pluto</A></I>(8). - -<DT><B>plutoopts</B> - -<DD> -additional options to pass to pluto upon startup. See -<I><A HREF="ipsec_pluto.8.html">ipsec_pluto</A></I>(8). - -<DT><B>plutostderrlog</B> - -<DD> -do not use syslog, but rather log to stderr, and direct stderr to the -argument file. -<DT><B>dumpdir</B> - -<DD> -in what directory should things started by -<I>setup</I> - -(notably the Pluto daemon) be allowed to -dump core? -The empty value (the default) means they are not -allowed to. -<DT><B>manualstart</B> - -<DD> -which manually-keyed connections to set up at startup -(empty, a name, or a quoted list of names separated by white space); -see -<I><A HREF="ipsec_manual.8.html">ipsec_manual</A></I>(8). - -Default is none. -<DT><B>pluto</B> - -<DD> -whether to start Pluto or not; -Values are -<B>yes</B> - -(the default) -or -<B>no</B> - -(useful only in special circumstances). -<DT><B>plutowait</B> - -<DD> -should Pluto wait for each -negotiation attempt that is part of startup to -finish before proceeding with the next? -Values are -<B>yes</B> - -or -<B>no</B> - -(the default). -<DT><B>prepluto</B> - -<DD> -shell command to run before starting Pluto -(e.g., to decrypt an encrypted copy of the -<I>ipsec.secrets</I> - -file). -It's run in a very simple way; -complexities like I/O redirection are best hidden within a script. -Any output is redirected for logging, -so running interactive commands is difficult unless they use -<I>/dev/tty</I> - -or equivalent for their interaction. -Default is none. -<DT><B>postpluto</B> - -<DD> -shell command to run after starting Pluto -(e.g., to remove a decrypted copy of the -<I>ipsec.secrets</I> - -file). -It's run in a very simple way; -complexities like I/O redirection are best hidden within a script. -Any output is redirected for logging, -so running interactive commands is difficult unless they use -<I>/dev/tty</I> - -or equivalent for their interaction. -Default is none. -<DT><B>fragicmp</B> - -<DD> -whether a tunnel's need to fragment a packet should be reported -back with an ICMP message, -in an attempt to make the sender lower his PMTU estimate; -acceptable values are -<B>yes</B> - -(the default) -and -<B>no</B>. - -<DT><B>hidetos</B> - -<DD> -whether a tunnel packet's TOS field should be set to -<B>0</B> - -rather than copied from the user packet inside; -acceptable values are -<B>yes</B> - -(the default) -and -<B>no</B>. - -<DT><B>uniqueids</B> - -<DD> -whether a particular participant ID should be kept unique, -with any new (automatically keyed) -connection using an ID from a different IP address -deemed to replace all old ones using that ID; -acceptable values are -<B>yes</B> - -(the default) -and -<B>no</B>. - -Participant IDs normally <I>are</I> unique, -so a new (automatically-keyed) connection using the same ID is -almost invariably intended to replace an old one. -<DT><B>overridemtu</B> - -<DD> -value that the MTU of the ipsec<I>n</I> interface(s) should be set to, -overriding IPsec's (large) default. -This parameter is needed only in special situations. -</DL> -<A NAME="lbAI"> </A> -<H2>IMPLICIT CONNS</H2> - -<P> - -The system automatically defines several conns to implement -default policy groups. Each can be overridden by explicitly -defining a new conn with the same name. If the new conn has <B>auto=ignore</B>, -the definition is suppressed. -<P> - -Here are the automatically supplied definitions. -<P> - - -<PRE> -<B> -conn clear - type=passthrough - authby=never - left=%defaultroute - right=%group - auto=route - -conn clear-or-private - type=passthrough - left=%defaultroute - leftid=%myid - right=%opportunisticgroup - failureshunt=passthrough - keyingtries=3 - ikelifetime=1h - keylife=1h - rekey=no - auto=route - -conn private-or-clear - type=tunnel - left=%defaultroute - leftid=%myid - right=%opportunisticgroup - failureshunt=passthrough - keyingtries=3 - ikelifetime=1h - keylife=1h - rekey=no - auto=route - -conn private - type=tunnel - left=%defaultroute - leftid=%myid - right=%opportunisticgroup - failureshunt=drop - keyingtries=3 - ikelifetime=1h - keylife=1h - rekey=no - auto=route - -conn block - type=reject - authby=never - left=%defaultroute - right=%group - auto=route - -# default policy -conn packetdefault - type=tunnel - left=%defaultroute - leftid=%myid - left=0.0.0.0/0 - right=%opportunistic - failureshunt=passthrough - keyingtries=3 - ikelifetime=1h - keylife=1h - rekey=no - auto=route -</B></PRE> - -<P> - -These conns are <I>not</I> affected by anything in <B>conn %default</B>. -They will only work if <B>%defaultroute</B> works. -The <B>leftid</B> will be the interfaces IP address; this -requires that reverse DNS records be set up properly. -<P> - -The implicit conns are defined after all others. It is -appropriate and reasonable to use <B>also=private-or-clear</B> -(for example) in any other opportunistic conn. -<A NAME="lbAJ"> </A> -<H2>POLICY GROUP FILES</H2> - -<P> - -The optional files under -<I>/etc/ipsec.d/policy</I>, - -including -<PRE> - -/etc/ipsec.d/policies/clear -/etc/ipsec.d/policies/clear-or-private -/etc/ipsec.d/policies/private-or-clear -/etc/ipsec.d/policies/private -/etc/ipsec.d/policies/block - -</PRE> - -may contain policy group configuration information to -supplement -<I>ipsec.conf</I>. - -Their contents are not security-sensitive. -<P> - -These files are text files. -Each consists of a list of CIDR blocks, one per line. -White space followed by # followed by anything to the end of the line -is a comment and is ignored, as are empty lines. -<P> - -A connection in -<I>/etc/ipsec.conf</I> - -which has -<B>right=%group</B> - -or -<B>right=%opportunisticgroup</B> - -is a policy group connection. -When a policy group file of the same name is loaded, with -<P> - - <B>ipsec auto --rereadgroups</B> -<P> - -or at system start, the connection is instantiated such that each -CIDR block serves as an instance's -<B>right</B> - -value. The system treats the -resulting instances as normal connections. -<P> - -For example, given a suitable connection definition -<B>private</B>, - -and the file -<I>/etc/ipsec.d/policy/private </I> - -with an entry 192.0.2.3, -the system creates a connection instance -<B>private#192.0.2.3.</B> - -This connection inherits all details from -<B>private</B>, - -except that its right client is 192.0.2.3. -<A NAME="lbAK"> </A> -<H2>DEFAULT POLICY GROUPS</H2> - -<P> - -The standard FreeS/WAN install includes several policy groups -which provide a way of classifying possible peers into IPsec security classes: -<B>private</B> - -(talk encrypted only), -<B>private-or-clear</B> - -(prefer encryption), -<B>clear-or-private</B> - -(respond to requests for encryption), -<B>clear</B> - -and -<B>block</B>. - -Implicit policy groups apply to the local host only, -and are implemented by the -<B>IMPLICIT CONNECTIONS </B> - -described above. -<A NAME="lbAL"> </A> -<H2>CHOOSING A CONNECTION</H2> - -<P> - -When choosing a connection to apply to an outbound packet caught with a -<B>%trap,</B> - -the system prefers the one with the most specific eroute that -includes the packet's source and destination IP addresses. -Source subnets are examined before destination subnets. -For initiating, only routed connections are considered. For responding, -unrouted but added connections are considered. -<P> - -When choosing a connection to use to respond to a negotiation which -doesn't match an ordinary conn, an opportunistic connection -may be instantiated. Eventually, its instance will be /32 -> /32, but -for earlier stages of the negotiation, there will not be enough -information about the client subnets to complete the instantiation. -<A NAME="lbAM"> </A> -<H2>FILES</H2> - -<PRE> -/etc/ipsec.conf -/etc/ipsec.d/policies/clear -/etc/ipsec.d/policies/clear-or-private -/etc/ipsec.d/policies/private-or-clear -/etc/ipsec.d/policies/private -/etc/ipsec.d/policies/block -</PRE> - -<A NAME="lbAN"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_ttoaddr.8.html">ipsec_ttoaddr</A>(8), <A HREF="ipsec_auto.8.html">ipsec_auto</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_rsasigkey.8.html">ipsec_rsasigkey</A>(8) -<A NAME="lbAO"> </A> -<H2>HISTORY</H2> - -Designed for the FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Henry Spencer. -<A NAME="lbAP"> </A> -<H2>BUGS</H2> - -<P> - -When -<B>type</B> - -or -<B>failureshunt</B> - -is set to -<B>drop</B> - -or -<B>reject,</B> - -FreeS/WAN blocks outbound packets using eroutes, but assumes inbound -blocking is handled by the firewall. FreeS/WAN offers firewall hooks -via an ``updown'' script. However, the default -<B>ipsec _updown</B> - -provides no help in controlling a modern firewall. -<P> - -Including attributes of the keying channel -(authentication methods, -<B>ikelifetime</B>, - -etc.) -as an attribute of a connection, -rather than of a participant pair, is dubious and incurs limitations. -<P> - -<I>Ipsec_manual</I> - -is not nearly as generous about the syntax of subnets, -addresses, etc. as the usual FreeS/WAN user interfaces. -Four-component dotted-decimal must be used for all addresses. -It -<I>is</I> - -smart enough to translate bit-count netmasks to dotted-decimal form. -<P> - -It would be good to have a line-continuation syntax, -especially for the very long lines involved in -RSA signature keys. -<P> - -The ability to specify different identities, -<B>authby</B>, - -and public keys for different automatic-keyed connections -between the same participants is misleading; -this doesn't work dependably because the identity of the participants -is not known early enough. -This is especially awkward for the ``Road Warrior'' case, -where the remote IP address is specified as -<B>0.0.0.0</B>, - -and that is considered to be the ``participant'' for such connections. -<P> - -In principle it might be necessary to control MTU on an -interface-by-interface basis, -rather than with the single global override that -<B>overridemtu</B> - -provides. -<P> - -A number of features which <I>could</I> be implemented in -both manual and automatic keying -actually are not yet implemented for manual keying. -This is unlikely to be fixed any time soon. -<P> - -If conns are to be added before DNS is available, -<B>left=</B><I>FQDN</I>, -<B>leftnextop=</B><I>FQDN</I>, -and -<B>leftrsasigkey=%dnsonload</B> - -will fail. -<I><A HREF="ipsec_pluto.8.html">ipsec_pluto</A></I>(8) - -does not actually use the public key for our side of a conn but it -isn't generally known at a add-time which side is ours (Road Warrior -and Opportunistic conns are currently exceptions). -<P> - -The <B>myid</B> option does not affect explicit <B> ipsec auto --add</B> or <B>ipsec auto --replace</B> commands for implicit conns. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">DESCRIPTION</A><DD> -<DT><A HREF="#lbAD">CONN SECTIONS</A><DD> -<DL> -<DT><A HREF="#lbAE">CONN PARAMETERS: GENERAL</A><DD> -<DT><A HREF="#lbAF">CONN PARAMETERS: AUTOMATIC KEYING</A><DD> -<DT><A HREF="#lbAG">CONN PARAMETERS: MANUAL KEYING</A><DD> -</DL> -<DT><A HREF="#lbAH">CONFIG SECTIONS</A><DD> -<DT><A HREF="#lbAI">IMPLICIT CONNS</A><DD> -<DT><A HREF="#lbAJ">POLICY GROUP FILES</A><DD> -<DT><A HREF="#lbAK">DEFAULT POLICY GROUPS</A><DD> -<DT><A HREF="#lbAL">CHOOSING A CONNECTION</A><DD> -<DT><A HREF="#lbAM">FILES</A><DD> -<DT><A HREF="#lbAN">SEE ALSO</A><DD> -<DT><A HREF="#lbAO">HISTORY</A><DD> -<DT><A HREF="#lbAP">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec.secrets.5.html b/doc/manpage.d/ipsec.secrets.5.html deleted file mode 100644 index 8abc1f492..000000000 --- a/doc/manpage.d/ipsec.secrets.5.html +++ /dev/null @@ -1,227 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC.SECRETS</TITLE> -</HEAD><BODY> -<H1>IPSEC.SECRETS</H1> -Section: File Formats (5)<BR>Updated: 28 March 1999<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec.secrets - secrets for IKE/IPsec authentication -<A NAME="lbAC"> </A> -<H2>DESCRIPTION</H2> - -The file <I>ipsec.secrets</I> holds a table of secrets. -These secrets are used by <I><A HREF="ipsec_pluto.8.html">ipsec_pluto</A></I>(8), the FreeS/WAN Internet Key -Exchange daemon, to authenticate other hosts. -Currently there are two kinds of secrets: preshared secrets and - -RSA private keys. -<P> - -It is vital that these secrets be protected. The file should be owned -by the super-user, -and its permissions should be set to block all access by others. -<P> - -The file is a sequence of entries and include directives. -Here is an example. Each entry or directive must start at the -left margin, but if it continues beyond a single line, each continuation -line must be indented. -<P> - -<DL COMPACT><DT><DD> -<PRE> -# sample /etc/ipsec.secrets file for 10.1.0.1 -10.1.0.1 10.2.0.1: PSK "secret shared by two hosts" - -# an entry may be split across lines, -# but indentation matters -<A HREF="http://www.xs4all.nl">www.xs4all.nl</A> @<A HREF="http://www.kremvax.ru">www.kremvax.ru</A> - 10.6.0.1 10.7.0.1 1.8.0.1: PSK "secret shared by 5" - -# an RSA private key. -# note that the lines are too wide for a -# man page, so ... has been substituted for -# the truncated part -@my.com: rsa { - Modulus: 0syXpo/6waam+ZhSs8Lt6jnBzu3C4grtt... - PublicExponent: 0sAw== - PrivateExponent: 0shlGbVR1m8Z+7rhzSyenCaBN... - Prime1: 0s8njV7WTxzVzRz7AP+0OraDxmEAt1BL5l... - Prime2: 0s1LgR7/oUMo9BvfU8yRFNos1s211KX5K0... - Exponent1: 0soaXj85ihM5M2inVf/NfHmtLutVz4r... - Exponent2: 0sjdAL9VFizF+BKU4ohguJFzOd55OG6... - Coefficient: 0sK1LWwgnNrNFGZsS/2GuMBg9nYVZ... - } - -include ipsec.*.secrets # get secrets from other files -</PRE> - -</DL> - -<P> - -Each entry in the file is a list of indices, followed by a secret. -The two parts are separated by a colon (<B>:</B>) that is -followed by whitespace or a newline. For compatability -with the previous form of this file, if the key part is just a -double-quoted string the colon may be left out. -<P> - -An index is an IP address, or a Fully Qualified Domain Name, <A HREF="mailto:user@FQDN">user@FQDN</A>, -<B>%any</B> or <B>%any6</B> (other kinds may come). An IP address may be written -in the familiar dotted quad form or as a domain name to be looked up -when the file is loaded -(or in any of the forms supported by the FreeS/WAN <I><A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A></I>(3) -routine). In many cases it is a bad idea to use domain names because -the name server may not be running or may be insecure. To denote a -Fully Qualified Domain Name (as opposed to an IP address denoted by -its domain name), precede the name with an at sign (<B>@</B>). -<P> - -Matching IDs with indices is fairly straightforward: they have to be -equal. In the case of a ``Road Warrior'' connection, if an equal -match is not found for the Peer's ID, and it is in the form of an IP -address, an index of <B>%any</B> will match the peer's IP address if IPV4 -and <B>%any6</B> will match a the peer's IP address if IPV6. -Currently, the obsolete notation <B>0.0.0.0</B> may be used in place of -<B>%any</B>. -<P> - -An additional complexity -arises in the case of authentication by preshared secret: the -responder will need to look up the secret before the Peer's ID payload has -been decoded, so the ID used will be the IP address. -<P> - -To authenticate a connection between two hosts, the entry that most -specifically matches the host and peer IDs is used. An entry with no -index will match any host and peer. More specifically, an entry with one index will -match a host and peer if the index matches the host's ID (the peer isn't -considered). Still more specifically, an entry with multiple indices will match a host and -peer if the host ID and peer ID each match one of the indices. If the key -is for an asymmetric authentication technique (i.e. a public key -system such as RSA), an entry with multiple indices will match a host -and peer even if only the host ID matches an index (it is presumed that the -multiple indices are all identities of the host). -It is acceptable for two entries to be the best match as -long as they agree about the secret or private key. -<P> - -Authentication by preshared secret requires that both systems find the -identical secret (the secret is not actually transmitted by the IKE -protocol). If both the host and peer appear in the index list, the -same entry will be suitable for both systems so verbatim copying -between systems can be used. This naturally extends to larger groups -sharing the same secret. Thus multiple-index entries are best for PSK -authentication. -<P> - -Authentication by RSA Signatures requires that each host have its own private -key. A host could reasonably use a different private keys -for different interfaces and for different peers. But it would not -be normal to share entries between systems. Thus thus no-index and -one-index forms of entry often make sense for RSA Signature authentication. -<P> - -The key part of an entry may start with a token indicating the kind of -key. ``RSA'' signifies RSA private key and ``PSK'' signifies -PreShared Key (case is ignored). For compatability with previous -forms of this file, PSK is the default. -<P> - -A preshared secret is most conveniently represented as a sequence of -characters, delimited by the double-quote -character (<B>"</B>). The sequence cannot contain a newline or -double-quote. Strictly speaking, the secret is actually the sequence -of bytes that is used in the file to represent the sequence of -characters (excluding the delimiters). -A preshared secret may also be represented, without quotes, in any form supported by -<I><A HREF="ipsec_ttodata.3.html">ipsec_ttodata</A></I>(3). -<P> - -An RSA private key is a composite of eight generally large numbers. The notation -used is a brace-enclosed list of field name and value pairs (see the example above). -A suitable key, in a suitable format, may be generated by <I><A HREF="ipsec_rsasigkey.8.html">ipsec_rsasigkey</A></I>(8). -The structure is very similar to that used by BIND 8.2.2 or later, but note that -the numbers must have a ``0s'' prefix if they are in base 64. The order of -the fields is fixed. -<P> - -The first token an entry must start in -the first column of its line. Subsequent tokens must be -separated by whitespace, -except for a colon token, which only needs to be followed by whitespace. -A newline is taken as whitespace, but every -line of an entry after the first must be indented. -<P> - -Whitespace at the end of a line is ignored (except in the 0t -notation for a key). At the start of line or -after whitespace, <B>#</B> and the following text up to the end of the -line is treated as a comment. Within entries, all lines must be -indented (except for lines with no tokens). -Outside entries, no line may be indented (this is to make sure that -the file layout reflects its structure). -<P> - -An include directive causes the contents of the named file to be processed -before continuing with the current file. The filename is subject to -``globbing'' as in <I><A HREF="sh.1.html">sh</A></I>(1), so every file with a matching name -is processed. Includes may be nested to a modest -depth (10, currently). If the filename doesn't start with a <B>/</B>, the -directory containing the current file is prepended to the name. The -include directive is a line that starts with the word <B>include</B>, -followed by whitespace, followed by the filename (which must not contain -whitespace). -<A NAME="lbAD"> </A> -<H2>FILES</H2> - -/etc/ipsec.secrets -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -The rest of the FreeS/WAN distribution, in particular -<I><A HREF="ipsec.conf.5.html">ipsec.conf</A></I>(5), -<I><A HREF="ipsec.8.html">ipsec</A></I>(8), -<I><A HREF="ipsec_newhostkey.8.html">ipsec_newhostkey</A></I>(8), -<I><A HREF="ipsec_rsasigkey.8.html">ipsec_rsasigkey</A></I>(8), -<I><A HREF="ipsec_showhostkey.8.html">ipsec_showhostkey</A></I>(8), -<I><A HREF="ipsec_auto.8.html">ipsec_auto</A></I>(8) <B>--rereadsecrets</B>, -and <I><A HREF="ipsec_pluto.8.html">ipsec_pluto</A></I>(8) <B>--listen</B>,. -<BR> - -BIND 8.2.2 or later, <A HREF="ftp://ftp.isc.org/isc/bind/src/">ftp://ftp.isc.org/isc/bind/src/</A> -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Designed for the FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by D. Hugh Redelmeier. -<A NAME="lbAG"> </A> -<H2>BUGS</H2> - -If an ID is <B>0.0.0.0</B>, it will match <B>%any</B>; -if it is <B>0::0</B>, it will match <B>%any6</B>. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">DESCRIPTION</A><DD> -<DT><A HREF="#lbAD">FILES</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -<DT><A HREF="#lbAG">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec__confread.8.html b/doc/manpage.d/ipsec__confread.8.html deleted file mode 100644 index ecc120c7e..000000000 --- a/doc/manpage.d/ipsec__confread.8.html +++ /dev/null @@ -1,58 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of _CONFREAD</TITLE> -</HEAD><BODY> -<H1>_CONFREAD</H1> -Section: Maintenance Commands (8)<BR>Updated: 25 Apr 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec _confread - internal routing to parse config file -<A NAME="lbAC"> </A> -<H2>DESCRIPTION</H2> - -<I>_confread </I> - -is an internal script used for parsing /etc/ipsec.conf into a canonical format. -<A NAME="lbAD"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_conf.8.html">ipsec_conf</A>(8) -<A NAME="lbAE"> </A> -<H2>HISTORY</H2> - -Man page written for the Linux FreeS/WAN project <<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael Richardson. Program written by Henry Spencer. - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">DESCRIPTION</A><DD> -<DT><A HREF="#lbAD">SEE ALSO</A><DD> -<DT><A HREF="#lbAE">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec__copyright.8.html b/doc/manpage.d/ipsec__copyright.8.html deleted file mode 100644 index 7f78b3feb..000000000 --- a/doc/manpage.d/ipsec__copyright.8.html +++ /dev/null @@ -1,62 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of _COPYRIGHT</TITLE> -</HEAD><BODY> -<H1>_COPYRIGHT</H1> -Section: Maintenance Commands (8)<BR>Updated: 25 Apr 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec _copyright - prints FreeSWAN copyright -<A NAME="lbAC"> </A> -<H2>DESCRIPTION</H2> - -<I>_copyright</I> - -outputs the FreeSWAN copyright, and version numbers for "ipsec --copyright" -<A NAME="lbAD"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8) -<A NAME="lbAE"> </A> -<H2>HISTORY</H2> - -Man page written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael Richardson. Program written by Henry Spencer. - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">DESCRIPTION</A><DD> -<DT><A HREF="#lbAD">SEE ALSO</A><DD> -<DT><A HREF="#lbAE">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec__include.8.html b/doc/manpage.d/ipsec__include.8.html deleted file mode 100644 index d85ee7852..000000000 --- a/doc/manpage.d/ipsec__include.8.html +++ /dev/null @@ -1,67 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of _INCLUDE</TITLE> -</HEAD><BODY> -<H1>_INCLUDE</H1> -Section: Maintenance Commands (8)<BR>Updated: 25 Apr 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec _include - internal script to process config files -<A NAME="lbAC"> </A> -<H2>DESCRIPTION</H2> - -<I>_include</I> - -is used by -<I>_confread </I> - -to process -<B>include </B> - -directives in /etc/ipsec.conf. -<A NAME="lbAD"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec__confread.8.html">ipsec__confread</A>(8) -<A NAME="lbAE"> </A> -<H2>HISTORY</H2> - -Man page written for the Linux FreeS/WAN project <<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael Richardson. Program written by Henry Spencer. - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">DESCRIPTION</A><DD> -<DT><A HREF="#lbAD">SEE ALSO</A><DD> -<DT><A HREF="#lbAE">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec__keycensor.8.html b/doc/manpage.d/ipsec__keycensor.8.html deleted file mode 100644 index 22e574932..000000000 --- a/doc/manpage.d/ipsec__keycensor.8.html +++ /dev/null @@ -1,64 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of _KEYCENSOR</TITLE> -</HEAD><BODY> -<H1>_KEYCENSOR</H1> -Section: Maintenance Commands (8)<BR>Updated: 25 Apr 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec _keycensor - internal routine to remove sensitive information -<A NAME="lbAC"> </A> -<H2>DESCRIPTION</H2> - -<I>_keycensor</I> - -is used by -<B>ipsec barf</B> - -to process the /etc/ipsec.secrets file, removing private key info. -<A NAME="lbAD"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_barf.8.html">ipsec_barf</A>(8) -<A NAME="lbAE"> </A> -<H2>HISTORY</H2> - -Man page written for the Linux FreeS/WAN project <<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael Richardson. Original program by Henry Spencer. - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">DESCRIPTION</A><DD> -<DT><A HREF="#lbAD">SEE ALSO</A><DD> -<DT><A HREF="#lbAE">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec__plutoload.8.html b/doc/manpage.d/ipsec__plutoload.8.html deleted file mode 100644 index 2c4968300..000000000 --- a/doc/manpage.d/ipsec__plutoload.8.html +++ /dev/null @@ -1,64 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of _PLUTOLOAD</TITLE> -</HEAD><BODY> -<H1>_PLUTOLOAD</H1> -Section: Maintenance Commands (8)<BR>Updated: 25 Apr 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec _plutoload - internal script to start pluto -<A NAME="lbAC"> </A> -<H2>DESCRIPTION</H2> - -<I>_plutoload</I> - -is called by -<B>_plutorun</B> - -to actually start the pluto executable. -<A NAME="lbAD"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_setup.8.html">ipsec_setup</A>(8), <A HREF="ipsec__realsetup.8.html">ipsec__realsetup</A>(8), <A HREF="ipsec__plutorun.8.html">ipsec__plutorun</A>(8) -<A NAME="lbAE"> </A> -<H2>HISTORY</H2> - -Man page written for the Linux FreeS/WAN project <<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael Richardson. Original program by Henry Spencer. - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">DESCRIPTION</A><DD> -<DT><A HREF="#lbAD">SEE ALSO</A><DD> -<DT><A HREF="#lbAE">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec__plutorun.8.html b/doc/manpage.d/ipsec__plutorun.8.html deleted file mode 100644 index 1b5a1da11..000000000 --- a/doc/manpage.d/ipsec__plutorun.8.html +++ /dev/null @@ -1,70 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of _PLUTORUN</TITLE> -</HEAD><BODY> -<H1>_PLUTORUN</H1> -Section: Maintenance Commands (8)<BR>Updated: 25 Apr 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec _plutorun - internal script to start pluto -<A NAME="lbAC"> </A> -<H2>DESCRIPTION</H2> - -<I>_plutorun</I> - -is called by -<B>_realsetup</B> - -to configure and bring up -<B><A HREF="ipsec_pluto.8.html">ipsec_pluto</A>(8).</B> - -It calls -<B>_plutoload</B> - -to invoke pluto, and watches to makes sure that pluto is restarted if it fails. -<A NAME="lbAD"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_setup.8.html">ipsec_setup</A>(8), <A HREF="ipsec__realsetup.8.html">ipsec__realsetup</A>(8), <A HREF="ipsec__plutoload.8.html">ipsec__plutoload</A>(8), <A HREF="ipsec_pluto.8.html">ipsec_pluto</A>(8). -<A NAME="lbAE"> </A> -<H2>HISTORY</H2> - -Man page written for the Linux FreeS/WAN project <<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael Richardson. Original program written by Henry Spencer. - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">DESCRIPTION</A><DD> -<DT><A HREF="#lbAD">SEE ALSO</A><DD> -<DT><A HREF="#lbAE">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec__realsetup.8.html b/doc/manpage.d/ipsec__realsetup.8.html deleted file mode 100644 index f45bec647..000000000 --- a/doc/manpage.d/ipsec__realsetup.8.html +++ /dev/null @@ -1,68 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of _REALSETUP</TITLE> -</HEAD><BODY> -<H1>_REALSETUP</H1> -Section: Maintenance Commands (8)<BR>Updated: 25 Apr 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec _realsetup - internal routine to start FreeS/WAN. -<A NAME="lbAC"> </A> -<H2>DESCRIPTION</H2> - -<I>_realsetup</I> - -is called by the system init scripts to start the FreeS/WAN -system. It starts -<B>KLIPS </B> - -(the kernel component) and -<B>pluto </B> - -(the userspace keying component). -<A NAME="lbAD"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec__klipsstart.8.html">ipsec__klipsstart</A>(8), <A HREF="ipsec__plutorun.8.html">ipsec__plutorun</A>(8). -<A NAME="lbAE"> </A> -<H2>HISTORY</H2> - -Man page written for the Linux FreeS/WAN project <<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael Richardson. Original program by Henry Spencer. - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">DESCRIPTION</A><DD> -<DT><A HREF="#lbAD">SEE ALSO</A><DD> -<DT><A HREF="#lbAE">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec__secretcensor.8.html b/doc/manpage.d/ipsec__secretcensor.8.html deleted file mode 100644 index 6c6ea312d..000000000 --- a/doc/manpage.d/ipsec__secretcensor.8.html +++ /dev/null @@ -1,65 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of _SECRETCENSOR</TITLE> -</HEAD><BODY> -<H1>_SECRETCENSOR</H1> -Section: Maintenance Commands (8)<BR>Updated: 25 Apr 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec _secretcensor - internal routing to sanitize files -<A NAME="lbAC"> </A> -<H2>DESCRIPTION</H2> - -<I>_secretcensor</I> - -is called by -<B>ipsec barf</B> - -to process the /etc/ipsec.secrets file to remove the private key components -from the file prior to revealing the contents. -<A NAME="lbAD"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_barf.8.html">ipsec_barf</A>(8). -<A NAME="lbAE"> </A> -<H2>HISTORY</H2> - -Man page written for the Linux FreeS/WAN project <<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael Richardson. Original program by Henry Spencer. - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">DESCRIPTION</A><DD> -<DT><A HREF="#lbAD">SEE ALSO</A><DD> -<DT><A HREF="#lbAE">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec__startklips.8.html b/doc/manpage.d/ipsec__startklips.8.html deleted file mode 100644 index 3ad565e57..000000000 --- a/doc/manpage.d/ipsec__startklips.8.html +++ /dev/null @@ -1,63 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of _STARTKLIPS</TITLE> -</HEAD><BODY> -<H1>_STARTKLIPS</H1> -Section: Maintenance Commands (8)<BR>Updated: 25 Apr 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec _startklips - internal script to bring up kernel components -<A NAME="lbAC"> </A> -<H2>DESCRIPTION</H2> - -<I>_startklips</I> - -brings up the FreeS/WAN kernel component. This involves loading any -required modules, attaching and configuring the ipsecX pseudo-devices and -attaching the pseudo-devices to the physical devices. -<A NAME="lbAD"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A>(8). -<A NAME="lbAE"> </A> -<H2>HISTORY</H2> - -Man page written for the Linux FreeS/WAN project <<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael Richardson. Original program by Henry Spencer. - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">DESCRIPTION</A><DD> -<DT><A HREF="#lbAD">SEE ALSO</A><DD> -<DT><A HREF="#lbAE">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec__updown.8.html b/doc/manpage.d/ipsec__updown.8.html deleted file mode 100644 index 73bf8a343..000000000 --- a/doc/manpage.d/ipsec__updown.8.html +++ /dev/null @@ -1,63 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of _UPDOWN</TITLE> -</HEAD><BODY> -<H1>_UPDOWN</H1> -Section: Maintenance Commands (8)<BR>Updated: 25 Apr 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec _updown - klips manipulation script -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<I>_updown</I> - -is invoked by pluto when it has brought up a new connection. This script -is used to insert the appropriate routing entries for IPsec operation. -The interface to the script is documented in the pluto man page. -<A NAME="lbAD"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_pluto.8.html">ipsec_pluto</A>(8). -<A NAME="lbAE"> </A> -<H2>HISTORY</H2> - -Man page written for the Linux FreeS/WAN project <<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael Richardson. Original program written by Henry Spencer. - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">SEE ALSO</A><DD> -<DT><A HREF="#lbAE">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_addrbytesof.3.html b/doc/manpage.d/ipsec_addrbytesof.3.html deleted file mode 100644 index ca1f857e7..000000000 --- a/doc/manpage.d/ipsec_addrbytesof.3.html +++ /dev/null @@ -1,232 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_INITADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_INITADDR</H1> -Section: C Library Functions (3)<BR>Updated: 11 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec initaddr - initialize an ip_address -<BR> - -ipsec addrtypeof - get address type of an ip_address -<BR> - -ipsec addrlenof - get length of address within an ip_address -<BR> - -ipsec addrbytesof - get copy of address within an ip_address -<BR> - -ipsec addrbytesptr - get pointer to address within an ip_address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *initaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *dst);</B> - -<BR> - -<B>int addrtypeof(const ip_address *src);</B> - -<BR> - -<B>size_t addrlenof(const ip_address *src);</B> - -<BR> - -<B>size_t addrbytesof(const ip_address *src,</B> - -<BR> - -<B>unsigned char *dst, size_t dstlen);</B> - -<BR> - -<B>size_t addrbytesptr(const ip_address *src,</B> - -<BR> - -<B>const unsigned char **dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -library uses an internal type -<I>ip_address</I> - -to contain one of the (currently two) types of IP address. -These functions provide basic tools for creating and examining this type. -<P> - -<I>Initaddr</I> - -initializes a variable -<I>*dst</I> - -of type -<I>ip_address</I> - -from an address -(in network byte order, -indicated by a pointer -<I>src</I> - -and a length -<I>srclen</I>) - -and an address family -<I>af</I> - -(typically -<B>AF_INET</B> - -or -<B>AF_INET6</B>). - -The length must be consistent with the address family. -<P> - -<I>Addrtypeof</I> - -returns the address type of an address, -normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -(The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file arranges to include the necessary headers for these -names to be known.) -<P> - -<I>Addrlenof</I> - -returns the size (in bytes) of the address within an -<I>ip_address</I>, - -to permit storage allocation etc. -<P> - -<I>Addrbytesof</I> - -copies the address within the -<I>ip_address</I> - -<I>src</I> - -to the buffer indicated by the pointer -<I>dst</I> - -and the length -<I>dstlen</I>, - -and returns the address length (in bytes). -If the address will not fit, -as many bytes as will fit are copied; -the returned length is still the full length. -It is the caller's responsibility to check the -returned value to ensure that there was enough room. -<P> - -<I>Addrbytesptr</I> - -sets -<I>*dst</I> - -to a pointer to the internal address within the -<I>ip_address</I>, - -and returns the address length (in bytes). -If -<I>dst</I> - -is -<B>NULL</B>, - -it just returns the address length. -The pointer points to -<B>const</B> - -to discourage misuse. -<P> - -<I>Initaddr</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<P> - -The functions which return -<I>size_t</I> - -return -<B>0</B> - -for a failure. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -An unknown address family is a fatal error for any of these functions -except -<I>addrtypeof</I>. - -An address-size mismatch is a fatal error for -<I>initaddr</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -<I>Addrtypeof</I> - -should probably have been named -<I>addrfamilyof</I>. - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_addrbytesptr.3.html b/doc/manpage.d/ipsec_addrbytesptr.3.html deleted file mode 100644 index ca1f857e7..000000000 --- a/doc/manpage.d/ipsec_addrbytesptr.3.html +++ /dev/null @@ -1,232 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_INITADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_INITADDR</H1> -Section: C Library Functions (3)<BR>Updated: 11 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec initaddr - initialize an ip_address -<BR> - -ipsec addrtypeof - get address type of an ip_address -<BR> - -ipsec addrlenof - get length of address within an ip_address -<BR> - -ipsec addrbytesof - get copy of address within an ip_address -<BR> - -ipsec addrbytesptr - get pointer to address within an ip_address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *initaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *dst);</B> - -<BR> - -<B>int addrtypeof(const ip_address *src);</B> - -<BR> - -<B>size_t addrlenof(const ip_address *src);</B> - -<BR> - -<B>size_t addrbytesof(const ip_address *src,</B> - -<BR> - -<B>unsigned char *dst, size_t dstlen);</B> - -<BR> - -<B>size_t addrbytesptr(const ip_address *src,</B> - -<BR> - -<B>const unsigned char **dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -library uses an internal type -<I>ip_address</I> - -to contain one of the (currently two) types of IP address. -These functions provide basic tools for creating and examining this type. -<P> - -<I>Initaddr</I> - -initializes a variable -<I>*dst</I> - -of type -<I>ip_address</I> - -from an address -(in network byte order, -indicated by a pointer -<I>src</I> - -and a length -<I>srclen</I>) - -and an address family -<I>af</I> - -(typically -<B>AF_INET</B> - -or -<B>AF_INET6</B>). - -The length must be consistent with the address family. -<P> - -<I>Addrtypeof</I> - -returns the address type of an address, -normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -(The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file arranges to include the necessary headers for these -names to be known.) -<P> - -<I>Addrlenof</I> - -returns the size (in bytes) of the address within an -<I>ip_address</I>, - -to permit storage allocation etc. -<P> - -<I>Addrbytesof</I> - -copies the address within the -<I>ip_address</I> - -<I>src</I> - -to the buffer indicated by the pointer -<I>dst</I> - -and the length -<I>dstlen</I>, - -and returns the address length (in bytes). -If the address will not fit, -as many bytes as will fit are copied; -the returned length is still the full length. -It is the caller's responsibility to check the -returned value to ensure that there was enough room. -<P> - -<I>Addrbytesptr</I> - -sets -<I>*dst</I> - -to a pointer to the internal address within the -<I>ip_address</I>, - -and returns the address length (in bytes). -If -<I>dst</I> - -is -<B>NULL</B>, - -it just returns the address length. -The pointer points to -<B>const</B> - -to discourage misuse. -<P> - -<I>Initaddr</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<P> - -The functions which return -<I>size_t</I> - -return -<B>0</B> - -for a failure. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -An unknown address family is a fatal error for any of these functions -except -<I>addrtypeof</I>. - -An address-size mismatch is a fatal error for -<I>initaddr</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -<I>Addrtypeof</I> - -should probably have been named -<I>addrfamilyof</I>. - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_addrcmp.3.html b/doc/manpage.d/ipsec_addrcmp.3.html deleted file mode 100644 index 93ac522cd..000000000 --- a/doc/manpage.d/ipsec_addrcmp.3.html +++ /dev/null @@ -1,274 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Nov 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec sameaddr - are two addresses the same? -<BR> - -ipsec addrcmp - ordered comparison of addresses -<BR> - -ipsec samesubnet - are two subnets the same? -<BR> - -ipsec addrinsubnet - is an address within a subnet? -<BR> - -ipsec subnetinsubnet - is a subnet within another subnet? -<BR> - -ipsec subnetishost - is a subnet a single host? -<BR> - -ipsec samesaid - are two SA IDs the same? -<BR> - -ipsec sameaddrtype - are two addresses of the same address family? -<BR> - -ipsec samesubnettype - are two subnets of the same address family? -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int sameaddr(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int addrcmp(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int addrinsubnet(const ip_address *a, const ip_subnet *s);</B> - -<BR> - -<B>int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int subnetishost(const ip_subnet *s);</B> - -<BR> - -<B>int samesaid(const ip_said *a, const ip_said *b);</B> - -<BR> - -<B>int sameaddrtype(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnettype(const ip_subnet *a, const ip_subnet *b);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions do various comparisons and tests on the -<I>ip_address</I> - -type and -<I>ip_subnet</I> - -types. -<P> - -<I>Sameaddr</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Addresses of different families are never identical. -<P> - -<I>Addrcmp</I> - -returns -<B>-1</B>, - -<B>0</B>, - -or -<B>1</B> - -respectively -if address -<I>a</I> - -is less than, equal to, or greater than -<I>b</I>. - -If they are not of the same address family, -they are never equal; -the ordering reported in this case is arbitrary -(and probably not useful) but consistent. -<P> - -<I>Samesubnet</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Subnets of different address families are never identical. -<P> - -<I>Addrinsubnet</I> - -returns -non-zero -if address -<I>a</I> - -is within subnet -<I>s</I> - -and -<B>0</B> - -otherwise. -An address is never within a -subnet of a different address family. -<P> - -<I>Subnetinsubnet</I> - -returns -non-zero -if subnet -<I>a</I> - -is a subset of subnet -<I>b</I> - -and -<B>0</B> - -otherwise. -A subnet is deemed to be a subset of itself. -A subnet is never a subset of another -subnet if their address families differ. -<P> - -<I>Subnetishost</I> - -returns -non-zero -if subnet -<I>s</I> - -is in fact only a single host, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesaid</I> - -returns -non-zero -if SA IDs -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -<P> - -<I>Sameaddrtype</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesubnettype</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_initaddr.3.html">ipsec_initaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_addrinsubnet.3.html b/doc/manpage.d/ipsec_addrinsubnet.3.html deleted file mode 100644 index 93ac522cd..000000000 --- a/doc/manpage.d/ipsec_addrinsubnet.3.html +++ /dev/null @@ -1,274 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Nov 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec sameaddr - are two addresses the same? -<BR> - -ipsec addrcmp - ordered comparison of addresses -<BR> - -ipsec samesubnet - are two subnets the same? -<BR> - -ipsec addrinsubnet - is an address within a subnet? -<BR> - -ipsec subnetinsubnet - is a subnet within another subnet? -<BR> - -ipsec subnetishost - is a subnet a single host? -<BR> - -ipsec samesaid - are two SA IDs the same? -<BR> - -ipsec sameaddrtype - are two addresses of the same address family? -<BR> - -ipsec samesubnettype - are two subnets of the same address family? -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int sameaddr(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int addrcmp(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int addrinsubnet(const ip_address *a, const ip_subnet *s);</B> - -<BR> - -<B>int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int subnetishost(const ip_subnet *s);</B> - -<BR> - -<B>int samesaid(const ip_said *a, const ip_said *b);</B> - -<BR> - -<B>int sameaddrtype(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnettype(const ip_subnet *a, const ip_subnet *b);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions do various comparisons and tests on the -<I>ip_address</I> - -type and -<I>ip_subnet</I> - -types. -<P> - -<I>Sameaddr</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Addresses of different families are never identical. -<P> - -<I>Addrcmp</I> - -returns -<B>-1</B>, - -<B>0</B>, - -or -<B>1</B> - -respectively -if address -<I>a</I> - -is less than, equal to, or greater than -<I>b</I>. - -If they are not of the same address family, -they are never equal; -the ordering reported in this case is arbitrary -(and probably not useful) but consistent. -<P> - -<I>Samesubnet</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Subnets of different address families are never identical. -<P> - -<I>Addrinsubnet</I> - -returns -non-zero -if address -<I>a</I> - -is within subnet -<I>s</I> - -and -<B>0</B> - -otherwise. -An address is never within a -subnet of a different address family. -<P> - -<I>Subnetinsubnet</I> - -returns -non-zero -if subnet -<I>a</I> - -is a subset of subnet -<I>b</I> - -and -<B>0</B> - -otherwise. -A subnet is deemed to be a subset of itself. -A subnet is never a subset of another -subnet if their address families differ. -<P> - -<I>Subnetishost</I> - -returns -non-zero -if subnet -<I>s</I> - -is in fact only a single host, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesaid</I> - -returns -non-zero -if SA IDs -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -<P> - -<I>Sameaddrtype</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesubnettype</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_initaddr.3.html">ipsec_initaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_addrlenof.3.html b/doc/manpage.d/ipsec_addrlenof.3.html deleted file mode 100644 index ca1f857e7..000000000 --- a/doc/manpage.d/ipsec_addrlenof.3.html +++ /dev/null @@ -1,232 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_INITADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_INITADDR</H1> -Section: C Library Functions (3)<BR>Updated: 11 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec initaddr - initialize an ip_address -<BR> - -ipsec addrtypeof - get address type of an ip_address -<BR> - -ipsec addrlenof - get length of address within an ip_address -<BR> - -ipsec addrbytesof - get copy of address within an ip_address -<BR> - -ipsec addrbytesptr - get pointer to address within an ip_address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *initaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *dst);</B> - -<BR> - -<B>int addrtypeof(const ip_address *src);</B> - -<BR> - -<B>size_t addrlenof(const ip_address *src);</B> - -<BR> - -<B>size_t addrbytesof(const ip_address *src,</B> - -<BR> - -<B>unsigned char *dst, size_t dstlen);</B> - -<BR> - -<B>size_t addrbytesptr(const ip_address *src,</B> - -<BR> - -<B>const unsigned char **dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -library uses an internal type -<I>ip_address</I> - -to contain one of the (currently two) types of IP address. -These functions provide basic tools for creating and examining this type. -<P> - -<I>Initaddr</I> - -initializes a variable -<I>*dst</I> - -of type -<I>ip_address</I> - -from an address -(in network byte order, -indicated by a pointer -<I>src</I> - -and a length -<I>srclen</I>) - -and an address family -<I>af</I> - -(typically -<B>AF_INET</B> - -or -<B>AF_INET6</B>). - -The length must be consistent with the address family. -<P> - -<I>Addrtypeof</I> - -returns the address type of an address, -normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -(The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file arranges to include the necessary headers for these -names to be known.) -<P> - -<I>Addrlenof</I> - -returns the size (in bytes) of the address within an -<I>ip_address</I>, - -to permit storage allocation etc. -<P> - -<I>Addrbytesof</I> - -copies the address within the -<I>ip_address</I> - -<I>src</I> - -to the buffer indicated by the pointer -<I>dst</I> - -and the length -<I>dstlen</I>, - -and returns the address length (in bytes). -If the address will not fit, -as many bytes as will fit are copied; -the returned length is still the full length. -It is the caller's responsibility to check the -returned value to ensure that there was enough room. -<P> - -<I>Addrbytesptr</I> - -sets -<I>*dst</I> - -to a pointer to the internal address within the -<I>ip_address</I>, - -and returns the address length (in bytes). -If -<I>dst</I> - -is -<B>NULL</B>, - -it just returns the address length. -The pointer points to -<B>const</B> - -to discourage misuse. -<P> - -<I>Initaddr</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<P> - -The functions which return -<I>size_t</I> - -return -<B>0</B> - -for a failure. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -An unknown address family is a fatal error for any of these functions -except -<I>addrtypeof</I>. - -An address-size mismatch is a fatal error for -<I>initaddr</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -<I>Addrtypeof</I> - -should probably have been named -<I>addrfamilyof</I>. - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_addrtoa.3.html b/doc/manpage.d/ipsec_addrtoa.3.html deleted file mode 100644 index 8f0d765e5..000000000 --- a/doc/manpage.d/ipsec_addrtoa.3.html +++ /dev/null @@ -1,448 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ATOADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ATOADDR</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec atoaddr, addrtoa - convert Internet addresses to and from ASCII -<BR> - -ipsec atosubnet, subnettoa - convert subnet/mask ASCII form to and from addresses -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *atoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>struct in_addr *addr);</B> - -<BR> - -<B>size_t addrtoa(struct in_addr addr, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<P> -<B>const char *atosubnet(const char *src, size_t srclen,</B> - -<BR> - -<B>struct in_addr *addr, struct in_addr *mask);</B> - -<BR> - -<B>size_t subnettoa(struct in_addr addr, struct in_addr mask,</B> - -<BR> - -<B>int format, char *dst, size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; see -<I><A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A></I>(3) - -for their replacements. -<P> - -<I>Atoaddr</I> - -converts an ASCII name or dotted-decimal address into a binary address -(in network byte order). -<I>Addrtoa</I> - -does the reverse conversion, back to an ASCII dotted-decimal address. -<I>Atosubnet</I> - -and -<I>subnettoa</I> - -do likewise for the ``address/mask'' ASCII form used to write a -specification of a subnet. -<P> - -An address is specified in ASCII as a -dotted-decimal address (e.g. -<B>1.2.3.4</B>), - -an eight-digit network-order hexadecimal number with the usual C prefix (e.g. -<B>0x01020304</B>, - -which is synonymous with -<B>1.2.3.4</B>), - -an eight-digit host-order hexadecimal number with a -<B>0h</B> - -prefix (e.g. -<B>0h01020304</B>, - -which is synonymous with -<B>1.2.3.4</B> - -on a big-endian host and -<B>4.3.2.1</B> - -on a little-endian host), -a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3), - -or an old-style network name to be looked up via -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3). - -<P> - -A dotted-decimal address may be incomplete, in which case -ASCII-to-binary conversion implicitly appends -as many instances of -<B>.0</B> - -as necessary to bring it up to four components. -The components of a dotted-decimal address are always taken as -decimal, and leading zeros are ignored. -For example, -<B>10</B> - -is synonymous with -<B>10.0.0.0</B>, - -and -<B>128.009.000.032</B> - -is synonymous with -<B>128.9.0.32</B> - -(the latter example is verbatim from RFC 1166). -The result of -<I>addrtoa</I> - -is always complete and does not contain leading zeros. -<P> - -The letters in -a hexadecimal address may be uppercase or lowercase or any mixture thereof. -Use of hexadecimal addresses is -<B>strongly</B> - -<B>discouraged</B>; - -they are included only to save hassles when dealing with -the handful of perverted programs which already print -network addresses in hexadecimal. -<P> - -DNS names may be complete (optionally terminated with a ``.'') -or incomplete, and are looked up as specified by local system configuration -(see -<I><A HREF="resolver.5.html">resolver</A></I>(5)). - -The -<I>h_addr</I> - -value returned by -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3) - -is used, -so with current DNS implementations, -the result when the name corresponds to more than one address is -difficult to predict. -Name lookup resorts to -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3) - -only if -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3) - -fails. -<P> - -A subnet specification is of the form <I>network</I><B>/</B><I>mask</I>. -The -<I>network</I> - -and -<I>mask</I> - -can be any form acceptable to -<I>atoaddr</I>. - -In addition, the -<I>mask</I> - -can be a decimal integer (leading zeros ignored) giving a bit count, -in which case -it stands for a mask with that number of high bits on and all others off -(e.g., -<B>24</B> - -means -<B>255.255.255.0</B>). - -In any case, the mask must be contiguous -(a sequence of high bits on and all remaining low bits off). -As a special case, the subnet specification -<B>%default</B> - -is a synonym for -<B>0.0.0.0/0</B>. - -<P> - -<I>Atosubnet</I> - -ANDs the mask with the address before returning, -so that any non-network bits in the address are turned off -(e.g., -<B>10.1.2.3/24</B> - -is synonymous with -<B>10.1.2.0/24</B>). - -<I>Subnettoa</I> - -generates the decimal-integer-bit-count -form of the mask, -with no leading zeros, -unless the mask is non-contiguous. -<P> - -The -<I>srclen</I> - -parameter of -<I>atoaddr</I> - -and -<I>atosubnet</I> - -specifies the length of the ASCII string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>addrtoa</I> - -and -<I>subnettoa</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines constants, -<B>ADDRTOA_BUF</B> - -and -<B>SUBNETTOA_BUF</B>, - -which are the sizes of buffers just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>addrtoa</I> - -and -<I>subnettoa</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the ASCII character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default, -and is in fact the only format currently available. -This parameter is a hedge against future needs. -<P> - -The ASCII-to-binary functions return NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -The binary-to-ASCII functions return -<B>0</B> - -for a failure, and otherwise -always return the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>atoaddr</I> - -are: -empty input; -attempt to allocate temporary storage for a very long name failed; -name lookup failed; -syntax error in dotted-decimal form; -dotted-decimal component too large to fit in 8 bits. -<P> - -Fatal errors in -<I>atosubnet</I> - -are: -no -<B>/</B> - -in -<I>src</I>; - -<I>atoaddr</I> - -error in conversion of -<I>network</I> - -or -<I>mask</I>; - -bit-count mask too big; -mask non-contiguous. -<P> - -Fatal errors in -<I>addrtoa</I> - -and -<I>subnettoa</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The interpretation of incomplete dotted-decimal addresses -(e.g. -<B>10/24</B> - -means -<B>10.0.0.0/24</B>) - -differs from that of some older conversion -functions, e.g. those of -<I><A HREF="inet.3.html">inet</A></I>(3). - -The behavior of the older functions has never been -particularly consistent or particularly useful. -<P> - -Ignoring leading zeros in dotted-decimal components and bit counts -is arguably the most useful behavior in this application, -but it might occasionally cause confusion with the historical use of leading -zeros to denote octal numbers. -<P> - -It is barely possible that somebody, somewhere, -might have a legitimate use for non-contiguous subnet masks. -<P> - -<I><A HREF="Getnetbyname.3.html">Getnetbyname</A></I>(3) - -is a historical dreg. -<P> - -The restriction of ASCII-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The ASCII-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = atoaddr( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_addrtosubnet.3.html b/doc/manpage.d/ipsec_addrtosubnet.3.html deleted file mode 100644 index e442a9100..000000000 --- a/doc/manpage.d/ipsec_addrtosubnet.3.html +++ /dev/null @@ -1,238 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_INITSUBNET</TITLE> -</HEAD><BODY> -<H1>IPSEC_INITSUBNET</H1> -Section: C Library Functions (3)<BR>Updated: 12 March 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec initsubnet - initialize an ip_subnet -<BR> - -ipsec addrtosubnet - initialize a singleton ip_subnet -<BR> - -ipsec subnettypeof - get address type of an ip_subnet -<BR> - -ipsec masktocount - convert subnet mask to bit count -<BR> - -ipsec networkof - get base address of an ip_subnet -<BR> - -ipsec maskof - get subnet mask of an ip_subnet -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *initsubnet(const ip_address *addr,</B> - -<BR> - -<B>int maskbits, int clash, ip_subnet *dst);</B> - -<BR> - -<B>const char *addrtosubnet(const ip_address *addr,</B> - -<BR> - -<B>ip_subnet *dst);</B> - -<P> -<B>int subnettypeof(const ip_subnet *src);</B> - -<BR> - -<B>int masktocount(const ip_address *src);</B> - -<BR> - -<B>void networkof(const ip_subnet *src, ip_address *dst);</B> - -<BR> - -<B>void maskof(const ip_subnet *src, ip_address *dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -library uses an internal type -<I>ip_subnet</I> - -to contain a description of an IP subnet -(base address plus mask). -These functions provide basic tools for creating and examining this type. -<P> - -<I>Initsubnet</I> - -initializes a variable -<I>*dst</I> - -of type -<I>ip_subnet</I> - -from a base address and -a count of mask bits. -The -<I>clash</I> - -parameter specifies what to do if the base address includes -<B>1</B> - -bits outside the prefix specified by the mask -(that is, in the ``host number'' part of the address): -<DL COMPACT><DT><DD> -<DL COMPACT> -<DT>'0'<DD> -zero out host-number bits -<DT>'x'<DD> -non-zero host-number bits are an error -</DL> -</DL> - -<P> - -<I>Initsubnet</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<P> - -<I>Addrtosubnet</I> - -initializes an -<I>ip_subnet</I> - -variable -<I>*dst</I> - -to a ``singleton subnet'' containing the single address -<I>*addr</I>. - -It returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure. -<P> - -<I>Subnettypeof</I> - -returns the address type of a subnet, -normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -(The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file arranges to include the necessary headers for these -names to be known.) -<P> - -<I>Masktocount</I> - -converts a subnet mask, expressed as an address, to a bit count -suitable for use with -<I>initsubnet</I>. - -It returns -<B>-1</B> - -for error; see DIAGNOSTICS. -<P> - -<I>Networkof</I> - -fills in -<I>*dst</I> - -with the base address of subnet -<I>src</I>. - -<P> - -<I>Maskof</I> - -fills in -<I>*dst</I> - -with the subnet mask of subnet -<I>src</I>, - -expressed as an address. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_ttosubnet.3.html">ipsec_ttosubnet</A>(3), <A HREF="ipsec_rangetosubnet.3.html">ipsec_rangetosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>initsubnet</I> - -are: -unknown address family; -unknown -<I>clash</I> - -value; -impossible mask bit count; -non-zero host-number bits and -<I>clash</I> - -is -<B>'x'</B>. - -Fatal errors in -<I>addrtosubnet</I> - -are: -unknown address family. -Fatal errors in -<I>masktocount</I> - -are: -unknown address family; -mask bits not contiguous. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_addrtot.3.html b/doc/manpage.d/ipsec_addrtot.3.html deleted file mode 100644 index eccb946e6..000000000 --- a/doc/manpage.d/ipsec_addrtot.3.html +++ /dev/null @@ -1,569 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TTOADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_TTOADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Sept 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ttoaddr, tnatoaddr, addrtot - convert Internet addresses to and from text -<BR> - -ipsec ttosubnet, subnettot - convert subnet/mask text form to and from addresses -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *ttoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *addr);</B> - -<BR> - -<B>const char *tnatoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *addr);</B> - -<BR> - -<B>size_t addrtot(const ip_address *addr, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<P> -<B>const char *ttosubnet(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_subnet *dst);</B> - -<BR> - -<B>size_t subnettot(const ip_subnet *sub, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ttoaddr</I> - -converts a text-string name or numeric address into a binary address -(in network byte order). -<I>Tnatoaddr</I> - -does the same conversion, -but the only text forms it accepts are -the ``official'' forms of -numeric address (dotted-decimal for IPv4, colon-hex for IPv6). -<I>Addrtot</I> - -does the reverse conversion, from binary address back to a text form. -<I>Ttosubnet</I> - -and -<I>subnettot</I> - -do likewise for the ``address/mask'' form used to write a -specification of a subnet. -<P> - -An IPv4 address is specified in text as a -dotted-decimal address (e.g. -<B>1.2.3.4</B>), - -an eight-digit network-order hexadecimal number with the usual C prefix (e.g. -<B>0x01020304</B>, - -which is synonymous with -<B>1.2.3.4</B>), - -an eight-digit host-order hexadecimal number with a -<B>0h</B> - -prefix (e.g. -<B>0h01020304</B>, - -which is synonymous with -<B>1.2.3.4</B> - -on a big-endian host and -<B>4.3.2.1</B> - -on a little-endian host), -a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3), - -or an old-style network name to be looked up via -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3). - -<P> - -A dotted-decimal address may be incomplete, in which case -text-to-binary conversion implicitly appends -as many instances of -<B>.0</B> - -as necessary to bring it up to four components. -The components of a dotted-decimal address are always taken as -decimal, and leading zeros are ignored. -For example, -<B>10</B> - -is synonymous with -<B>10.0.0.0</B>, - -and -<B>128.009.000.032</B> - -is synonymous with -<B>128.9.0.32</B> - -(the latter example is verbatim from RFC 1166). -The result of applying -<I>addrtot</I> - -to an IPv4 address is always complete and does not contain leading zeros. -<P> - -Use of hexadecimal addresses is -<B>strongly</B> - -<B>discouraged</B>; - -they are included only to save hassles when dealing with -the handful of perverted programs which already print -network addresses in hexadecimal. -<P> - -An IPv6 address is specified in text with -colon-hex notation (e.g. -<B>0:56:78ab:22:33:44:55:66</B>), - -colon-hex with -<B>::</B> - -abbreviating at most one subsequence of multiple zeros (e.g. -<B>99:ab::54:068</B>, - -which is synonymous with -<B>99:ab:0:0:0:0:54:68</B>), - -or a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3). - -The result of applying -<I>addrtot</I> - -to an IPv6 address will use -<B>::</B> - -abbreviation if possible, -and will not contain leading zeros. -<P> - -The letters in hexadecimal -may be uppercase or lowercase or any mixture thereof. -<P> - -DNS names may be complete (optionally terminated with a ``.'') -or incomplete, and are looked up as specified by local system configuration -(see -<I><A HREF="resolver.5.html">resolver</A></I>(5)). - -The -<I>h_addr</I> - -value returned by -<I><A HREF="gethostbyname2.3.html">gethostbyname2</A></I>(3) - -is used, -so with current DNS implementations, -the result when the name corresponds to more than one address is -difficult to predict. -IPv4 name lookup resorts to -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3) - -only if -<I><A HREF="gethostbyname2.3.html">gethostbyname2</A></I>(3) - -fails. -<P> - -A subnet specification is of the form <I>network</I><B>/</B><I>mask</I>. -The -<I>network</I> - -and -<I>mask</I> - -can be any form acceptable to -<I>ttoaddr</I>. - -In addition, and preferably, the -<I>mask</I> - -can be a decimal integer (leading zeros ignored) giving a bit count, -in which case -it stands for a mask with that number of high bits on and all others off -(e.g., -<B>24</B> - -in IPv4 means -<B>255.255.255.0</B>). - -In any case, the mask must be contiguous -(a sequence of high bits on and all remaining low bits off). -As a special case, the subnet specification -<B>%default</B> - -is a synonym for -<B>0.0.0.0/0</B> - -or -<B>::/0</B> - -in IPv4 or IPv6 respectively. -<P> - -<I>Ttosubnet</I> - -ANDs the mask with the address before returning, -so that any non-network bits in the address are turned off -(e.g., -<B>10.1.2.3/24</B> - -is synonymous with -<B>10.1.2.0/24</B>). - -<I>Subnettot</I> - -always generates the decimal-integer-bit-count -form of the mask, -with no leading zeros. -<P> - -The -<I>srclen</I> - -parameter of -<I>ttoaddr</I> - -and -<I>ttosubnet</I> - -specifies the length of the text string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>af</I> - -parameter of -<I>ttoaddr</I> - -and -<I>ttosubnet</I> - -specifies the address family of interest. -It should be either -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>addrtot</I> - -and -<I>subnettot</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines constants, -<B>ADDRTOT_BUF</B> - -and -<B>SUBNETTOT_BUF</B>, - -which are the sizes of buffers just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>addrtot</I> - -and -<I>subnettot</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default, -and is in fact the only format currently available in -<I>subnettot</I>. - -<I>Addrtot</I> - -also accepts format values -<B>'r'</B> - -(signifying a text form suitable for DNS reverse lookups, -e.g. -<B>4.3.2.1.IN-ADDR.ARPA.</B> - -for IPv4 and -RFC 2874 format for IPv6), -and -<B>'R'</B> - -(signifying an alternate reverse-lookup form, -an error for IPv4 and RFC 1886 format for IPv6). -Reverse-lookup names always end with a ``.''. -<P> - -The text-to-binary functions return NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -The binary-to-text functions return -<B>0</B> - -for a failure, and otherwise -always return the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>ttoaddr</I> - -are: -empty input; -unknown address family; -attempt to allocate temporary storage for a very long name failed; -name lookup failed; -syntax error in dotted-decimal or colon-hex form; -dotted-decimal or colon-hex component too large. -<P> - -Fatal errors in -<I>ttosubnet</I> - -are: -no -<B>/</B> - -in -<I>src</I>; - -<I>ttoaddr</I> - -error in conversion of -<I>network</I> - -or -<I>mask</I>; - -bit-count mask too big; -mask non-contiguous. -<P> - -Fatal errors in -<I>addrtot</I> - -and -<I>subnettot</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The interpretation of incomplete dotted-decimal addresses -(e.g. -<B>10/24</B> - -means -<B>10.0.0.0/24</B>) - -differs from that of some older conversion -functions, e.g. those of -<I><A HREF="inet.3.html">inet</A></I>(3). - -The behavior of the older functions has never been -particularly consistent or particularly useful. -<P> - -Ignoring leading zeros in dotted-decimal components and bit counts -is arguably the most useful behavior in this application, -but it might occasionally cause confusion with the historical use of leading -zeros to denote octal numbers. -<P> - -<I>Ttoaddr</I> - -does not support the mixed colon-hex-dotted-decimal -convention used to embed an IPv4 address in an IPv6 address. -<P> - -<I>Addrtot</I> - -always uses the -<B>::</B> - -abbreviation (which can appear only once in an address) for the -<I>first</I> - -sequence of multiple zeros in an IPv6 address. -One can construct addresses (unlikely ones) in which this is suboptimal. -<P> - -<I>Addrtot</I> - -<B>'r'</B> - -conversion of an IPv6 address uses lowercase hexadecimal, -not the uppercase used in RFC 2874's examples. -It takes careful reading of RFCs 2874, 2673, and 2234 to realize -that lowercase is technically legitimate here, -and there may be software which botches this -and hence would have trouble with lowercase hex. -<P> - -Possibly -<I>subnettot</I> - -ought to recognize the -<B>%default</B> - -case and generate that string as its output. -Currently it doesn't. -<P> - -It is barely possible that somebody, somewhere, -might have a legitimate use for non-contiguous subnet masks. -<P> - -<I><A HREF="Getnetbyname.3.html">Getnetbyname</A></I>(3) - -is a historical dreg. -<P> - -<I>Tnatoaddr</I> - -probably should enforce completeness of dotted-decimal addresses. -<P> - -The restriction of text-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The text-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = ttoaddr( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_addrtypeof.3.html b/doc/manpage.d/ipsec_addrtypeof.3.html deleted file mode 100644 index ca1f857e7..000000000 --- a/doc/manpage.d/ipsec_addrtypeof.3.html +++ /dev/null @@ -1,232 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_INITADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_INITADDR</H1> -Section: C Library Functions (3)<BR>Updated: 11 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec initaddr - initialize an ip_address -<BR> - -ipsec addrtypeof - get address type of an ip_address -<BR> - -ipsec addrlenof - get length of address within an ip_address -<BR> - -ipsec addrbytesof - get copy of address within an ip_address -<BR> - -ipsec addrbytesptr - get pointer to address within an ip_address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *initaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *dst);</B> - -<BR> - -<B>int addrtypeof(const ip_address *src);</B> - -<BR> - -<B>size_t addrlenof(const ip_address *src);</B> - -<BR> - -<B>size_t addrbytesof(const ip_address *src,</B> - -<BR> - -<B>unsigned char *dst, size_t dstlen);</B> - -<BR> - -<B>size_t addrbytesptr(const ip_address *src,</B> - -<BR> - -<B>const unsigned char **dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -library uses an internal type -<I>ip_address</I> - -to contain one of the (currently two) types of IP address. -These functions provide basic tools for creating and examining this type. -<P> - -<I>Initaddr</I> - -initializes a variable -<I>*dst</I> - -of type -<I>ip_address</I> - -from an address -(in network byte order, -indicated by a pointer -<I>src</I> - -and a length -<I>srclen</I>) - -and an address family -<I>af</I> - -(typically -<B>AF_INET</B> - -or -<B>AF_INET6</B>). - -The length must be consistent with the address family. -<P> - -<I>Addrtypeof</I> - -returns the address type of an address, -normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -(The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file arranges to include the necessary headers for these -names to be known.) -<P> - -<I>Addrlenof</I> - -returns the size (in bytes) of the address within an -<I>ip_address</I>, - -to permit storage allocation etc. -<P> - -<I>Addrbytesof</I> - -copies the address within the -<I>ip_address</I> - -<I>src</I> - -to the buffer indicated by the pointer -<I>dst</I> - -and the length -<I>dstlen</I>, - -and returns the address length (in bytes). -If the address will not fit, -as many bytes as will fit are copied; -the returned length is still the full length. -It is the caller's responsibility to check the -returned value to ensure that there was enough room. -<P> - -<I>Addrbytesptr</I> - -sets -<I>*dst</I> - -to a pointer to the internal address within the -<I>ip_address</I>, - -and returns the address length (in bytes). -If -<I>dst</I> - -is -<B>NULL</B>, - -it just returns the address length. -The pointer points to -<B>const</B> - -to discourage misuse. -<P> - -<I>Initaddr</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<P> - -The functions which return -<I>size_t</I> - -return -<B>0</B> - -for a failure. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -An unknown address family is a fatal error for any of these functions -except -<I>addrtypeof</I>. - -An address-size mismatch is a fatal error for -<I>initaddr</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -<I>Addrtypeof</I> - -should probably have been named -<I>addrfamilyof</I>. - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_anyaddr.3.html b/doc/manpage.d/ipsec_anyaddr.3.html deleted file mode 100644 index 974236005..000000000 --- a/doc/manpage.d/ipsec_anyaddr.3.html +++ /dev/null @@ -1,166 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 8 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec anyaddr - get "any" address -<BR> - -ipsec isanyaddr - test address for equality to "any" address -<BR> - -ipsec unspecaddr - get "unspecified" address -<BR> - -ipsec isunspecaddr - test address for equality to "unspecified" address -<BR> - -ipsec loopbackaddr - get loopback address -<BR> - -ipsec isloopbackaddr - test address for equality to loopback address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *anyaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isanyaddr(const ip_address *src);</B> - -<BR> - -<B>const char *unspecaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isunspecaddr(const ip_address *src);</B> - -<BR> - -<B>const char *loopbackaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isloopbackaddr(const ip_address *src);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions fill in, and test for, special values of the -<I>ip_address</I> - -type. -<P> - -<I>Anyaddr</I> - -fills in the destination -<I>*dst</I> - -with the ``any'' address of address family -<I>af</I> - -(normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>). - -The IPv4 ``any'' address is the one embodied in the old -<B>INADDR_ANY</B> - -macro. -<P> - -<I>Isanyaddr</I> - -returns -<B>1</B> - -if the -<I>src</I> - -address equals the ``any'' address, -and -<B>0</B> - -otherwise. -<P> - -Similarly, -<I>unspecaddr</I> - -supplies, and -<I>isunspecaddr</I> - -tests for, -the ``unspecified'' address, -which may be the same as the ``any'' address. -<P> - -Similarly, -<I>loopbackaddr</I> - -supplies, and -<I>islookbackaddr</I> - -tests for, -the loopback address. -<P> - -<I>Anyaddr</I>, - -<I>unspecaddr</I>, - -and -<I>loopbackaddr</I> - -return -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_addrtot.3.html">ipsec_addrtot</A>(3), <A HREF="ipsec_sameaddr.3.html">ipsec_sameaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in the address-supplying functions are: -unknown address family. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_atoaddr.3.html b/doc/manpage.d/ipsec_atoaddr.3.html deleted file mode 100644 index 8f0d765e5..000000000 --- a/doc/manpage.d/ipsec_atoaddr.3.html +++ /dev/null @@ -1,448 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ATOADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ATOADDR</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec atoaddr, addrtoa - convert Internet addresses to and from ASCII -<BR> - -ipsec atosubnet, subnettoa - convert subnet/mask ASCII form to and from addresses -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *atoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>struct in_addr *addr);</B> - -<BR> - -<B>size_t addrtoa(struct in_addr addr, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<P> -<B>const char *atosubnet(const char *src, size_t srclen,</B> - -<BR> - -<B>struct in_addr *addr, struct in_addr *mask);</B> - -<BR> - -<B>size_t subnettoa(struct in_addr addr, struct in_addr mask,</B> - -<BR> - -<B>int format, char *dst, size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; see -<I><A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A></I>(3) - -for their replacements. -<P> - -<I>Atoaddr</I> - -converts an ASCII name or dotted-decimal address into a binary address -(in network byte order). -<I>Addrtoa</I> - -does the reverse conversion, back to an ASCII dotted-decimal address. -<I>Atosubnet</I> - -and -<I>subnettoa</I> - -do likewise for the ``address/mask'' ASCII form used to write a -specification of a subnet. -<P> - -An address is specified in ASCII as a -dotted-decimal address (e.g. -<B>1.2.3.4</B>), - -an eight-digit network-order hexadecimal number with the usual C prefix (e.g. -<B>0x01020304</B>, - -which is synonymous with -<B>1.2.3.4</B>), - -an eight-digit host-order hexadecimal number with a -<B>0h</B> - -prefix (e.g. -<B>0h01020304</B>, - -which is synonymous with -<B>1.2.3.4</B> - -on a big-endian host and -<B>4.3.2.1</B> - -on a little-endian host), -a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3), - -or an old-style network name to be looked up via -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3). - -<P> - -A dotted-decimal address may be incomplete, in which case -ASCII-to-binary conversion implicitly appends -as many instances of -<B>.0</B> - -as necessary to bring it up to four components. -The components of a dotted-decimal address are always taken as -decimal, and leading zeros are ignored. -For example, -<B>10</B> - -is synonymous with -<B>10.0.0.0</B>, - -and -<B>128.009.000.032</B> - -is synonymous with -<B>128.9.0.32</B> - -(the latter example is verbatim from RFC 1166). -The result of -<I>addrtoa</I> - -is always complete and does not contain leading zeros. -<P> - -The letters in -a hexadecimal address may be uppercase or lowercase or any mixture thereof. -Use of hexadecimal addresses is -<B>strongly</B> - -<B>discouraged</B>; - -they are included only to save hassles when dealing with -the handful of perverted programs which already print -network addresses in hexadecimal. -<P> - -DNS names may be complete (optionally terminated with a ``.'') -or incomplete, and are looked up as specified by local system configuration -(see -<I><A HREF="resolver.5.html">resolver</A></I>(5)). - -The -<I>h_addr</I> - -value returned by -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3) - -is used, -so with current DNS implementations, -the result when the name corresponds to more than one address is -difficult to predict. -Name lookup resorts to -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3) - -only if -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3) - -fails. -<P> - -A subnet specification is of the form <I>network</I><B>/</B><I>mask</I>. -The -<I>network</I> - -and -<I>mask</I> - -can be any form acceptable to -<I>atoaddr</I>. - -In addition, the -<I>mask</I> - -can be a decimal integer (leading zeros ignored) giving a bit count, -in which case -it stands for a mask with that number of high bits on and all others off -(e.g., -<B>24</B> - -means -<B>255.255.255.0</B>). - -In any case, the mask must be contiguous -(a sequence of high bits on and all remaining low bits off). -As a special case, the subnet specification -<B>%default</B> - -is a synonym for -<B>0.0.0.0/0</B>. - -<P> - -<I>Atosubnet</I> - -ANDs the mask with the address before returning, -so that any non-network bits in the address are turned off -(e.g., -<B>10.1.2.3/24</B> - -is synonymous with -<B>10.1.2.0/24</B>). - -<I>Subnettoa</I> - -generates the decimal-integer-bit-count -form of the mask, -with no leading zeros, -unless the mask is non-contiguous. -<P> - -The -<I>srclen</I> - -parameter of -<I>atoaddr</I> - -and -<I>atosubnet</I> - -specifies the length of the ASCII string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>addrtoa</I> - -and -<I>subnettoa</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines constants, -<B>ADDRTOA_BUF</B> - -and -<B>SUBNETTOA_BUF</B>, - -which are the sizes of buffers just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>addrtoa</I> - -and -<I>subnettoa</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the ASCII character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default, -and is in fact the only format currently available. -This parameter is a hedge against future needs. -<P> - -The ASCII-to-binary functions return NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -The binary-to-ASCII functions return -<B>0</B> - -for a failure, and otherwise -always return the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>atoaddr</I> - -are: -empty input; -attempt to allocate temporary storage for a very long name failed; -name lookup failed; -syntax error in dotted-decimal form; -dotted-decimal component too large to fit in 8 bits. -<P> - -Fatal errors in -<I>atosubnet</I> - -are: -no -<B>/</B> - -in -<I>src</I>; - -<I>atoaddr</I> - -error in conversion of -<I>network</I> - -or -<I>mask</I>; - -bit-count mask too big; -mask non-contiguous. -<P> - -Fatal errors in -<I>addrtoa</I> - -and -<I>subnettoa</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The interpretation of incomplete dotted-decimal addresses -(e.g. -<B>10/24</B> - -means -<B>10.0.0.0/24</B>) - -differs from that of some older conversion -functions, e.g. those of -<I><A HREF="inet.3.html">inet</A></I>(3). - -The behavior of the older functions has never been -particularly consistent or particularly useful. -<P> - -Ignoring leading zeros in dotted-decimal components and bit counts -is arguably the most useful behavior in this application, -but it might occasionally cause confusion with the historical use of leading -zeros to denote octal numbers. -<P> - -It is barely possible that somebody, somewhere, -might have a legitimate use for non-contiguous subnet masks. -<P> - -<I><A HREF="Getnetbyname.3.html">Getnetbyname</A></I>(3) - -is a historical dreg. -<P> - -The restriction of ASCII-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The ASCII-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = atoaddr( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_atoasr.3.html b/doc/manpage.d/ipsec_atoasr.3.html deleted file mode 100644 index 7c9e2c4aa..000000000 --- a/doc/manpage.d/ipsec_atoasr.3.html +++ /dev/null @@ -1,294 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ATOASR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ATOASR</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec atoasr - convert ASCII to Internet address, subnet, or range -<BR> - -ipsec rangetoa - convert Internet address range to ASCII -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *atoasr(const char *src, size_t srclen,</B> - -<BR> - -<B>char *type, struct in_addr *addrs);</B> - -<BR> - -<B>size_t rangetoa(struct in_addr *addrs, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; -there is no current equivalent, -because so far they have not proved useful. -<P> - -<I>Atoasr</I> - -converts an ASCII address, subnet, or address range -into a suitable combination of binary addresses -(in network byte order). -<I>Rangetoa</I> - -converts an address range back into ASCII, -using dotted-decimal form for the addresses -(the other reverse conversions are handled by -<I><A HREF="ipsec_addrtoa.3.html">ipsec_addrtoa</A></I>(3) - -and -<I><A HREF="ipsec_subnettoa.3.html">ipsec_subnettoa</A></I>(3)). - -<P> - -A single address can be any form acceptable to -<I><A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A></I>(3): - -dotted decimal, DNS name, or hexadecimal number. -A subnet -specification uses the form <I>network</I><B>/</B><I>mask</I> -interpreted by -<I><A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A></I>(3). - -<P> - -An address range is two -<I><A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A></I>(3) - -addresses separated by a -<B>...</B> - -delimiter. -If there are four dots rather than three, the first is taken as -part of the begin address, -e.g. for a complete DNS name which ends with -<B>.</B> - -to suppress completion attempts. -The begin address of a range must be -less than or equal to the end address. -<P> - -The -<I>srclen</I> - -parameter of -<I>atoasr</I> - -specifies the length of the ASCII string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>type</I> - -parameter of -<I>atoasr</I> - -must point to a -<B>char</B> - -variable used to record which form was found. -The -<I>addrs</I> - -parameter must point to a two-element array of -<B>struct in_addr</B> - -which receives the results. -The values stored into -<B>*type</B>, - -and the corresponding values in the array, are: -<P> - - - -<TT> </TT>*typeaddrs[0]addrs[1]<BR> -<P> -address<B>'a'</B>address-<BR> -<BR> - -subnet<TT> </TT><B>'s'</B>networkmask<BR> -<BR> - -range<TT> </TT><B>'r'</B>beginend<BR> -<P> - -The -<I>dstlen</I> - -parameter of -<I>rangetoa</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines a constant, -<B>RANGETOA_BUF</B>, - -which is the size of a buffer just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>rangetoa</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the ASCII character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default, -and is in fact the only format currently available. -This parameter is a hedge against future needs. -<P> - -<I>Atoasr</I> - -returns NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<I>Rangetoa</I> - -returns -<B>0</B> - -for a failure, and otherwise -always returns the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A>(3), <A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>atoasr</I> - -are: -empty input; -error in -<I><A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A></I>(3) - -or -<I><A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A></I>(3) - -during conversion; -begin address of range exceeds end address. -<P> - -Fatal errors in -<I>rangetoa</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The restriction of error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = atoasr( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_atosa.3.html b/doc/manpage.d/ipsec_atosa.3.html deleted file mode 100644 index 9e2dc2f61..000000000 --- a/doc/manpage.d/ipsec_atosa.3.html +++ /dev/null @@ -1,347 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ATOSA</TITLE> -</HEAD><BODY> -<H1>IPSEC_ATOSA</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec atosa, satoa - convert IPsec Security Association IDs to and from ASCII -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *atosa(const char *src, size_t srclen,</B> - -<BR> - -<B>struct sa_id *sa);</B> - -<BR> - -<B>size_t satoa(struct sa_id sa, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<P> -<B>struct sa_id {</B> - -<BR> - -<B>struct in_addr dst;</B> - -<BR> - -<B>ipsec_spi_t spi;</B> - -<BR> - -<B>int proto;</B> - -<BR> - -<B>};</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; see -<I><A HREF="ipsec_ttosa.3.html">ipsec_ttosa</A></I>(3) - -for their replacements. -<P> - -<I>Atosa</I> - -converts an ASCII Security Association (SA) specifier into an -<B>sa_id</B> - -structure (containing -a destination-host address -in network byte order, -an SPI number in network byte order, and -a protocol code). -<I>Satoa</I> - -does the reverse conversion, back to an ASCII SA specifier. -<P> - -An SA is specified in ASCII with a mail-like syntax, e.g. -<B><A HREF="mailto:esp507@1.2.3.4">esp507@1.2.3.4</A></B>. - -An SA specifier contains -a protocol prefix (currently -<B>ah</B>, - -<B>esp</B>, - -or -<B>tun</B>), - -an unsigned integer SPI number, -and an IP address. -The SPI number can be decimal or hexadecimal -(with -<B>0x</B> - -prefix), as accepted by -<I><A HREF="ipsec_atoul.3.html">ipsec_atoul</A></I>(3). - -The IP address can be any form accepted by -<I><A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A></I>(3), - -e.g. dotted-decimal address or DNS name. -<P> - -As a special case, the SA specifier -<B>%passthrough</B> - -signifies the special SA used to indicate that packets should be -passed through unaltered. -(At present, this is a synonym for -<B><A HREF="mailto:tun0x0@0.0.0.0">tun0x0@0.0.0.0</A></B>, - -but that is subject to change without notice.) -This form is known to both -<I>atosa</I> - -and -<I>satoa</I>, - -so the internal form of -<B>%passthrough</B> - -is never visible. -<P> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file supplies the -<B>sa_id</B> - -structure, as well as a data type -<B>ipsec_spi_t</B> - -which is an unsigned 32-bit integer. -(There is no consistency between kernel and user on what such a type -is called, hence the header hides the differences.) -<P> - -The protocol code uses the same numbers that IP does. -For user convenience, given the difficulty in acquiring the exact set of -protocol names used by the kernel, -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -defines the names -<B>SA_ESP</B>, - -<B>SA_AH</B>, - -and -<B>SA_IPIP</B> - -to have the same values as the kernel names -<B>IPPROTO_ESP</B>, - -<B>IPPROTO_AH</B>, - -and -<B>IPPROTO_IPIP</B>. - -<P> - -The -<I>srclen</I> - -parameter of -<I>atosa</I> - -specifies the length of the ASCII string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>satoa</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines a constant, -<B>SATOA_BUF</B>, - -which is the size of a buffer just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>satoa</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the ASCII character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default -(currently -lowercase protocol prefix, lowercase hexadecimal SPI, dotted-decimal address). -The value -<B>d</B> - -causes the SPI to be generated in decimal instead. -<P> - -<I>Atosa</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<I>Satoa</I> - -returns -<B>0</B> - -for a failure, and otherwise -always returns the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec_atoul.3.html">ipsec_atoul</A>(3), <A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A>(3), <A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>atosa</I> - -are: -empty input; -input too small to be a legal SA specifier; -no -<B>@</B> - -in input; -unknown protocol prefix; -conversion error in -<I>atoul</I> - -or -<I>atoaddr</I>. - -<P> - -Fatal errors in -<I>satoa</I> - -are: -unknown format; unknown protocol code. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The -<B>tun</B> - -protocol code is a FreeS/WANism which may eventually disappear. -<P> - -The restriction of ASCII-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The ASCII-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = atoaddr( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_atosubnet.3.html b/doc/manpage.d/ipsec_atosubnet.3.html deleted file mode 100644 index 8f0d765e5..000000000 --- a/doc/manpage.d/ipsec_atosubnet.3.html +++ /dev/null @@ -1,448 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ATOADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ATOADDR</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec atoaddr, addrtoa - convert Internet addresses to and from ASCII -<BR> - -ipsec atosubnet, subnettoa - convert subnet/mask ASCII form to and from addresses -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *atoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>struct in_addr *addr);</B> - -<BR> - -<B>size_t addrtoa(struct in_addr addr, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<P> -<B>const char *atosubnet(const char *src, size_t srclen,</B> - -<BR> - -<B>struct in_addr *addr, struct in_addr *mask);</B> - -<BR> - -<B>size_t subnettoa(struct in_addr addr, struct in_addr mask,</B> - -<BR> - -<B>int format, char *dst, size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; see -<I><A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A></I>(3) - -for their replacements. -<P> - -<I>Atoaddr</I> - -converts an ASCII name or dotted-decimal address into a binary address -(in network byte order). -<I>Addrtoa</I> - -does the reverse conversion, back to an ASCII dotted-decimal address. -<I>Atosubnet</I> - -and -<I>subnettoa</I> - -do likewise for the ``address/mask'' ASCII form used to write a -specification of a subnet. -<P> - -An address is specified in ASCII as a -dotted-decimal address (e.g. -<B>1.2.3.4</B>), - -an eight-digit network-order hexadecimal number with the usual C prefix (e.g. -<B>0x01020304</B>, - -which is synonymous with -<B>1.2.3.4</B>), - -an eight-digit host-order hexadecimal number with a -<B>0h</B> - -prefix (e.g. -<B>0h01020304</B>, - -which is synonymous with -<B>1.2.3.4</B> - -on a big-endian host and -<B>4.3.2.1</B> - -on a little-endian host), -a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3), - -or an old-style network name to be looked up via -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3). - -<P> - -A dotted-decimal address may be incomplete, in which case -ASCII-to-binary conversion implicitly appends -as many instances of -<B>.0</B> - -as necessary to bring it up to four components. -The components of a dotted-decimal address are always taken as -decimal, and leading zeros are ignored. -For example, -<B>10</B> - -is synonymous with -<B>10.0.0.0</B>, - -and -<B>128.009.000.032</B> - -is synonymous with -<B>128.9.0.32</B> - -(the latter example is verbatim from RFC 1166). -The result of -<I>addrtoa</I> - -is always complete and does not contain leading zeros. -<P> - -The letters in -a hexadecimal address may be uppercase or lowercase or any mixture thereof. -Use of hexadecimal addresses is -<B>strongly</B> - -<B>discouraged</B>; - -they are included only to save hassles when dealing with -the handful of perverted programs which already print -network addresses in hexadecimal. -<P> - -DNS names may be complete (optionally terminated with a ``.'') -or incomplete, and are looked up as specified by local system configuration -(see -<I><A HREF="resolver.5.html">resolver</A></I>(5)). - -The -<I>h_addr</I> - -value returned by -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3) - -is used, -so with current DNS implementations, -the result when the name corresponds to more than one address is -difficult to predict. -Name lookup resorts to -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3) - -only if -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3) - -fails. -<P> - -A subnet specification is of the form <I>network</I><B>/</B><I>mask</I>. -The -<I>network</I> - -and -<I>mask</I> - -can be any form acceptable to -<I>atoaddr</I>. - -In addition, the -<I>mask</I> - -can be a decimal integer (leading zeros ignored) giving a bit count, -in which case -it stands for a mask with that number of high bits on and all others off -(e.g., -<B>24</B> - -means -<B>255.255.255.0</B>). - -In any case, the mask must be contiguous -(a sequence of high bits on and all remaining low bits off). -As a special case, the subnet specification -<B>%default</B> - -is a synonym for -<B>0.0.0.0/0</B>. - -<P> - -<I>Atosubnet</I> - -ANDs the mask with the address before returning, -so that any non-network bits in the address are turned off -(e.g., -<B>10.1.2.3/24</B> - -is synonymous with -<B>10.1.2.0/24</B>). - -<I>Subnettoa</I> - -generates the decimal-integer-bit-count -form of the mask, -with no leading zeros, -unless the mask is non-contiguous. -<P> - -The -<I>srclen</I> - -parameter of -<I>atoaddr</I> - -and -<I>atosubnet</I> - -specifies the length of the ASCII string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>addrtoa</I> - -and -<I>subnettoa</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines constants, -<B>ADDRTOA_BUF</B> - -and -<B>SUBNETTOA_BUF</B>, - -which are the sizes of buffers just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>addrtoa</I> - -and -<I>subnettoa</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the ASCII character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default, -and is in fact the only format currently available. -This parameter is a hedge against future needs. -<P> - -The ASCII-to-binary functions return NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -The binary-to-ASCII functions return -<B>0</B> - -for a failure, and otherwise -always return the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>atoaddr</I> - -are: -empty input; -attempt to allocate temporary storage for a very long name failed; -name lookup failed; -syntax error in dotted-decimal form; -dotted-decimal component too large to fit in 8 bits. -<P> - -Fatal errors in -<I>atosubnet</I> - -are: -no -<B>/</B> - -in -<I>src</I>; - -<I>atoaddr</I> - -error in conversion of -<I>network</I> - -or -<I>mask</I>; - -bit-count mask too big; -mask non-contiguous. -<P> - -Fatal errors in -<I>addrtoa</I> - -and -<I>subnettoa</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The interpretation of incomplete dotted-decimal addresses -(e.g. -<B>10/24</B> - -means -<B>10.0.0.0/24</B>) - -differs from that of some older conversion -functions, e.g. those of -<I><A HREF="inet.3.html">inet</A></I>(3). - -The behavior of the older functions has never been -particularly consistent or particularly useful. -<P> - -Ignoring leading zeros in dotted-decimal components and bit counts -is arguably the most useful behavior in this application, -but it might occasionally cause confusion with the historical use of leading -zeros to denote octal numbers. -<P> - -It is barely possible that somebody, somewhere, -might have a legitimate use for non-contiguous subnet masks. -<P> - -<I><A HREF="Getnetbyname.3.html">Getnetbyname</A></I>(3) - -is a historical dreg. -<P> - -The restriction of ASCII-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The ASCII-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = atoaddr( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_atoul.3.html b/doc/manpage.d/ipsec_atoul.3.html deleted file mode 100644 index 923a16131..000000000 --- a/doc/manpage.d/ipsec_atoul.3.html +++ /dev/null @@ -1,266 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ATOUL</TITLE> -</HEAD><BODY> -<H1>IPSEC_ATOUL</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec atoul, ultoa - convert unsigned-long numbers to and from ASCII -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *atoul(const char *src, size_t srclen,</B> - -<BR> - -<B>int base, unsigned long *n);</B> - -<BR> - -<B>size_t ultoa(unsigned long n, int base, char *dst,</B> - -<BR> - -<B>size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; see -<I><A HREF="ipsec_ttoul.3.html">ipsec_ttoul</A></I>(3) - -for their replacements. -<P> - -<I>Atoul</I> - -converts an ASCII number into a binary -<B>unsigned long</B> - -value. -<I>Ultoa</I> - -does the reverse conversion, back to an ASCII version. -<P> - -Numbers are specified in ASCII as -decimal (e.g. -<B>123</B>), - -octal with a leading zero (e.g. -<B>012</B>, - -which has value 10), -or hexadecimal with a leading -<B>0x</B> - -(e.g. -<B>0x1f</B>, - -which has value 31) -in either upper or lower case. -<P> - -The -<I>srclen</I> - -parameter of -<I>atoul</I> - -specifies the length of the ASCII string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>base</I> - -parameter of -<I>atoul</I> - -can be -<B>8</B>, - -<B>10</B>, - -or -<B>16</B>, - -in which case the number supplied is assumed to be of that form -(and in the case of -<B>16</B>, - -to lack any -<B>0x</B> - -prefix). -It can also be -<B>0</B>, - -in which case the number is examined for a leading zero -or a leading -<B>0x</B> - -to determine its base, -or -<B>13</B> - -(halfway between 10 and 16), -which has the same effect as -<B>0</B> - -except that a non-hexadecimal -number is considered decimal regardless of any leading zero. -<P> - -The -<I>dstlen</I> - -parameter of -<I>ultoa</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -<P> - -The -<I>base</I> - -parameter of -<I>ultoa</I> - -must be -<B>8</B>, - -<B>10</B>, - -or -<B>16</B>. - -<P> - -<I>Atoul</I> - -returns NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<I>Ultoa</I> - -returns the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="atol.3.html">atol</A>(3), <A HREF="strtoul.3.html">strtoul</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>atoul</I> - -are: -empty input; -unknown -<I>base</I>; - -non-digit character found; -number too large for an -<B>unsigned long</B>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -There is no provision for reporting an invalid -<I>base</I> - -parameter given to -<I>ultoa</I>. - -<P> - -The restriction of error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The error-reporting convention lends itself to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = atoul( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_auto.8.html b/doc/manpage.d/ipsec_auto.8.html deleted file mode 100644 index 68ca61bdc..000000000 --- a/doc/manpage.d/ipsec_auto.8.html +++ /dev/null @@ -1,416 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_AUTO</TITLE> -</HEAD><BODY> -<H1>IPSEC_AUTO</H1> -Section: Maintenance Commands (8)<BR>Updated: 31 Jan 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec auto - control automatically-keyed IPsec connections -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>auto</B> - -[ -<B>--show</B> - -] [ -<B>--showonly</B> - -] [ -<B>--asynchronous</B> - -] -<BR> - - [ -<B>--config</B> - -configfile -] [ -<B>--verbose</B> - -] -<BR> - - operation -connection -<P> -<B>ipsec</B> - -<B>auto</B> - -[ -<B>--show</B> - -] [ -<B>--showonly</B> - -] operation -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Auto</I> - -manipulates automatically-keyed FreeS/WAN IPsec connections, -setting them up and shutting them down -based on the information in the IPsec configuration file. -In the normal usage, -<I>connection</I> - -is the name of a connection specification in the configuration file; -<I>operation</I> - -is -<B>--add</B>, - -<B>--delete</B>, - -<B>--replace</B>, - -<B>--up</B>, - -<B>--down</B>, - -<B>--route</B>, - -or -<B>--unroute</B>. - -The -<B>--ready</B>, - -<B>--rereadsecrets</B>, - -<B>--rereadgroups</B>, - -and -<B>--status</B> - -<I>operations</I> - -do not take a connection name. -<I>Auto</I> - -generates suitable -commands and feeds them to a shell for execution. -<P> - -The -<B>--add</B> - -operation adds a connection specification to the internal database -within -<I>pluto</I>; - -it will fail if -<I>pluto</I> - -already has a specification by that name. -The -<B>--delete</B> - -operation deletes a connection specification from -<I>pluto</I>'s - -internal database (also tearing down any connections based on it); -it will fail if the specification does not exist. -The -<B>--replace</B> - -operation is equivalent to -<B>--delete</B> - -(if there is already a specification by the given name) -followed by -<B>--add</B>, - -and is a convenience for updating -<I>pluto</I>'s - -internal specification to match an external one. -(Note that a -<B>--rereadsecrets</B> - -may also be needed.) -The -<B>--rereadgroups</B> - -operation causes any changes to the policy group files to take effect -(this is currently a synonym for -<B>--ready</B>, - -but that may change). -None of the other operations alters the internal database. -<P> - -The -<B>--up</B> - -operation asks -<I>pluto</I> - -to establish a connection based on an entry in its internal database. -The -<B>--down</B> - -operation tells -<I>pluto</I> - -to tear down such a connection. -<P> - -Normally, -<I>pluto</I> - -establishes a route to the destination specified for a connection as -part of the -<B>--up</B> - -operation. -However, the route and only the route can be established with the -<B>--route</B> - -operation. -Until and unless an actual connection is established, -this discards any packets sent there, -which may be preferable to having them sent elsewhere based on a more -general route (e.g., a default route). -<P> - -Normally, -<I>pluto</I>'s - -route to a destination remains in place when a -<B>--down</B> - -operation is used to take the connection down -(or if connection setup, or later automatic rekeying, fails). -This permits establishing a new connection (perhaps using a -different specification; the route is altered as necessary) -without having a ``window'' in which packets might go elsewhere -based on a more general route. -Such a route can be removed using the -<B>--unroute</B> - -operation -(and is implicitly removed by -<B>--delete</B>). - -<P> - -The -<B>--ready</B> - -operation tells -<I>pluto</I> - -to listen for connection-setup requests from other hosts. -Doing an -<B>--up</B> - -operation before doing -<B>--ready</B> - -on both ends is futile and will not work, -although this is now automated as part of IPsec startup and -should not normally be an issue. -<P> - -The -<B>--status</B> - -operation asks -<I>pluto</I> - -for current connection status. -The output format is ad-hoc and likely to change. -<P> - -The -<B>--rereadsecrets</B> - -operation tells -<I>pluto</I> - -to re-read the -<I>/etc/ipsec.secrets</I> - -secret-keys file, -which it normally reads only at startup time. -(This is currently a synonym for -<B>--ready</B>, - -but that may change.) -<P> - -The -<B>--show</B> - -option turns on the -<B>-x</B> - -option of the shell used to execute the commands, -so each command is shown as it is executed. -<P> - -The -<B>--showonly</B> - -option causes -<I>auto</I> - -to show the commands it would run, on standard output, -and not run them. -<P> - -The -<B>--asynchronous</B> - -option, applicable only to the -<B>up</B> - -operation, -tells -<I>pluto</I> - -to attempt to establish the connection, -but does not delay to report results. -This is especially useful to start multiple connections in parallel -when network links are slow. -<P> - -The -<B>--verbose</B> - -option instructs -<I>auto</I> - -to pass through all output from -<I><A HREF="ipsec_whack.8.html">ipsec_whack</A></I>(8), - -including log output that is normally filtered out as uninteresting. -<P> - -The -<B>--config</B> - -option specifies a non-standard location for the IPsec -configuration file (default -<I>/etc/ipsec.conf</I>). - -<P> - -See -<I><A HREF="ipsec.conf.5.html">ipsec.conf</A></I>(5) - -for details of the configuration file. -Apart from the basic parameters which specify the endpoints and routing -of a connection (<B>left</B> -and -<B>right</B>, - -plus possibly -<B>leftsubnet</B>, - -<B>leftnexthop</B>, - -<B>leftfirewall</B>, - -their -<B>right</B> - -equivalents, -and perhaps -<B>type</B>), - -an -<I>auto</I> - -connection almost certainly needs a -<B>keyingtries</B> - -parameter (since the -<B>keyingtries</B> - -default is poorly chosen). -<A NAME="lbAE"> </A> -<H2>FILES</H2> - - - -/etc/ipsec.conf<TT> </TT>default IPSEC configuration file<BR> -<BR> - -/var/run/ipsec.info<TT> </TT><B>%defaultroute</B> information<BR> -<A NAME="lbAF"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.conf.5.html">ipsec.conf</A>(5), <A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_pluto.8.html">ipsec_pluto</A>(8), <A HREF="ipsec_whack.8.html">ipsec_whack</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8) -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -Although an -<B>--up</B> - -operation does connection setup on both ends, -<B>--down</B> - -tears only one end of the connection down -(although the orphaned end will eventually time out). -<P> - -There is no support for -<B>passthrough</B> - -connections. -<P> - -A connection description which uses -<B>%defaultroute</B> - -for one of its -<B>nexthop</B> - -parameters but not the other may be falsely -rejected as erroneous in some circumstances. -<P> - -The exit status of -<B>--showonly</B> - -does not always reflect errors discovered during processing of the request. -(This is fine for human inspection, but not so good for use in scripts.) -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">SEE ALSO</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_barf.8.html b/doc/manpage.d/ipsec_barf.8.html deleted file mode 100644 index e7b7200e0..000000000 --- a/doc/manpage.d/ipsec_barf.8.html +++ /dev/null @@ -1,150 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_BARF</TITLE> -</HEAD><BODY> -<H1>IPSEC_BARF</H1> -Section: Maintenance Commands (8)<BR>Updated: 17 March 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec barf - spew out collected IPsec debugging information -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>barf</B> - -[ -<B>--short</B> - -] -<P> -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Barf</I> - -outputs (on standard output) a collection of debugging information -(contents of files, selections from logs, etc.) -related to the IPsec encryption/authentication system. -It is primarily a convenience for remote debugging, -a single command which packages up (and labels) all information -that might be relevant to diagnosing a problem in IPsec. -<P> - -<P> - -The -<B>--short</B> - -option limits the length of -the log portion of -<I>barf</I>'s - -output, which can otherwise be extremely voluminous -if debug logging is turned on. -<P> - -<I>Barf</I> - -censors its output, -replacing keys -and secrets with brief checksums to avoid revealing sensitive information. -<P> - -Beware that the output of both commands is aimed at humans, -not programs, -and the output format is subject to change without warning. -<P> - -<I>Barf</I> - -has to figure out which files in -<I>/var/log</I> - -contain the IPsec log messages. -It looks for KLIPS and general log messages first in -<I>messages</I> - -and -<I>syslog</I>, - -and for Pluto messages first in -<I>secure</I>, - -<I>auth.log</I>, - -and -<I>debug</I>. - -In both cases, -if it does not find what it is looking for in one of those ``likely'' places, -it will resort to a brute-force search of most (non-compressed) files in -<I>/var/log</I>. - -<A NAME="lbAE"> </A> -<H2>FILES</H2> - -<PRE> -/proc/net/* -/var/log/* -/etc/ipsec.conf -/etc/ipsec.secrets -</PRE> - -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Henry Spencer. -<A NAME="lbAG"> </A> -<H2>BUGS</H2> - -<I>Barf</I> - -uses heuristics to try to pick relevant material out of the logs, -and relevant messages -which are not labelled with any of the tags that -<I>barf</I> - -looks for will be lost. -We think we've eliminated the last such case, but one never knows... -<P> - -Finding -<I>updown</I> - -scripts (so they can be included in output) is, in general, difficult. -<I>Barf</I> - -uses a very simple heuristic that is easily fooled. -<P> - -The brute-force search for the right log files can get expensive on -systems with a lot of clutter in -<I>/var/log</I>. - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -<DT><A HREF="#lbAG">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_bitstomask.3.html b/doc/manpage.d/ipsec_bitstomask.3.html deleted file mode 100644 index a67a08d83..000000000 --- a/doc/manpage.d/ipsec_bitstomask.3.html +++ /dev/null @@ -1,122 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_GOODMASK</TITLE> -</HEAD><BODY> -<H1>IPSEC_GOODMASK</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec goodmask - is this Internet subnet mask a valid one? -<BR> - -ipsec masktobits - convert Internet subnet mask to bit count -<BR> - -ipsec bitstomask - convert bit count to Internet subnet mask -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int goodmask(struct in_addr mask);</B> - -<BR> - -<B>int masktobits(struct in_addr mask);</B> - -<BR> - -<B>struct in_addr bitstomask(int n);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; -see -<I><A HREF="ipsec_masktocount.3.html">ipsec_masktocount</A></I>(3) - -for a partial replacement. -<P> - -<I>Goodmask</I> - -reports whether the subnet -<I>mask</I> - -is a valid one, -i.e. consists of a (possibly empty) sequence of -<B>1</B>s - -followed by a (possibly empty) sequence of -<B>0</B>s. - -<I>Masktobits</I> - -takes a (valid) subnet mask and returns the number of -<B>1</B> - -bits in it. -<I>Bitstomask</I> - -reverses this, -returning the subnet mask corresponding to bit count -<I>n</I>. - -<P> - -All masks are in network byte order. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -<I>Masktobits</I> - -returns -<B>-1</B> - -for an invalid mask. -<I>Bitstomask</I> - -returns an all-zeros mask for a negative or out-of-range -<I>n</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The error-reporting convention of -<I>bitstomask</I> - -is less than ideal; -zero is sometimes a legitimate mask. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_broadcastof.3.html b/doc/manpage.d/ipsec_broadcastof.3.html deleted file mode 100644 index 57d4a5648..000000000 --- a/doc/manpage.d/ipsec_broadcastof.3.html +++ /dev/null @@ -1,107 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_SUBNETOF</TITLE> -</HEAD><BODY> -<H1>IPSEC_SUBNETOF</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec subnetof - given Internet address and subnet mask, return subnet number -<BR> - -ipsec hostof - given Internet address and subnet mask, return host part -<BR> - -ipsec broadcastof - given Internet address and subnet mask, return broadcast address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>struct in_addr subnetof(struct in_addr addr,</B> - -<BR> - -<B>struct in_addr mask);</B> - -<BR> - -<B>struct in_addr hostof(struct in_addr addr,</B> - -<BR> - -<B>struct in_addr mask);</B> - -<BR> - -<B>struct in_addr broadcastof(struct in_addr addr,</B> - -<BR> - -<B>struct in_addr mask);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; see -<I><A HREF="ipsec_networkof.3.html">ipsec_networkof</A></I>(3) - -for their replacements. -<P> - -<I>Subnetof</I> - -takes an Internet -<I>address</I> - -and a subnet -<I>mask</I> - -and returns the network part of the address -(all in network byte order). -<I>Hostof</I> - -similarly returns the host part, and -<I>broadcastof</I> - -returns the broadcast address (all-1s convention) for the network. -<P> - -These functions are provided to hide the Internet bit-munging inside -an API, in hopes of easing the eventual transition to IPv6. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAG"> </A> -<H2>BUGS</H2> - -Calling functions for this is more costly than doing it yourself. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -<DT><A HREF="#lbAG">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_calcgoo.8.html b/doc/manpage.d/ipsec_calcgoo.8.html deleted file mode 100644 index 8379ac6a4..000000000 --- a/doc/manpage.d/ipsec_calcgoo.8.html +++ /dev/null @@ -1,78 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_CALCGOO</TITLE> -</HEAD><BODY> -<H1>IPSEC_CALCGOO</H1> -Section: Maintenance Commands (8)<BR>Updated: 8 June 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec calcgoo - calculate hex value for matching modules and kernels -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>calcgoo</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>calcgoo</I> - -accepts the output of -<B>nm -ao</B> - -or -<B>/proc/ksyms</B> - -and extracts a release dependant list of symbols from it. The symbols -are processed to extract the values assigned during the MODVERSIONS -process. This process makes sure that Linux modules are only loaded -on matching kernels. - -This routine is used to find an appropriate module to match the currently -running kernel by _startklips. -<A NAME="lbAE"> </A> -<H2>FILES</H2> - -<PRE> -/proc/ksyms -</PRE> - -<A NAME="lbAF"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec__startklips.8.html">ipsec__startklips</A>(8), <A HREF="genksyms.8.html">genksyms</A>(8) -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Michael Richardson. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">SEE ALSO</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_copyright_notice.3.html b/doc/manpage.d/ipsec_copyright_notice.3.html deleted file mode 100644 index c832e01f7..000000000 --- a/doc/manpage.d/ipsec_copyright_notice.3.html +++ /dev/null @@ -1,94 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_VERSION</TITLE> -</HEAD><BODY> -<H1>IPSEC_VERSION</H1> -Section: C Library Functions (3)<BR>Updated: 21 Nov 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ipsec_version_code - get IPsec version code -<BR> - -ipsec ipsec_version_string - get full IPsec version string -<BR> - -ipsec ipsec_copyright_notice - get IPsec copyright notice -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *ipsec_version_code(void);</B> - -<BR> - -<B>const char *ipsec_version_string(void);</B> - -<BR> - -<B>const char **ipsec_copyright_notice(void);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions provide information on version numbering and copyright -of the Linux FreeS/WAN IPsec implementation. -<P> - -<I>Ipsec_version_code</I> - -returns a pointer to a string constant -containing the current IPsec version code, -such as ``1.92'' or ``snap2001Nov19b''. -<P> - -<I>Ipsec_version_string</I> - -returns a pointer to a string constant giving a full version identification, -consisting of the version code preceded by a prefix identifying the software, -e.g. ``Linux FreeS/WAN 1.92''. -<P> - -<I>Ipsec_copyright_notice</I> - -returns a pointer to a vector of pointers, -terminated by a -<B>NULL</B>, - -which is the text of a suitable copyright notice. -Each pointer points to a string constant (possibly empty) which is one line -of the somewhat-verbose copyright notice. -The strings are NUL-terminated and do not contain a newline; -supplying suitable line termination for the output device is -the caller's responsibility. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_datatot.3.html b/doc/manpage.d/ipsec_datatot.3.html deleted file mode 100644 index 628558001..000000000 --- a/doc/manpage.d/ipsec_datatot.3.html +++ /dev/null @@ -1,439 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TTODATA</TITLE> -</HEAD><BODY> -<H1>IPSEC_TTODATA</H1> -Section: C Library Functions (3)<BR>Updated: 16 August 2003<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ttodata, datatot - convert binary data bytes from and to text formats -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *ttodata(const char *src, size_t srclen,</B> - -<BR> - -<B>int base, char *dst, size_t dstlen, size_t *lenp);</B> - -<BR> - -<B>const char *ttodatav(const char *src, size_t srclen,</B> - -<BR> - -<B>int base, char *dst, size_t dstlen, size_t *lenp,</B> - -<BR> - -<B>char *errp, size_t errlen, int flags);</B> - -<BR> - -<B>size_t datatot(const char *src, size_t srclen,</B> - -<BR> - -<B>int format, char *dst, size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ttodata</I>, - -<I>ttodatav</I>, - -and -<I>datatot</I> - -convert arbitrary binary data (e.g. encryption or authentication keys) -from and to more-or-less human-readable text formats. -<P> - -Currently supported formats are hexadecimal, base64, and characters. -<P> - -A hexadecimal text value begins with a -<B>0x</B> - -(or -<B>0X</B>) - -prefix and continues with two-digit groups -of hexadecimal digits (0-9, and a-f or A-F), -each group encoding the value of one binary byte, high-order digit first. -A single -<B>_</B> - -(underscore) -between consecutive groups is ignored, permitting punctuation to improve -readability; doing this every eight digits seems about right. -<P> - -A base64 text value begins with a -<B>0s</B> - -(or -<B>0S</B>) - -prefix -and continues with four-digit groups of base64 digits (A-Z, a-z, 0-9, +, and /), -each group encoding the value of three binary bytes as described in -section 6.8 of RFC 2045. -If -<B>flags</B> - -has the -<B>TTODATAV_IGNORESPACE</B> - -bit on, blanks are ignore (after the prefix). -Note that the last one or two digits of a base64 group can be -<B>=</B> - -to indicate that fewer than three binary bytes are encoded. -<P> - -A character text value begins with a -<B>0t</B> - -(or -<B>0T</B>) - -prefix -and continues with text characters, each being the value of one binary byte. -<P> - -All these functions basically copy data from -<I>src</I> - -(whose size is specified by -<I>srclen</I>) - -to -<I>dst</I> - -(whose size is specified by -<I>dstlen</I>), - -doing the conversion en route. -If the result will not fit in -<I>dst</I>, - -it is truncated; -under no circumstances are more than -<I>dstlen</I> - -bytes of result written to -<I>dst</I>. - -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result bytes are written at all. -<P> - -The -<I>base</I> - -parameter of -<I>ttodata</I> - -and -<I>ttodatav</I> - -specifies what format the input is in; -normally it should be -<B>0</B> - -to signify that this gets figured out from the prefix. -Values of -<B>16</B>, - -<B>64</B>, - -and -<B>256</B> - -respectively signify hexadecimal, base64, and character-text formats -without prefixes. -<P> - -The -<I>format</I> - -parameter of -<I>datatot</I>, - -a single character used as a type code, -specifies which text format is wanted. -The value -<B>0</B> - -(not ASCII -<B>'0'</B>, - -but a zero value) specifies a reasonable default. -Other currently-supported values are: -<DL COMPACT><DT><DD> -<DL COMPACT> -<DT><B>'x'</B> - -<DD> -continuous lower-case hexadecimal with a -<B>0x</B> - -prefix -<DT><B>'h'</B> - -<DD> -lower-case hexadecimal with a -<B>0x</B> - -prefix and a -<B>_</B> - -every eight digits -<DT><B>':'</B> - -<DD> -lower-case hexadecimal with no prefix and a -<B>:</B> - -(colon) every two digits -<DT><B>16</B> - -<DD> -lower-case hexadecimal with no prefix or -<B>_</B> - -<DT><B>'s'</B> - -<DD> -continuous base64 with a -<B>0s</B> - -prefix -<DT><B>64</B> - -<DD> -continuous base64 with no prefix -</DL> -</DL> - -<P> - -The default format is currently -<B>'h'</B>. - -<P> - -<I>Ttodata</I> - -returns NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -On success, -if and only if -<I>lenp</I> - -is non-NULL, -<B>*lenp</B> - -is set to the number of bytes required to contain the full untruncated result. -It is the caller's responsibility to check this against -<I>dstlen</I> - -to determine whether he has obtained a complete result. -The -<B>*lenp</B> - -value is correct even if -<I>dstlen</I> - -is zero, which offers a way to determine how much space would be needed -before having to allocate any. -<P> - -<I>Ttodatav</I> - -is just like -<I>ttodata</I> - -except that in certain cases, -if -<I>errp</I> - -is non-NULL, -the buffer pointed to by -<I>errp</I> - -(whose length is given by -<I>errlen</I>) - -is used to hold a more detailed error message. -The return value is NULL for success, -and is either -<I>errp</I> - -or a pointer to a string literal for failure. -If the size of the error-message buffer is -inadequate for the desired message, -<I>ttodatav</I> - -will fall back on returning a pointer to a literal string instead. -The -<I>freeswan.h</I> - -header file defines a constant -<B>TTODATAV_BUF</B> - -which is the size of a buffer large enough for worst-case results. -<P> - -The normal return value of -<I>datatot</I> - -is the number of bytes required -to contain the full untruncated result. -It is the caller's responsibility to check this against -<I>dstlen</I> - -to determine whether he has obtained a complete result. -The return value is correct even if -<I>dstlen</I> - -is zero, which offers a way to determine how much space would be needed -before having to allocate any. -A return value of -<B>0</B> - -signals a fatal error of some kind -(see DIAGNOSTICS). -<P> - -A zero value for -<I>srclen</I> - -in -<I>ttodata</I> - -(but not -<I>datatot</I>!) - -is synonymous with -<B>strlen(src)</B>. - -A non-zero -<I>srclen</I> - -in -<I>ttodata</I> - -must not include the terminating NUL. -<P> - -Unless -<I>dstlen</I> - -is zero, -the result supplied by -<I>datatot</I> - -is always NUL-terminated, -and its needed-size return value includes space for the terminating NUL. -<P> - -Several obsolete variants of these functions -(<I>atodata</I>, - -<I>datatoa</I>, - -<I>atobytes</I>, - -and -<I>bytestoa</I>) - -are temporarily also supported. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="sprintf.3.html">sprintf</A>(3), <A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>ttodata</I> - -and -<I>ttodatav</I> - -are: -unknown characters in the input; -unknown or missing prefix; -unknown base; -incomplete digit group; -non-zero padding in a base64 less-than-three-bytes digit group; -zero-length input. -<P> - -Fatal errors in -<I>datatot</I> - -are: -unknown format code; -zero-length input. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -<I>Datatot</I> - -should have a format code to produce character-text output. -<P> - -The -<B>0s</B> - -and -<B>0t</B> - -prefixes are the author's inventions and are not a standard -of any kind. -They have been chosen to avoid collisions with existing practice -(some C implementations use -<B>0b</B> - -for binary) -and possible confusion with unprefixed hexadecimal. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_eroute.5.html b/doc/manpage.d/ipsec_eroute.5.html deleted file mode 100644 index 158b57015..000000000 --- a/doc/manpage.d/ipsec_eroute.5.html +++ /dev/null @@ -1,370 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_EROUTE</TITLE> -</HEAD><BODY> -<H1>IPSEC_EROUTE</H1> -Section: File Formats (5)<BR>Updated: 20 Sep 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec_eroute - list of existing eroutes -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>eroute</B> - -<P> - -<B>cat</B> - -<B>/proc/net/ipsec_eroute</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>/proc/net/ipsec_eroute</I> - -lists the IPSEC extended routing tables, -which control what (if any) processing is applied -to non-encrypted packets arriving for IPSEC processing and forwarding. -At this point it is a read-only file. -<P> - -A table entry consists of: -<DL COMPACT> -<DT>+<DD> -packet count, -<DT>+<DD> -source address with mask, -<DT>+<DD> -a '->' separator for visual and automated parsing between src and dst -<DT>+<DD> -destination address with mask -<DT>+<DD> -a '=>' separator for visual and automated parsing between selection -criteria and SAID to use -<DT>+<DD> -SAID (Security Association IDentifier), comprised of: -<DT>+<DD> -protocol -(<I>proto</I>), -<DT>+<DD> -address family -(<I>af</I>), -where '.' stands for IPv4 and ':' for IPv6 -<DT>+<DD> -Security Parameters Index -(<I>SPI</I>), -<DT>+<DD> -effective destination -(<I>edst</I>), -where the packet should be forwarded after processing -(normally the other security gateway) -together indicate which Security Association should be used to process -the packet, -<DT>+<DD> -source identity text string with no whitespace, in parens, -<DT>+<DD> -destination identity text string with no whitespace, in parens -</DL> -<P> - -Addresses are written as IPv4 dotted quads or IPv6 coloned hex, -protocol is one of "ah", "esp", "comp" or "tun" -and -SPIs are prefixed hexadecimal numbers where the prefix '.' is for IPv4 and the prefix ':' is for IPv6 -<P> - -SAIDs are written as "<A HREF="mailto:protoafSPI@edst">protoafSPI@edst</A>". There are also 5 -"magic" SAIDs which have special meaning: -<DL COMPACT> -<DT>+<DD> -<B>%drop</B> - -means that matches are to be dropped -<DT>+<DD> -<B>%reject</B> - -means that matches are to be dropped and an ICMP returned, if -possible to inform -<DT>+<DD> -<B>%trap</B> - -means that matches are to trigger an ACQUIRE message to the Key -Management daemon(s) and a hold eroute will be put in place to -prevent subsequent packets also triggering ACQUIRE messages. -<DT>+<DD> -<B>%hold</B> - -means that matches are to stored until the eroute is replaced or -until that eroute gets reaped -<DT>+<DD> -<B>%pass</B> - -means that matches are to allowed to pass without IPSEC processing -<BR> - - -</DL> -<A NAME="lbAE"> </A> -<H2>EXAMPLES</H2> - -<P> - -<B>1867 172.31.252.0/24 -> 0.0.0.0/0 => <A HREF="mailto:tun.130@192.168.43.1">tun.130@192.168.43.1</A> </B> - -<BR> - -<B> ()<TT> </TT>()</B> - -<P> - -means that 1,867 packets have been sent to an<BR> -<B>eroute</B> - -that has been set up to protect traffic between the subnet -<B>172.31.252.0</B> - -with a subnet mask of -<B>24</B> - -bits and the default address/mask represented by an address of -<B>0.0.0.0</B> - -with a subnet mask of -<B>0</B> - -bits using the local machine as a security gateway on this end of the -tunnel and the machine -<B>192.168.43.1</B> - -on the other end of the tunnel with a Security Association IDentifier of -<B><A HREF="mailto:tun0x130@192.168.43.1">tun0x130@192.168.43.1</A></B> - -which means that it is a tunnel mode connection (4, IPPROTO_IPIP) with a -Security Parameters Index of -<B>130</B> - -in hexadecimal with no identies defined for either end. -<P> - -<B>125 3049:1::/64 -> 0:0/0 => tun:<A HREF="mailto:130@3058">130@3058</A>:4::5<TT> </TT>()<TT> </TT>()</B> - -<P> - -means that 125 packets have been sent to an<BR> -<B>eroute</B> - -that has been set up to protect traffic between the subnet -<B>3049:1::</B> - -with a subnet mask of -<B>64</B> - -bits and the default address/mask represented by an address of -<B>0:0</B> - -with a subnet mask of -<B>0</B> - -bits using the local machine as a security gateway on this end of the -tunnel and the machine -<B>3058:4::5</B> - -on the other end of the tunnel with a Security Association IDentifier of -<B>tun:<A HREF="mailto:130@3058">130@3058</A>:4::5</B> - -which means that it is a tunnel mode connection with a -Security Parameters Index of -<B>130</B> - -in hexadecimal with no identies defined for either end. -<P> - -<B>42 192.168.6.0/24 -> 192.168.7.0/24 => %passthrough</B> - -<P> - -means that 42 packets have been sent to an -<B>eroute</B> - -that has been set up to pass the traffic from the subnet -<B>192.168.6.0</B> - -with a subnet mask of -<B>24</B> - -bits and to subnet -<B>192.168.7.0</B> - -with a subnet mask of -<B>24</B> - -bits without any IPSEC processing with no identies defined for either end. -<P> - -<B>2112 192.168.8.55/32 -> 192.168.9.47/24 => %hold<TT> </TT>(east)<TT> </TT>()</B> - -<P> - -means that 2112 packets have been sent to an<BR> -<B>eroute</B> - -that has been set up to hold the traffic from the host -<B>192.168.8.55</B> - -and to host -<B>192.168.9.47</B> - -until a key exchange from a Key Management daemon -succeeds and puts in an SA or fails and puts in a pass -or drop eroute depending on the default configuration with the local client -defined as "east" and no identy defined for the remote end. -<P> - -<B>2001 192.168.2.110/32 -> 192.168.2.120/32 => </B> - -<BR> - -<B> <A HREF="mailto:esp.e6de@192.168.2.120">esp.e6de@192.168.2.120</A><TT> </TT>()<TT> </TT>()</B> - -<P> - -means that 2001 packets have been sent to an<BR> -<B>eroute</B> - -that has been set up to protect traffic between the host -<B>192.168.2.110</B> - -and the host -<B>192.168.2.120</B> - -using -<B>192.168.2.110</B> - -as a security gateway on this end of the -connection and the machine -<B>192.168.2.120</B> - -on the other end of the connection with a Security Association IDentifier of -<B><A HREF="mailto:esp.e6de@192.168.2.120">esp.e6de@192.168.2.120</A></B> - -which means that it is a transport mode connection with a Security -Parameters Index of -<B>e6de</B> - -in hexadecimal using Encapsuation Security Payload protocol (50, -IPPROTO_ESP) with no identies defined for either end. -<P> - -<B>1984 3049:1::110/128 -> 3049:1::120/128 => </B> - -<BR> - -<B> ah:<A HREF="mailto:f5ed@3049">f5ed@3049</A>:1::120<TT> </TT>()<TT> </TT>()</B> - -<P> - -means that 1984 packets have been sent to an<BR> -<B>eroute</B> - -that has been set up to authenticate traffic between the host -<B>3049:1::110</B> - -and the host -<B>3049:1::120</B> - -using -<B>3049:1::110</B> - -as a security gateway on this end of the -connection and the machine -<B>3049:1::120</B> - -on the other end of the connection with a Security Association IDentifier of -<B>ah:<A HREF="mailto:f5ed@3049">f5ed@3049</A>:1::120</B> - -which means that it is a transport mode connection with a Security -Parameters Index of -<B>f5ed</B> - -in hexadecimal using Authentication Header protocol (51, -IPPROTO_AH) with no identies defined for either end. -<A NAME="lbAF"> </A> -<H2>FILES</H2> - -/proc/net/ipsec_eroute, /usr/local/bin/ipsec -<A NAME="lbAG"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_tncfg.5.html">ipsec_tncfg</A>(5), <A HREF="ipsec_spi.5.html">ipsec_spi</A>(5), -<A HREF="ipsec_spigrp.5.html">ipsec_spigrp</A>(5), <A HREF="ipsec_klipsdebug.5.html">ipsec_klipsdebug</A>(5), <A HREF="ipsec_eroute.8.html">ipsec_eroute</A>(8), <A HREF="ipsec_version.5.html">ipsec_version</A>(5), -<A HREF="ipsec_pf_key.5.html">ipsec_pf_key</A>(5) -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Richard Guy Briggs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">EXAMPLES</A><DD> -<DT><A HREF="#lbAF">FILES</A><DD> -<DT><A HREF="#lbAG">SEE ALSO</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_eroute.8.html b/doc/manpage.d/ipsec_eroute.8.html deleted file mode 100644 index 7489462d7..000000000 --- a/doc/manpage.d/ipsec_eroute.8.html +++ /dev/null @@ -1,421 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_EROUTE</TITLE> -</HEAD><BODY> -<H1>IPSEC_EROUTE</H1> -Section: Maintenance Commands (8)<BR>Updated: 21 Jun 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec eroute - manipulate IPSEC extended routing tables -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>eroute</B> - -<P> - -<B>ipsec</B> - -<B>eroute</B> - -<B>--add</B> - -<B>--eraf (inet | inet6)</B> - -<B>--src</B> - -src/srcmaskbits|srcmask -<B>--dst</B> - -dst/dstmaskbits|dstmask -<SAID> -<P> - -<B>ipsec</B> - -<B>eroute</B> - -<B>--replace</B> - -<B>--eraf (inet | inet6)</B> - -<B>--src</B> - -src/srcmaskbits|srcmask -<B>--dst</B> - -dst/dstmaskbits|dstmask -<SAID> -<P> - -<B>ipsec</B> - -<B>eroute</B> - -<B>--del</B> - -<B>--eraf (inet | inet6)</B> - -<B>--src</B> - -src/srcmaskbits|srcmask -<B>--dst</B> - -dst/dstmaskbits|dstmask -<P> - -<B>ipsec</B> - -<B>eroute</B> - -<B>--clear</B> - -<P> - -<B>ipsec</B> - -<B>eroute</B> - -<B>--help</B> - -<P> - -<B>ipsec</B> - -<B>eroute</B> - -<B>--version</B> - -<P> - -Where <SAID> is -<B>--af</B> - -(inet | inet6) -<B>--edst</B> - -edst -<B>--spi</B> - -spi -<B>--proto</B> - -proto -OR -<B>--said</B> - -said -OR -<B>--said</B> - -<B>(%passthrough | %passthrough4 | %passthrough6)</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Eroute</I> - -manages the IPSEC extended routing tables, -which control what (if any) processing is applied -to non-encrypted packets arriving for IPSEC processing and forwarding. -The form with no additional arguments lists the contents of -/proc/net/ipsec_eroute. -The -<B>--add</B> - -form adds a table entry, the -<B>--replace</B> - -form replaces a table entry, while the -<B>--del</B> - -form deletes one. The -<B>--clear</B> - -form deletes the entire table. -<P> - -A table entry consists of: -<DL COMPACT> -<DT>+<DD> -source and destination addresses, -with masks, -for selection of packets -<DT>+<DD> -Security Association IDentifier, comprised of: -<DT>+<DD> -protocol -(<I>proto</I>), indicating (together with the -effective destination and the security parameters index) -which Security Association should be used to process the packet -<DT>+<DD> -address family -(<I>af</I>), -<DT>+<DD> -Security Parameters Index -(<I>spi</I>), indicating (together with the -effective destination and protocol) -which Security Association should be used to process the packet -(must be larger than or equal to 0x100) -<DT>+<DD> -effective destination -(<I>edst</I>), -where the packet should be forwarded after processing -(normally the other security gateway) -<DT>+<DD> -OR -<DT>+<DD> -SAID -(<I>said</I>), indicating -which Security Association should be used to process the packet -</DL> -<P> - -Addresses are written as IPv4 dotted quads or IPv6 coloned hex, -protocol is one of "ah", "esp", "comp" or "tun" and SPIs are -prefixed hexadecimal numbers where '.' represents IPv4 and ':' -stands for IPv6. -<P> - -SAIDs are written as "<A HREF="mailto:protoafSPI@address">protoafSPI@address</A>". There are also 5 -"magic" SAIDs which have special meaning: -<DL COMPACT> -<DT>+<DD> -<B>%drop</B> - -means that matches are to be dropped -<DT>+<DD> -<B>%reject</B> - -means that matches are to be dropped and an ICMP returned, if -possible to inform -<DT>+<DD> -<B>%trap</B> - -means that matches are to trigger an ACQUIRE message to the Key -Management daemon(s) and a hold eroute will be put in place to -prevent subsequent packets also triggering ACQUIRE messages. -<DT>+<DD> -<B>%hold</B> - -means that matches are to stored until the eroute is replaced or -until that eroute gets reaped -<DT>+<DD> -<B>%pass</B> - -means that matches are to allowed to pass without IPSEC processing -</DL> -<P> - -The format of /proc/net/ipsec_eroute is listed in <A HREF="ipsec_eroute.5.html">ipsec_eroute</A>(5). -<BR> - - -<A NAME="lbAE"> </A> -<H2>EXAMPLES</H2> - -<P> - -<B>ipsec eroute --add --eraf inet --src 192.168.0.1/32 \</B> - -<BR> - -<B> --dst 192.168.2.0/24 --af inet --edst 192.168.0.2 \</B> - -<BR> - -<B> --spi 0x135 --proto tun</B> - -<P> - -sets up an -<B>eroute</B> - -on a Security Gateway to protect traffic between the host -<B>192.168.0.1</B> - -and the subnet -<B>192.168.2.0</B> - -with -<B>24</B> - -bits of subnet mask via Security Gateway -<B>192.168.0.2</B> - -using the Security Association with address -<B>192.168.0.2</B>, - -Security Parameters Index -<B>0x135</B> - -and protocol -<B>tun</B> - -(50, IPPROTO_ESP). -<P> - -<B>ipsec eroute --add --eraf inet6 --src 3049:1::1/128 \</B> - -<BR> - -<B> --dst 3049:2::/64 --af inet6 --edst 3049:1::2 \</B> - -<BR> - -<B> --spi 0x145 --proto tun</B> - -<P> - -sets up an -<B>eroute</B> - -on a Security Gateway to protect traffic between the host -<B>3049:1::1</B> - -and the subnet -<B>3049:2::</B> - -with -<B>64</B> - -bits of subnet mask via Security Gateway -<B>3049:1::2</B> - -using the Security Association with address -<B>3049:1::2</B>, - -Security Parameters Index -<B>0x145</B> - -and protocol -<B>tun</B> - -(50, IPPROTO_ESP). -<P> - -<B>ipsec eroute --replace --eraf inet --src company.com/24 \</B> - -<BR> - -<B> --dst <A HREF="ftp://ftp.ngo.org">ftp.ngo.org</A>/32 --said <A HREF="mailto:tun.135@gw.ngo.org">tun.135@gw.ngo.org</A></B> - -<P> - -replaces an -<B>eroute</B> - -on a Security Gateway to protect traffic between the subnet -<B>company.com</B> - -with -<B>24</B> - -bits of subnet mask and the host -<B><A HREF="ftp://ftp.ngo.org">ftp.ngo.org</A></B> - -via Security Gateway -<B>gw.ngo.org</B> - -using the Security Association with Security Association ID -<B><A HREF="mailto:tun0x135@gw.ngo.org">tun0x135@gw.ngo.org</A></B> - -<P> - -<B>ipsec eroute --del --eraf inet --src company.com/24 \</B> - -<BR> - -<B> --dst <A HREF="http://www.ietf.org">www.ietf.org</A>/32 --said %passthrough4</B> - -<P> - -deletes an -<B>eroute</B> - -on a Security Gateway that allowed traffic between the subnet -<B>company.com</B> - -with -<B>24</B> - -bits of subnet mask and the host -<B><A HREF="http://www.ietf.org">www.ietf.org</A></B> - -to pass in the clear, unprocessed. -<A NAME="lbAF"> </A> -<H2>FILES</H2> - -/proc/net/ipsec_eroute, /usr/local/bin/ipsec -<A NAME="lbAG"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A>(8), <A HREF="ipsec_spi.8.html">ipsec_spi</A>(8), -<A HREF="ipsec_spigrp.8.html">ipsec_spigrp</A>(8), <A HREF="ipsec_klipsdebug.8.html">ipsec_klipsdebug</A>(8), <A HREF="ipsec_eroute.5.html">ipsec_eroute</A>(5) -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Richard Guy Briggs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">EXAMPLES</A><DD> -<DT><A HREF="#lbAF">FILES</A><DD> -<DT><A HREF="#lbAG">SEE ALSO</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_goodmask.3.html b/doc/manpage.d/ipsec_goodmask.3.html deleted file mode 100644 index a67a08d83..000000000 --- a/doc/manpage.d/ipsec_goodmask.3.html +++ /dev/null @@ -1,122 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_GOODMASK</TITLE> -</HEAD><BODY> -<H1>IPSEC_GOODMASK</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec goodmask - is this Internet subnet mask a valid one? -<BR> - -ipsec masktobits - convert Internet subnet mask to bit count -<BR> - -ipsec bitstomask - convert bit count to Internet subnet mask -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int goodmask(struct in_addr mask);</B> - -<BR> - -<B>int masktobits(struct in_addr mask);</B> - -<BR> - -<B>struct in_addr bitstomask(int n);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; -see -<I><A HREF="ipsec_masktocount.3.html">ipsec_masktocount</A></I>(3) - -for a partial replacement. -<P> - -<I>Goodmask</I> - -reports whether the subnet -<I>mask</I> - -is a valid one, -i.e. consists of a (possibly empty) sequence of -<B>1</B>s - -followed by a (possibly empty) sequence of -<B>0</B>s. - -<I>Masktobits</I> - -takes a (valid) subnet mask and returns the number of -<B>1</B> - -bits in it. -<I>Bitstomask</I> - -reverses this, -returning the subnet mask corresponding to bit count -<I>n</I>. - -<P> - -All masks are in network byte order. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -<I>Masktobits</I> - -returns -<B>-1</B> - -for an invalid mask. -<I>Bitstomask</I> - -returns an all-zeros mask for a negative or out-of-range -<I>n</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The error-reporting convention of -<I>bitstomask</I> - -is less than ideal; -zero is sometimes a legitimate mask. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_hostof.3.html b/doc/manpage.d/ipsec_hostof.3.html deleted file mode 100644 index 57d4a5648..000000000 --- a/doc/manpage.d/ipsec_hostof.3.html +++ /dev/null @@ -1,107 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_SUBNETOF</TITLE> -</HEAD><BODY> -<H1>IPSEC_SUBNETOF</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec subnetof - given Internet address and subnet mask, return subnet number -<BR> - -ipsec hostof - given Internet address and subnet mask, return host part -<BR> - -ipsec broadcastof - given Internet address and subnet mask, return broadcast address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>struct in_addr subnetof(struct in_addr addr,</B> - -<BR> - -<B>struct in_addr mask);</B> - -<BR> - -<B>struct in_addr hostof(struct in_addr addr,</B> - -<BR> - -<B>struct in_addr mask);</B> - -<BR> - -<B>struct in_addr broadcastof(struct in_addr addr,</B> - -<BR> - -<B>struct in_addr mask);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; see -<I><A HREF="ipsec_networkof.3.html">ipsec_networkof</A></I>(3) - -for their replacements. -<P> - -<I>Subnetof</I> - -takes an Internet -<I>address</I> - -and a subnet -<I>mask</I> - -and returns the network part of the address -(all in network byte order). -<I>Hostof</I> - -similarly returns the host part, and -<I>broadcastof</I> - -returns the broadcast address (all-1s convention) for the network. -<P> - -These functions are provided to hide the Internet bit-munging inside -an API, in hopes of easing the eventual transition to IPv6. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAG"> </A> -<H2>BUGS</H2> - -Calling functions for this is more costly than doing it yourself. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -<DT><A HREF="#lbAG">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_ikeping.8.html b/doc/manpage.d/ipsec_ikeping.8.html deleted file mode 100644 index 03ed961f3..000000000 --- a/doc/manpage.d/ipsec_ikeping.8.html +++ /dev/null @@ -1,137 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_IKEPING</TITLE> -</HEAD><BODY> -<H1>IPSEC_IKEPING</H1> -Section: Maintenance Commands (8)<BR>Updated: 23 Feb 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ikeping - send/receive ISAKMP/IKE echo requests/replies -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>ikeping</B> - -[ -<B>--listen</B> - -] [ -<B>--verbose</B> - -] [ -<B>--wait </B> - -time ] [ -<B>--exchangenum </B> - -num ] [ -<B>--ikeport </B> - -localport ] [ -<B>--ikeaddress </B> - -address ] [ -<B>--inet</B> - -] [ -<B>--inet6</B> - -] destaddr[/dstport] ... -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ikeping</I> - -sends and receives ISAKMP/IKE echo request and echo reply packets. These -packets are intended for diagnostics purposes, in a manner similar to -<I><A HREF="ping.8.html">ping</A></I>(8) - -does for ICMP echo request/reply packets. -<P> - -At the time of this writing, the ISAKMP echo request/reply exchange is still -an internet-draft, and is therefore completely non-standard. -<P> - -<I>Ikeping</I> - -will bind to the local address given by -<B>--ikeaddress</B> - -and the port number given by -<B>--ikeport</B> - -defaulting to the wildcard address and the ISAKMP port 500. An ISAKMP -exchange of type 244 (a private use number) is sent to each of the -address/ports listed on the command line. The exchange number may be -overridden by the -<B>--exchangenum </B> - -option. -<P> - -<I>Ikeping</I> - -then listens for replies, printing them as they are received. Replies -are of exchange type 245 or the specified exchange number plus 1. -<I>Ikeping </I> - -will keep listening until it either receives as many echo responses as it sent, -or until the timeout period (10 seconds) has been reached. Receipt of a -packet will reset the timer. The -<B>--wait</B> - -option can be used to specify a different timeout period. -<P> - -If the -<B>--listen</B> - -option is given, then -<I>ikeping</I> - -will not send any packets. Instead, it will listen for them and reply to -each request received. -<A NAME="lbAE"> </A> -<H2>FILES</H2> - -no external files -<A NAME="lbAF"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ping.8.html">ping</A>(8), <A HREF="ipsec_pluto.8.html">ipsec_pluto</A>(8) -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Michael Richardson. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">SEE ALSO</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_initaddr.3.html b/doc/manpage.d/ipsec_initaddr.3.html deleted file mode 100644 index ca1f857e7..000000000 --- a/doc/manpage.d/ipsec_initaddr.3.html +++ /dev/null @@ -1,232 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_INITADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_INITADDR</H1> -Section: C Library Functions (3)<BR>Updated: 11 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec initaddr - initialize an ip_address -<BR> - -ipsec addrtypeof - get address type of an ip_address -<BR> - -ipsec addrlenof - get length of address within an ip_address -<BR> - -ipsec addrbytesof - get copy of address within an ip_address -<BR> - -ipsec addrbytesptr - get pointer to address within an ip_address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *initaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *dst);</B> - -<BR> - -<B>int addrtypeof(const ip_address *src);</B> - -<BR> - -<B>size_t addrlenof(const ip_address *src);</B> - -<BR> - -<B>size_t addrbytesof(const ip_address *src,</B> - -<BR> - -<B>unsigned char *dst, size_t dstlen);</B> - -<BR> - -<B>size_t addrbytesptr(const ip_address *src,</B> - -<BR> - -<B>const unsigned char **dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -library uses an internal type -<I>ip_address</I> - -to contain one of the (currently two) types of IP address. -These functions provide basic tools for creating and examining this type. -<P> - -<I>Initaddr</I> - -initializes a variable -<I>*dst</I> - -of type -<I>ip_address</I> - -from an address -(in network byte order, -indicated by a pointer -<I>src</I> - -and a length -<I>srclen</I>) - -and an address family -<I>af</I> - -(typically -<B>AF_INET</B> - -or -<B>AF_INET6</B>). - -The length must be consistent with the address family. -<P> - -<I>Addrtypeof</I> - -returns the address type of an address, -normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -(The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file arranges to include the necessary headers for these -names to be known.) -<P> - -<I>Addrlenof</I> - -returns the size (in bytes) of the address within an -<I>ip_address</I>, - -to permit storage allocation etc. -<P> - -<I>Addrbytesof</I> - -copies the address within the -<I>ip_address</I> - -<I>src</I> - -to the buffer indicated by the pointer -<I>dst</I> - -and the length -<I>dstlen</I>, - -and returns the address length (in bytes). -If the address will not fit, -as many bytes as will fit are copied; -the returned length is still the full length. -It is the caller's responsibility to check the -returned value to ensure that there was enough room. -<P> - -<I>Addrbytesptr</I> - -sets -<I>*dst</I> - -to a pointer to the internal address within the -<I>ip_address</I>, - -and returns the address length (in bytes). -If -<I>dst</I> - -is -<B>NULL</B>, - -it just returns the address length. -The pointer points to -<B>const</B> - -to discourage misuse. -<P> - -<I>Initaddr</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<P> - -The functions which return -<I>size_t</I> - -return -<B>0</B> - -for a failure. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -An unknown address family is a fatal error for any of these functions -except -<I>addrtypeof</I>. - -An address-size mismatch is a fatal error for -<I>initaddr</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -<I>Addrtypeof</I> - -should probably have been named -<I>addrfamilyof</I>. - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_initsaid.3.html b/doc/manpage.d/ipsec_initsaid.3.html deleted file mode 100644 index 2ba79a8ac..000000000 --- a/doc/manpage.d/ipsec_initsaid.3.html +++ /dev/null @@ -1,453 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TTOSA</TITLE> -</HEAD><BODY> -<H1>IPSEC_TTOSA</H1> -Section: C Library Functions (3)<BR>Updated: 26 Nov 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ttosa, satot - convert IPsec Security Association IDs to and from text -<BR> - -ipsec initsaid - initialize an SA ID -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>typedef struct {</B> - -<BR> - -<B>ip_address dst;</B> - -<BR> - -<B>ipsec_spi_t spi;</B> - -<BR> - -<B>int proto;</B> - -<BR> - -<B>} ip_said;</B> - -<P> -<B>const char *ttosa(const char *src, size_t srclen,</B> - -<BR> - -<B>ip_said *sa);</B> - -<BR> - -<B>size_t satot(const ip_said *sa, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<BR> - -<B>void initsaid(const ip_address *addr, ipsec_spi_t spi,</B> - -<BR> - -<B>int proto, ip_said *dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ttosa</I> - -converts an ASCII Security Association (SA) specifier into an -<B>ip_said</B> - -structure (containing -a destination-host address -in network byte order, -an SPI number in network byte order, and -a protocol code). -<I>Satot</I> - -does the reverse conversion, back to a text SA specifier. -<I>Initsaid</I> - -initializes an -<B>ip_said</B> - -from separate items of information. -<P> - -An SA is specified in text with a mail-like syntax, e.g. -<B><A HREF="mailto:esp.5a7@1.2.3.4">esp.5a7@1.2.3.4</A></B>. - -An SA specifier contains -a protocol prefix (currently -<B>ah</B>, - -<B>esp</B>, - -<B>tun</B>, - -<B>comp</B>, - -or -<B>int</B>), - -a single character indicating the address family -(<B>.</B> - -for IPv4, -<B>:</B> - -for IPv6), -an unsigned integer SPI number in hexadecimal (with no -<B>0x</B> - -prefix), -and an IP address. -The IP address can be any form accepted by -<I><A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A></I>(3), - -e.g. dotted-decimal IPv4 address, -colon-hex IPv6 address, -or DNS name. -<P> - -As a special case, the SA specifier -<B>%passthrough4</B> - -or -<B>%passthrough6</B> - -signifies the special SA used to indicate that packets should be -passed through unaltered. -(At present, these are synonyms for -<B><A HREF="mailto:tun.0@0.0.0.0">tun.0@0.0.0.0</A></B> - -and -<B>tun:0@::</B> - -respectively, -but that is subject to change without notice.) -<B>%passthrough</B> - -is a historical synonym for -<B>%passthrough4</B>. - -These forms are known to both -<I>ttosa</I> - -and -<I>satot</I>, - -so the internal representation is never visible. -<P> - -Similarly, the SA specifiers -<B>%pass</B>, - -<B>%drop</B>, - -<B>%reject</B>, - -<B>%hold</B>, - -<B>%trap</B>, - -and -<B>%trapsubnet</B> - -signify special ``magic'' SAs used to indicate that packets should be -passed, dropped, rejected (dropped with ICMP notification), -held, -and trapped (sent up to -<I><A HREF="ipsec_pluto.8.html">ipsec_pluto</A></I>(8), - -with either of two forms of -<B>%hold</B> - -automatically installed) -respectively. -These forms too are known to both routines, -so the internal representation of the magic SAs should never be visible. -<P> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file supplies the -<B>ip_said</B> - -structure, as well as a data type -<B>ipsec_spi_t</B> - -which is an unsigned 32-bit integer. -(There is no consistency between kernel and user on what such a type -is called, hence the header hides the differences.) -<P> - -The protocol code uses the same numbers that IP does. -For user convenience, given the difficulty in acquiring the exact set of -protocol names used by the kernel, -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -defines the names -<B>SA_ESP</B>, - -<B>SA_AH</B>, - -<B>SA_IPIP</B>, - -and -<B>SA_COMP</B> - -to have the same values as the kernel names -<B>IPPROTO_ESP</B>, - -<B>IPPROTO_AH</B>, - -<B>IPPROTO_IPIP</B>, - -and -<B>IPPROTO_COMP</B>. - -<P> - -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -also defines -<B>SA_INT</B> - -to have the value -<B>61</B> - -(reserved by IANA for ``any host internal protocol'') -and -<B>SPI_PASS</B>, - -<B>SPI_DROP</B>, - -<B>SPI_REJECT</B>, - -<B>SPI_HOLD</B>, - -and -<B>SPI_TRAP</B> - -to have the values 256-260 (in <I>host</I> byte order) respectively. -These are used in constructing the magic SAs -(which always have address -<B>0.0.0.0</B>). - -<P> - -If -<I>satot</I> - -encounters an unknown protocol code, e.g. 77, -it yields output using a prefix -showing the code numerically, e.g. ``unk77''. -This form is -<I>not</I> - -recognized by -<I>ttosa</I>. - -<P> - -The -<I>srclen</I> - -parameter of -<I>ttosa</I> - -specifies the length of the string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>satot</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file defines a constant, -<B>SATOT_BUF</B>, - -which is the size of a buffer just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>satot</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the ASCII character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default -(currently -lowercase protocol prefix, lowercase hexadecimal SPI, -dotted-decimal or colon-hex address). -The value -<B>'f'</B> - -is similar except that the SPI is padded with -<B>0</B>s - -to a fixed 32-bit width, to ease aligning displayed tables. -<P> - -<I>Ttosa</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<I>Satot</I> - -returns -<B>0</B> - -for a failure, and otherwise -always returns the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<P> - -There is also, temporarily, support for some obsolete -forms of SA specifier which lack the address-family indicator. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec_ttoul.3.html">ipsec_ttoul</A>(3), <A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A>(3), <A HREF="ipsec_samesaid.3.html">ipsec_samesaid</A>(3), <A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>ttosa</I> - -are: -empty input; -input too small to be a legal SA specifier; -no -<B>@</B> - -in input; -unknown protocol prefix; -conversion error in -<I>ttoul</I> - -or -<I>ttoaddr</I>. - -<P> - -Fatal errors in -<I>satot</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The restriction of text-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The text-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = ttosa( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_initsubnet.3.html b/doc/manpage.d/ipsec_initsubnet.3.html deleted file mode 100644 index e442a9100..000000000 --- a/doc/manpage.d/ipsec_initsubnet.3.html +++ /dev/null @@ -1,238 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_INITSUBNET</TITLE> -</HEAD><BODY> -<H1>IPSEC_INITSUBNET</H1> -Section: C Library Functions (3)<BR>Updated: 12 March 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec initsubnet - initialize an ip_subnet -<BR> - -ipsec addrtosubnet - initialize a singleton ip_subnet -<BR> - -ipsec subnettypeof - get address type of an ip_subnet -<BR> - -ipsec masktocount - convert subnet mask to bit count -<BR> - -ipsec networkof - get base address of an ip_subnet -<BR> - -ipsec maskof - get subnet mask of an ip_subnet -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *initsubnet(const ip_address *addr,</B> - -<BR> - -<B>int maskbits, int clash, ip_subnet *dst);</B> - -<BR> - -<B>const char *addrtosubnet(const ip_address *addr,</B> - -<BR> - -<B>ip_subnet *dst);</B> - -<P> -<B>int subnettypeof(const ip_subnet *src);</B> - -<BR> - -<B>int masktocount(const ip_address *src);</B> - -<BR> - -<B>void networkof(const ip_subnet *src, ip_address *dst);</B> - -<BR> - -<B>void maskof(const ip_subnet *src, ip_address *dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -library uses an internal type -<I>ip_subnet</I> - -to contain a description of an IP subnet -(base address plus mask). -These functions provide basic tools for creating and examining this type. -<P> - -<I>Initsubnet</I> - -initializes a variable -<I>*dst</I> - -of type -<I>ip_subnet</I> - -from a base address and -a count of mask bits. -The -<I>clash</I> - -parameter specifies what to do if the base address includes -<B>1</B> - -bits outside the prefix specified by the mask -(that is, in the ``host number'' part of the address): -<DL COMPACT><DT><DD> -<DL COMPACT> -<DT>'0'<DD> -zero out host-number bits -<DT>'x'<DD> -non-zero host-number bits are an error -</DL> -</DL> - -<P> - -<I>Initsubnet</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<P> - -<I>Addrtosubnet</I> - -initializes an -<I>ip_subnet</I> - -variable -<I>*dst</I> - -to a ``singleton subnet'' containing the single address -<I>*addr</I>. - -It returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure. -<P> - -<I>Subnettypeof</I> - -returns the address type of a subnet, -normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -(The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file arranges to include the necessary headers for these -names to be known.) -<P> - -<I>Masktocount</I> - -converts a subnet mask, expressed as an address, to a bit count -suitable for use with -<I>initsubnet</I>. - -It returns -<B>-1</B> - -for error; see DIAGNOSTICS. -<P> - -<I>Networkof</I> - -fills in -<I>*dst</I> - -with the base address of subnet -<I>src</I>. - -<P> - -<I>Maskof</I> - -fills in -<I>*dst</I> - -with the subnet mask of subnet -<I>src</I>, - -expressed as an address. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_ttosubnet.3.html">ipsec_ttosubnet</A>(3), <A HREF="ipsec_rangetosubnet.3.html">ipsec_rangetosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>initsubnet</I> - -are: -unknown address family; -unknown -<I>clash</I> - -value; -impossible mask bit count; -non-zero host-number bits and -<I>clash</I> - -is -<B>'x'</B>. - -Fatal errors in -<I>addrtosubnet</I> - -are: -unknown address family. -Fatal errors in -<I>masktocount</I> - -are: -unknown address family; -mask bits not contiguous. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_isanyaddr.3.html b/doc/manpage.d/ipsec_isanyaddr.3.html deleted file mode 100644 index 974236005..000000000 --- a/doc/manpage.d/ipsec_isanyaddr.3.html +++ /dev/null @@ -1,166 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 8 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec anyaddr - get "any" address -<BR> - -ipsec isanyaddr - test address for equality to "any" address -<BR> - -ipsec unspecaddr - get "unspecified" address -<BR> - -ipsec isunspecaddr - test address for equality to "unspecified" address -<BR> - -ipsec loopbackaddr - get loopback address -<BR> - -ipsec isloopbackaddr - test address for equality to loopback address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *anyaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isanyaddr(const ip_address *src);</B> - -<BR> - -<B>const char *unspecaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isunspecaddr(const ip_address *src);</B> - -<BR> - -<B>const char *loopbackaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isloopbackaddr(const ip_address *src);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions fill in, and test for, special values of the -<I>ip_address</I> - -type. -<P> - -<I>Anyaddr</I> - -fills in the destination -<I>*dst</I> - -with the ``any'' address of address family -<I>af</I> - -(normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>). - -The IPv4 ``any'' address is the one embodied in the old -<B>INADDR_ANY</B> - -macro. -<P> - -<I>Isanyaddr</I> - -returns -<B>1</B> - -if the -<I>src</I> - -address equals the ``any'' address, -and -<B>0</B> - -otherwise. -<P> - -Similarly, -<I>unspecaddr</I> - -supplies, and -<I>isunspecaddr</I> - -tests for, -the ``unspecified'' address, -which may be the same as the ``any'' address. -<P> - -Similarly, -<I>loopbackaddr</I> - -supplies, and -<I>islookbackaddr</I> - -tests for, -the loopback address. -<P> - -<I>Anyaddr</I>, - -<I>unspecaddr</I>, - -and -<I>loopbackaddr</I> - -return -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_addrtot.3.html">ipsec_addrtot</A>(3), <A HREF="ipsec_sameaddr.3.html">ipsec_sameaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in the address-supplying functions are: -unknown address family. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_isloopbackaddr.3.html b/doc/manpage.d/ipsec_isloopbackaddr.3.html deleted file mode 100644 index 974236005..000000000 --- a/doc/manpage.d/ipsec_isloopbackaddr.3.html +++ /dev/null @@ -1,166 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 8 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec anyaddr - get "any" address -<BR> - -ipsec isanyaddr - test address for equality to "any" address -<BR> - -ipsec unspecaddr - get "unspecified" address -<BR> - -ipsec isunspecaddr - test address for equality to "unspecified" address -<BR> - -ipsec loopbackaddr - get loopback address -<BR> - -ipsec isloopbackaddr - test address for equality to loopback address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *anyaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isanyaddr(const ip_address *src);</B> - -<BR> - -<B>const char *unspecaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isunspecaddr(const ip_address *src);</B> - -<BR> - -<B>const char *loopbackaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isloopbackaddr(const ip_address *src);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions fill in, and test for, special values of the -<I>ip_address</I> - -type. -<P> - -<I>Anyaddr</I> - -fills in the destination -<I>*dst</I> - -with the ``any'' address of address family -<I>af</I> - -(normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>). - -The IPv4 ``any'' address is the one embodied in the old -<B>INADDR_ANY</B> - -macro. -<P> - -<I>Isanyaddr</I> - -returns -<B>1</B> - -if the -<I>src</I> - -address equals the ``any'' address, -and -<B>0</B> - -otherwise. -<P> - -Similarly, -<I>unspecaddr</I> - -supplies, and -<I>isunspecaddr</I> - -tests for, -the ``unspecified'' address, -which may be the same as the ``any'' address. -<P> - -Similarly, -<I>loopbackaddr</I> - -supplies, and -<I>islookbackaddr</I> - -tests for, -the loopback address. -<P> - -<I>Anyaddr</I>, - -<I>unspecaddr</I>, - -and -<I>loopbackaddr</I> - -return -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_addrtot.3.html">ipsec_addrtot</A>(3), <A HREF="ipsec_sameaddr.3.html">ipsec_sameaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in the address-supplying functions are: -unknown address family. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_isunspecaddr.3.html b/doc/manpage.d/ipsec_isunspecaddr.3.html deleted file mode 100644 index 974236005..000000000 --- a/doc/manpage.d/ipsec_isunspecaddr.3.html +++ /dev/null @@ -1,166 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 8 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec anyaddr - get "any" address -<BR> - -ipsec isanyaddr - test address for equality to "any" address -<BR> - -ipsec unspecaddr - get "unspecified" address -<BR> - -ipsec isunspecaddr - test address for equality to "unspecified" address -<BR> - -ipsec loopbackaddr - get loopback address -<BR> - -ipsec isloopbackaddr - test address for equality to loopback address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *anyaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isanyaddr(const ip_address *src);</B> - -<BR> - -<B>const char *unspecaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isunspecaddr(const ip_address *src);</B> - -<BR> - -<B>const char *loopbackaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isloopbackaddr(const ip_address *src);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions fill in, and test for, special values of the -<I>ip_address</I> - -type. -<P> - -<I>Anyaddr</I> - -fills in the destination -<I>*dst</I> - -with the ``any'' address of address family -<I>af</I> - -(normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>). - -The IPv4 ``any'' address is the one embodied in the old -<B>INADDR_ANY</B> - -macro. -<P> - -<I>Isanyaddr</I> - -returns -<B>1</B> - -if the -<I>src</I> - -address equals the ``any'' address, -and -<B>0</B> - -otherwise. -<P> - -Similarly, -<I>unspecaddr</I> - -supplies, and -<I>isunspecaddr</I> - -tests for, -the ``unspecified'' address, -which may be the same as the ``any'' address. -<P> - -Similarly, -<I>loopbackaddr</I> - -supplies, and -<I>islookbackaddr</I> - -tests for, -the loopback address. -<P> - -<I>Anyaddr</I>, - -<I>unspecaddr</I>, - -and -<I>loopbackaddr</I> - -return -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_addrtot.3.html">ipsec_addrtot</A>(3), <A HREF="ipsec_sameaddr.3.html">ipsec_sameaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in the address-supplying functions are: -unknown address family. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:17 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_keyblobtoid.3.html b/doc/manpage.d/ipsec_keyblobtoid.3.html deleted file mode 100644 index 109cfafa7..000000000 --- a/doc/manpage.d/ipsec_keyblobtoid.3.html +++ /dev/null @@ -1,174 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_KEYBLOBTOID</TITLE> -</HEAD><BODY> -<H1>IPSEC_KEYBLOBTOID</H1> -Section: C Library Functions (3)<BR>Updated: 25 March 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec keyblobtoid, splitkeytoid - generate key IDs from RSA keys -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>size_t keyblobtoid(const unsigned char *blob,</B> - -<BR> - -<B>size_t bloblen, char *dst, size_t dstlen);</B> - -<BR> - -<B>size_t splitkeytoid(const unsigned char *e, size_t elen,</B> - -<BR> - -<B>const unsigned char *m, size_t mlen, char *dst,</B> - -<BR> - -<B>size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Keyblobtoid</I> - -and -<I>splitkeytoid</I> - -generate -key IDs -from RSA keys, -for use in messages and reporting, -writing the result to -<I>dst</I>. - -A -<I>key ID</I> - -is a short ASCII string identifying a key; -currently it is just the first nine characters of the base64 -encoding of the RFC 2537/3110 ``byte blob'' representation of the key. -(Beware that no finite key ID can be collision-proof: -there is always some small chance of two random keys having the -same ID.) -<P> - -<I>Keyblobtoid</I> - -generates a key ID from a key which is already in the form of an -RFC 2537/3110 binary key -<I>blob</I> - -(encoded exponent length, exponent, modulus). -<P> - -<I>Splitkeytoid</I> - -generates a key ID from a key given in the form of a separate -(binary) exponent -<I>e</I> - -and modulus -<I>m</I>. - -<P> - -The -<I>dstlen</I> - -parameter of either -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines a constant -<B>KEYID_BUF</B> - -which is the size of a buffer large enough for worst-case results. -<P> - -Both functions return -<B>0</B> - -for a failure, and otherwise -always return the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. - -With keys generated by -<I><A HREF="ipsec_rsasigkey.3.html">ipsec_rsasigkey</A></I>(3), - -the first two base64 digits are always the same, -and the third carries only about one bit of information. -It's worse with keys using longer fixed exponents, -e.g. the 24-bit exponent that's common in X.509 certificates. -However, being able to relate key IDs to the full -base64 text form of keys by eye is sufficiently useful that this -waste of space seems justifiable. -The choice of nine digits is a compromise between bulk and -probability of collision. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -RFC 3110, -<I>RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)</I>, -Eastlake, 2001 -(superseding the older but better-known RFC 2537). -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors are: -key too short to supply enough bits to construct a complete key ID -(almost certainly indicating a garbage key); -exponent too long for its length to be representable. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_klipsdebug.5.html b/doc/manpage.d/ipsec_klipsdebug.5.html deleted file mode 100644 index 964329256..000000000 --- a/doc/manpage.d/ipsec_klipsdebug.5.html +++ /dev/null @@ -1,229 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_KLIPSDEBUG</TITLE> -</HEAD><BODY> -<H1>IPSEC_KLIPSDEBUG</H1> -Section: File Formats (5)<BR>Updated: 26 Jun 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec_klipsdebug - list KLIPS (kernel IPSEC support) debug features and level -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>klipsdebug</B> - -<P> - -<B>cat</B> - -<B>/proc/net/ipsec_klipsdebug</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>/proc/net/ipsec_klipsdebug</I> - -lists flags that control various parts of the debugging output of Klips -(the kernel portion of FreeS/WAN IPSEC). -At this point it is a read-only file. -<P> - -A table entry consists of: -<DL COMPACT> -<DT>+<DD> -a KLIPS debug variable -<DT>+<DD> -a '=' separator for visual and automated parsing between the variable -name and its current value -<DT>+<DD> -hexadecimal bitmap of variable's flags. -</DL> -<P> - -The variable names roughly describe the scope of the debugging variable. -Currently, no flags are documented or individually accessible yet except -tunnel-xmit. - -<P> - -The variable names are: -<DL COMPACT> -<DT><B>tunnel</B> - -<DD> -tunnelling code -<DT><B>netlink</B> - -<DD> -userspace communication code (obsolete) -<DT><B>xform</B> - -<DD> -transform selection and manipulation code -<DT><B>eroute</B> - -<DD> -eroute table manipulation code -<DT><B>spi</B> - -<DD> -SA table manipulation code -<DT><B>radij</B> - -<DD> -radij tree manipulation code -<DT><B>esp</B> - -<DD> -encryptions transforms code -<DT><B>ah</B> - -<DD> -authentication transforms code -<DT><B>rcv</B> - -<DD> -receive code -<DT><B>ipcomp</B> - -<DD> -ip compression transforms code -<DT><B>verbose</B> - -<DD> -give even more information, beware this will probably trample the 4k kernel printk buffer giving inaccurate output -</DL> -<P> - -All KLIPS debug output appears as -<B>kernel.info</B> - -messages to -<I><A HREF="syslogd.8.html">syslogd</A></I>(8). - -Most systems are set up -to log these messages to -<I>/var/log/messages</I>. - -<P> - -<A NAME="lbAE"> </A> -<H2>EXAMPLES</H2> - -<P> - -<B>debug_tunnel=00000010.</B> - -<BR> - -<B>debug_netlink=00000000.</B> - -<BR> - -<B>debug_xform=00000000.</B> - -<BR> - -<B>debug_eroute=00000000.</B> - -<BR> - -<B>debug_spi=00000000.</B> - -<BR> - -<B>debug_radij=00000000.</B> - -<BR> - -<B>debug_esp=00000000.</B> - -<BR> - -<B>debug_ah=00000000.</B> - -<BR> - -<B>debug_rcv=00000000.</B> - -<BR> - -<B>debug_pfkey=ffffffff.</B> - -<P> - -means that one -<B>tunnel</B> - -flag has been set (tunnel-xmit), -full -<B>pfkey</B> - -sockets debugging has been set and everything else is not set. -<P> - -<A NAME="lbAF"> </A> -<H2>FILES</H2> - -/proc/net/ipsec_klipsdebug, /usr/local/bin/ipsec -<A NAME="lbAG"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A>(8), <A HREF="ipsec_eroute.8.html">ipsec_eroute</A>(8), -<A HREF="ipsec_spi.8.html">ipsec_spi</A>(8), <A HREF="ipsec_spigrp.8.html">ipsec_spigrp</A>(8), <A HREF="ipsec_klipsdebug.5.html">ipsec_klipsdebug</A>(5), <A HREF="ipsec_version.5.html">ipsec_version</A>(5), -<A HREF="ipsec_pf_key.5.html">ipsec_pf_key</A>(5) -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Richard Guy Briggs. - - - - - - - - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">EXAMPLES</A><DD> -<DT><A HREF="#lbAF">FILES</A><DD> -<DT><A HREF="#lbAG">SEE ALSO</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_klipsdebug.8.html b/doc/manpage.d/ipsec_klipsdebug.8.html deleted file mode 100644 index 67b1c3a5d..000000000 --- a/doc/manpage.d/ipsec_klipsdebug.8.html +++ /dev/null @@ -1,264 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_KLIPSDEBUG</TITLE> -</HEAD><BODY> -<H1>IPSEC_KLIPSDEBUG</H1> -Section: Maintenance Commands (8)<BR>Updated: 21 Jun 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec klipsdebug - set KLIPS (kernel IPSEC support) debug features and level -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>klipsdebug</B> - -<P> - -<B>ipsec</B> - -<B>klipsdebug</B> - -<B>--set</B> - -flagname -<P> - -<B>ipsec</B> - -<B>klipsdebug</B> - -<B>--clear</B> - -flagname -<P> - -<B>ipsec</B> - -<B>klipsdebug</B> - -<B>--all</B> - -<P> - -<B>ipsec</B> - -<B>klipsdebug</B> - -<B>--none</B> - -<P> - -<B>ipsec</B> - -<B>klipsdebug</B> - -<B>--help</B> - -<P> - -<B>ipsec</B> - -<B>klipsdebug</B> - -<B>--version</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Klipsdebug</I> - -sets and clears flags that control -various parts of the debugging output of Klips -(the kernel portion of FreeS/WAN IPSEC). -The form with no additional arguments lists the present contents of -/proc/net/ipsec_klipsdebug. -The -<B>--set</B> - -form turns the specified flag on, -while the -<B>--clear</B> - -form turns the specified flag off. -The -<B>--all</B> - -form -turns all flags on except verbose, while the -<B>--none</B> - -form turns all flags off. -<P> - -The current flag names are: -<DL COMPACT> -<DT><B>tunnel</B> - -<DD> -tunnelling code -<DT><B>tunnel-xmit</B> - -<DD> -tunnelling transmit only code -<DT><B>pfkey</B> - -<DD> -userspace communication code -<DT><B>xform</B> - -<DD> -transform selection and manipulation code -<DT><B>eroute</B> - -<DD> -eroute table manipulation code -<DT><B>spi</B> - -<DD> -SA table manipulation code -<DT><B>radij</B> - -<DD> -radij tree manipulation code -<DT><B>esp</B> - -<DD> -encryptions transforms code -<DT><B>ah</B> - -<DD> -authentication transforms code -<B>rcv</B> - -receive code -<DT><B>ipcomp</B> - -<DD> -ip compression transforms code -<DT><B>verbose</B> - -<DD> -give even more information, BEWARE: -a)this will print authentication and encryption keys in the logs -b)this will probably trample the 4k kernel printk buffer giving inaccurate output -</DL> -<P> - -All Klips debug output appears as -<B>kernel.info</B> - -messages to -<I><A HREF="syslogd.8.html">syslogd</A></I>(8). - -Most systems are set up -to log these messages to -<I>/var/log/messages</I>. - -Beware that -<B>klipsdebug</B> - -<B>--all</B> - -produces a lot of output and the log file will grow quickly. -<P> - -The file format for /proc/net/ipsec_klipsdebug is discussed in -<A HREF="ipsec_klipsdebug.5.html">ipsec_klipsdebug</A>(5). -<A NAME="lbAE"> </A> -<H2>EXAMPLES</H2> - -<DL COMPACT> -<DT><B>klipsdebug --all</B> - -<DD> -turns on all KLIPS debugging except verbose. -<DT><B>klipsdebug --clear tunnel</B> - -<DD> -turns off only the -<B>tunnel</B> - -debugging messages. -</DL> -<P> - -<A NAME="lbAF"> </A> -<H2>FILES</H2> - -/proc/net/ipsec_klipsdebug, /usr/local/bin/ipsec -<A NAME="lbAG"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A>(8), <A HREF="ipsec_eroute.8.html">ipsec_eroute</A>(8), -<A HREF="ipsec_spi.8.html">ipsec_spi</A>(8), <A HREF="ipsec_spigrp.8.html">ipsec_spigrp</A>(8), <A HREF="ipsec_klipsdebug.5.html">ipsec_klipsdebug</A>(5) -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Richard Guy Briggs. -<A NAME="lbAI"> </A> -<H2>BUGS</H2> - -It really ought to be possible to set or unset selective combinations -of flags. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">EXAMPLES</A><DD> -<DT><A HREF="#lbAF">FILES</A><DD> -<DT><A HREF="#lbAG">SEE ALSO</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -<DT><A HREF="#lbAI">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_look.8.html b/doc/manpage.d/ipsec_look.8.html deleted file mode 100644 index ffe07a57c..000000000 --- a/doc/manpage.d/ipsec_look.8.html +++ /dev/null @@ -1,76 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of look</TITLE> -</HEAD><BODY> -<H1>look</H1> -Section: Maintenance Commands (8)<BR>Updated: 25 Apr 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec look - get a quick summary of FreeS/WAN status -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<I>look</I> - -is used to get a quick overview of what the status of FreeSWAN is. -It is equivalent to: - ipsec eroute -<P> - ipsec spigrp -<P> - ipsec tncfg -<P> - ipsec spi -<P> - netstat -rn -<P> -<P> - -However a bit of processing is done to combine the outputs. -<A NAME="lbAD"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A>(8), <A HREF="ipsec_spi.8.html">ipsec_spi</A>(8), <A HREF="ipsec_spigrp.8.html">ipsec_spigrp</A>(8), <A HREF="ipsec_eroute.5.html">ipsec_eroute</A>(5), -<A HREF="netstat.8.html">netstat</A>(8). -<A NAME="lbAE"> </A> -<H2>HISTORY</H2> - -Man page written for the Linux FreeS/WAN project <<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael Richardson. Original program written by Henry Spencer. - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">SEE ALSO</A><DD> -<DT><A HREF="#lbAE">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_loopbackaddr.3.html b/doc/manpage.d/ipsec_loopbackaddr.3.html deleted file mode 100644 index 92f69d99c..000000000 --- a/doc/manpage.d/ipsec_loopbackaddr.3.html +++ /dev/null @@ -1,166 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 8 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec anyaddr - get "any" address -<BR> - -ipsec isanyaddr - test address for equality to "any" address -<BR> - -ipsec unspecaddr - get "unspecified" address -<BR> - -ipsec isunspecaddr - test address for equality to "unspecified" address -<BR> - -ipsec loopbackaddr - get loopback address -<BR> - -ipsec isloopbackaddr - test address for equality to loopback address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *anyaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isanyaddr(const ip_address *src);</B> - -<BR> - -<B>const char *unspecaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isunspecaddr(const ip_address *src);</B> - -<BR> - -<B>const char *loopbackaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isloopbackaddr(const ip_address *src);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions fill in, and test for, special values of the -<I>ip_address</I> - -type. -<P> - -<I>Anyaddr</I> - -fills in the destination -<I>*dst</I> - -with the ``any'' address of address family -<I>af</I> - -(normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>). - -The IPv4 ``any'' address is the one embodied in the old -<B>INADDR_ANY</B> - -macro. -<P> - -<I>Isanyaddr</I> - -returns -<B>1</B> - -if the -<I>src</I> - -address equals the ``any'' address, -and -<B>0</B> - -otherwise. -<P> - -Similarly, -<I>unspecaddr</I> - -supplies, and -<I>isunspecaddr</I> - -tests for, -the ``unspecified'' address, -which may be the same as the ``any'' address. -<P> - -Similarly, -<I>loopbackaddr</I> - -supplies, and -<I>islookbackaddr</I> - -tests for, -the loopback address. -<P> - -<I>Anyaddr</I>, - -<I>unspecaddr</I>, - -and -<I>loopbackaddr</I> - -return -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_addrtot.3.html">ipsec_addrtot</A>(3), <A HREF="ipsec_sameaddr.3.html">ipsec_sameaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in the address-supplying functions are: -unknown address family. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_lwdnsq.8.html b/doc/manpage.d/ipsec_lwdnsq.8.html deleted file mode 100644 index 1122b188a..000000000 --- a/doc/manpage.d/ipsec_lwdnsq.8.html +++ /dev/null @@ -1,400 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC LWDNSQ</TITLE> -</HEAD><BODY> -<H1>IPSEC LWDNSQ</H1> -Section: (8)<BR>Updated: <BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -lwdnsq - lookup items in DNS to help pluto (and others) -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<P> -<PRE> -<B>ipsec lwdnsq</B> lwdnsq [<B>--prompt</B>] [<B>--serial</B>] -</PRE> - -<P> -<PRE> -<B>ipsec lwdnsq</B> lwdnsq [<B>--help</B>] -</PRE> - -<P> -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<P> -<P> - -The <B>ipsec lwdnsq</B> is a helper program that does DNS lookups for other programs. It implements an asynchronous interface on stdin/stdout, with an ASCII driven command language. -<P> -<P> - -If stdin is a tty or if the <B>--prompt</B> option is given, then it issues a prompt to the user. Otherwise, it is silent, except for results. -<P> -<P> - -The program will accept multiple queries concurrently, with each result being marked with the ID provided on the output. The IDs are strings. -<P> -<P> - -If the <B>--serial</B> option is given, then the program will not attempt to execute concurrent queries, but will serialize all input and output. -<P> -<A NAME="lbAE"> </A> -<H2>QUERY LANGUAGE</H2> - -<P> -<P> - -There are eleven command that the program understands. This is to lookup different types of records in both the forward and reverse maps. Every query includes a queryid, which is returned in the output, on every single line to identify the transaction. -<P> -<A NAME="lbAF"> </A> -<H3>KEY queryid FQDN</H3> - -<P> -<P> - -This request looks up the KEY resource record for the given <B>FQDN.</B>. -<P> -<A NAME="lbAG"> </A> -<H3>KEY4 queryid A.B.C.D</H3> - -<P> -<P> - -This request looks up the KEY resource record found in the reverse map for the IP version 4 address <B>A.B.C.D</B>, i.e. it looks up D.C.B.A.in-addr.arpa. -<P> -<A NAME="lbAH"> </A> -<H3>KEY6 queryid A:B::C:D</H3> - -<P> -<P> - -This request looks up the KEY resource record found in the reverse map for the IPv6 address <B>A:B::C:D</B>, i.e. it looks the 32-nibble long entry in ip6.arpa (and ip6.int). -<P> -<A NAME="lbAI"> </A> -<H3>TXT4 queryid A.B.C.D</H3> - -<P> -<P> - -This request looks up the TXT resource record found in the reverse map for the IP version 4 address <B>A.B.C.D</B>, i.e. it looks up D.C.B.A.in-addr.arpa. -<P> -<A NAME="lbAJ"> </A> -<H3>TXT6 queryid A:B::C:D</H3> - -<P> -<P> - -This request looks up the TXT resource record found in the reverse map for the IPv6 address <B>A:B::C:D</B>, i.e. it looks the 32-nibble long entry in ip6.arpa (and ip6.int). -<P> -<A NAME="lbAK"> </A> -<H3>KEY queryid FQDN</H3> - -<P> -<P> - -This request looks up the IPSECKEY resource record for the given <B>FQDN.</B>. See note about IPSECKEY processing, below. -<P> -<A NAME="lbAL"> </A> -<H3>IPSECKEY4 queryid A.B.C.D</H3> - -<P> -<P> - -This request looks up the IPSECKEY resource record found in the reverse map for the IP version 4 address <B>A.B.C.D</B>, i.e. it looks up D.C.B.A.in-addr.arpa. See special note about IPSECKEY processing, below. -<P> -<A NAME="lbAM"> </A> -<H3>IPSECKEY6 queryid A:B::C:D</H3> - -<P> -<P> - -This request looks up the IPSECKEY resource record found in the reverse map for the IPv6 address <B>A:B::C:D</B>, i.e. it looks the 32-nibble long entry in ip6.arpa (and ip6.int). See special note about IPSECKEY processing, below. -<P> -<A NAME="lbAN"> </A> -<H3>OE4 queryid A.B.C.D</H3> - -<P> -<P> - -This request looks an appropriate record for Opportunistic Encryption for the given IP address. This attempts to look for the delegation record. This may be one of IPSECKEY, KEY, or TXT record. Unless configured otherwise, (see OE4 Directives, below), then a query type of ANY will be used to retrieve all relevant records, and all will be returned. -<P> -<A NAME="lbAO"> </A> -<H3>OE6 queryid A:B::C:D</H3> - -<P> -<P> - -This request looks an appropriate record for Opportunistic Encryption for the given IPv6 address. This attempts to look for the delegation record. This may be one of IPSECKEY, KEY, or TXT record. Unless configured otherwise, (see OE Directives, below), then a query type of ALL will be used to retrieve all relevant records, and all will be returned. i.e. it looks the 32-nibble long entry in ip6.arpa (and ip6.int). -<P> -<A NAME="lbAP"> </A> -<H3>A queryid FQDN</H3> - -<P> -<P> - -This request looks up the A (IPv4) resource record for the given <B>FQDN.</B>. -<P> -<A NAME="lbAQ"> </A> -<H3>AAAA queryid FQDN</H3> - -<P> -<P> - -This request looks up the AAAA (IPv6) resource record for the given <B>FQDN.</B>. -<P> -<A NAME="lbAR"> </A> -<H2>REPLIES TO QUERIES</H2> - -<P> -<P> - -All replies from the queries are in the following format: -<P> -<PRE> - -<ID> <TIME> <TTL> <TYPE> <TYPE-SPECIFIC> \n - -</PRE> - -<BR> -<P> -<DL COMPACT> -<DT><I>ID</I><DD> -this is the <B>queryid</B> value that was provided in the query. It is repeated on every line to permit the replies to be properly associated with the query. When the response is not ascribable to particular query (such as for a mis-formed query), then the query ID "0" will be used. -<P> -<DT><I>TIME</I><DD> -this is the current time in seconds since epoch. -<P> -<DT><I>TTL</I><DD> -for answers which have a time to live, this is the current value. The answer is valid for this number of seconds. If there is no useful value here, then the number 0 is used. -<P> -<DT><I>TYPE</I><DD> -This is the type of the record that is being returned. The types are described in the next section. The TYPE specific data that follows is specific to the type. -<BR> -<P> -</DL> -<P> - -The replies are limited to 4096 bytes, a value defined as <B>LWDNSQ_RESULT_LEN_MAX</B>. This is defined in <I>freeswan.h</I>. -<P> -<P> - -All of the replies which include resource records use the standard presentation format (with no line feeds or carriage returns) in their answer. -<P> -<A NAME="lbAS"> </A> -<H3>START</H3> - -<P> -<P> - -This reply indicates that a query has been received and has been started. It serves as an anchor point for timing, as well as an acknowledgement. -<P> -<A NAME="lbAT"> </A> -<H3>DONE</H3> - -<P> -<P> - -This reply indicates that a query is entirely over, and no further information from this query will be sent. -<P> -<A NAME="lbAU"> </A> -<H3>RETRY</H3> - -<P> -<P> - -This reply indicates that a query is entirely over, but that no data was found. The records may exist, but appropriate servers could not be reached. -<P> -<A NAME="lbAV"> </A> -<H3>FATAL</H3> - -<P> -<P> - -This reply indicates that a query is entirely over, and that no data of the type requested could be found. There were no timeouts, and all servers were available and confirmed non-existances. There may be NXT records returned prior to this. -<P> -<A NAME="lbAW"> </A> -<H3>CNAME</H3> - -<P> -<P> - -This is an interim reply, and indicates that a CNAME was found (and followed) while performing the query. The value of the CNAME is present in the type specific section. -<P> -<A NAME="lbAX"> </A> -<H3>CNAMEFROM</H3> - -<P> -<P> - -This is an interim reply, and indicates that a CNAME was found. The original name that was queries for was not the canonical name, and this reply indicates the name that was actually followed. -<P> -<A NAME="lbAY"> </A> -<H3>NAME</H3> - -<P> -<P> - -This is an interim reply. The original name that was queries for was not the canonical name. This reply indicates the canonical name. -<P> -<A NAME="lbAZ"> </A> -<H3>DNSSEC</H3> - -<P> -<P> - -This is an interim reply. It is followed either by "OKAY" or "not present. It indicates if DNSSEC was available on the reply. -<P> -<A NAME="lbBA"> </A> -<H3>TXT and AD-TXT</H3> - -<P> -<P> - -This is an interim reply. If there are TXT resource records in the reply, then each one is presented using this type. If preceeded by AD-, then this record was signed with DNSSEC. -<P> -<A NAME="lbBB"> </A> -<H3>A and AD-A</H3> - -<P> -<P> - -This is an interim reply. If there are A resource records in the reply, then each one is presented using this type. If preceeded by AD-, then this record was signed with DNSSEC. -<P> -<A NAME="lbBC"> </A> -<H3>AAAA and AD-AAAA</H3> - -<P> -<P> - -This is an interim reply. If there are AAAA resource records in the reply, then each one is presented using this type. If preceeded by AD-, then this record was signed with DNSSEC. -<P> -<A NAME="lbBD"> </A> -<H3>PTR and AD-PTR</H3> - -<P> -<P> - -This is an interim reply. If there are PTR resource records in the reply, then each one is presented using this type. If preceeded by AD-, then this record was signed with DNSSEC. -<P> -<A NAME="lbBE"> </A> -<H3>KEY and AD-KEY</H3> - -<P> -<P> - -This is an interim reply. If there are KEY resource records in the reply, then each one is presented using this type. If preceeded by AD-, then this record was signed with DNSSEC. -<P> -<A NAME="lbBF"> </A> -<H3>IPSECKEY and AD-IPSECKEY</H3> - -<P> -<P> - -This is an interim reply. If there are IPSEC resource records in the reply, then each one is presented using this type. If preceeded by AD-, then this record was signed with DNSSEC. -<P> -<A NAME="lbBG"> </A> -<H2>SPECIAL IPSECKEY PROCESSING</H2> - -<P> -<P> - -At the time of this writing, the IPSECKEY resource record is not entirely specified. In particular no resource record number has been assigned. This program assumes that it is resource record number 45. If the file /etc/ipsec.d/lwdnsq.conf exists, and contains a line like -<P> -<PRE> - -ipseckey_rr=<B>number</B> - -</PRE> - -<BR> then this number will be used instead. The file is read only once at startup. -<P> -<A NAME="lbBH"> </A> -<H2>OE DIRECTIVES</H2> - -<P> -<P> - -If the file /etc/ipsec.d/lwdnsq.conf exists, and contains a line like -<P> -<PRE> - -queryany=false - -</PRE> - -<BR> then instead of doing an ALL query when looking for OE delegation records, lwdnsq will do a series of queries. It will first look for IPSECKEY, and then TXT record. If it finds neither, it will then look for KEY records of all kinds, although they do not contain delegation information. -<P> -<A NAME="lbBI"> </A> -<H2>SPECIAL IPSECKEY PROCESSING</H2> - -<P> -<PRE> - -/etc/ipsec.d/lwdnsq.conf - -</PRE> - -<P> -<A NAME="lbBJ"> </A> -<H2>AUTHOR</H2> - -Michael Richardson <<A HREF="mailto:mcr@sandelman.ottawa.on.ca">mcr@sandelman.ottawa.on.ca</A>>. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">QUERY LANGUAGE</A><DD> -<DL> -<DT><A HREF="#lbAF">KEY queryid FQDN</A><DD> -<DT><A HREF="#lbAG">KEY4 queryid A.B.C.D</A><DD> -<DT><A HREF="#lbAH">KEY6 queryid A:B::C:D</A><DD> -<DT><A HREF="#lbAI">TXT4 queryid A.B.C.D</A><DD> -<DT><A HREF="#lbAJ">TXT6 queryid A:B::C:D</A><DD> -<DT><A HREF="#lbAK">KEY queryid FQDN</A><DD> -<DT><A HREF="#lbAL">IPSECKEY4 queryid A.B.C.D</A><DD> -<DT><A HREF="#lbAM">IPSECKEY6 queryid A:B::C:D</A><DD> -<DT><A HREF="#lbAN">OE4 queryid A.B.C.D</A><DD> -<DT><A HREF="#lbAO">OE6 queryid A:B::C:D</A><DD> -<DT><A HREF="#lbAP">A queryid FQDN</A><DD> -<DT><A HREF="#lbAQ">AAAA queryid FQDN</A><DD> -</DL> -<DT><A HREF="#lbAR">REPLIES TO QUERIES</A><DD> -<DL> -<DT><A HREF="#lbAS">START</A><DD> -<DT><A HREF="#lbAT">DONE</A><DD> -<DT><A HREF="#lbAU">RETRY</A><DD> -<DT><A HREF="#lbAV">FATAL</A><DD> -<DT><A HREF="#lbAW">CNAME</A><DD> -<DT><A HREF="#lbAX">CNAMEFROM</A><DD> -<DT><A HREF="#lbAY">NAME</A><DD> -<DT><A HREF="#lbAZ">DNSSEC</A><DD> -<DT><A HREF="#lbBA">TXT and AD-TXT</A><DD> -<DT><A HREF="#lbBB">A and AD-A</A><DD> -<DT><A HREF="#lbBC">AAAA and AD-AAAA</A><DD> -<DT><A HREF="#lbBD">PTR and AD-PTR</A><DD> -<DT><A HREF="#lbBE">KEY and AD-KEY</A><DD> -<DT><A HREF="#lbBF">IPSECKEY and AD-IPSECKEY</A><DD> -</DL> -<DT><A HREF="#lbBG">SPECIAL IPSECKEY PROCESSING</A><DD> -<DT><A HREF="#lbBH">OE DIRECTIVES</A><DD> -<DT><A HREF="#lbBI">SPECIAL IPSECKEY PROCESSING</A><DD> -<DT><A HREF="#lbBJ">AUTHOR</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_mailkey.8.html b/doc/manpage.d/ipsec_mailkey.8.html deleted file mode 100644 index 83a532563..000000000 --- a/doc/manpage.d/ipsec_mailkey.8.html +++ /dev/null @@ -1,97 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_MAILKEY</TITLE> -</HEAD><BODY> -<H1>IPSEC_MAILKEY</H1> -Section: Maintenance Commands (8)<BR>Updated: 21 Feb 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec mailkey - mail DNS records for Opportunistic Encryption -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>mailkey</B> - ---me -<A HREF="mailto:my@address.tld">my@address.tld</A> -[ -<B>--reverse</B> - -1.2.3.4 -] [ -<B>--forward</B> - -hostname.domain.tld -] -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>mailkey</I> - -is a meta-program. It generates a script which will attempt to mail the TXT -records required to enable Opportunistic Encryption (OE). -<P> - -An e-mail address for the domain's DNS administrator is derived from SOA records. -The mail body and destination address are freely editable in the script. -<P> - -If no administrator can be located, the output file will not be executable. -<P> - -<DL COMPACT> -<DT><B>--me</B> <I><A HREF="mailto:my@address.tld">my@address.tld</A></I><DD> -set the Reply-To: address of the mail to be sent. -<DT><B>--forward</B> <I>hostname.domain.tld</I><DD> -the domain name to be used for initator-only OE. -<DT><B>--reverse</B> <I>1.2.3.4</I><DD> -the IP address to be used for full Opportunistic Encryption. -</DL> -<P> - -Only one of --forward or --reverse may be specified. -<A NAME="lbAE"> </A> -<H2>FILES</H2> - -<PRE> -/etc/ipsec.secrets -</PRE> - -<A NAME="lbAF"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec_showhostkey.8.html">ipsec_showhostkey</A>(8), <A HREF="host.8.html">host</A>(8) -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project <<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> by Sam Sgro. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -May produce indeterminate results when processing non-routable IPs. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">SEE ALSO</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_manual.8.html b/doc/manpage.d/ipsec_manual.8.html deleted file mode 100644 index 77134f7d0..000000000 --- a/doc/manpage.d/ipsec_manual.8.html +++ /dev/null @@ -1,414 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_MANUAL</TITLE> -</HEAD><BODY> -<H1>IPSEC_MANUAL</H1> -Section: Maintenance Commands (8)<BR>Updated: 17 July 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec manual - take manually-keyed IPsec connections up and down -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>manual</B> - -[ -<B>--show</B> - -] [ -<B>--showonly</B> - -] [ -<B>--other</B> - -] -<BR> - - [ -<B>--iam</B> - -address<B>@</B>interface - -] [ -<B>--config</B> - -configfile -] -<BR> - - operation connection -<P> -<B>ipsec</B> - -<B>manual</B> - -[ -<I>options</I> - -] -<B>--union</B> - -operation part ... -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Manual</I> - -manipulates manually-keyed FreeS/WAN IPsec connections, -setting them up and shutting them down, -based on the information in the IPsec configuration file. -In the normal usage, -<I>connection</I> - -is the name of a connection specification in the configuration file; -<I>operation</I> - -is -<B>--up</B>, - -<B>--down</B>, - -<B>--route</B>, - -or -<B>--unroute</B>. - -<I>Manual</I> - -generates setup (<B>--route</B> - -or -<B>--up</B>) - -or -teardown (<B>--down</B> - -or -<B>--unroute</B>) - -commands for the connection and feeds them to a shell for execution. -<P> - -The -<B>--up</B> - -operation brings the specified connection up, including establishing a -suitable route for it if necessary. -<P> - -The -<B>--route</B> - -operation just establishes the route for a connection. -Unless and until an -<B>--up</B> - -operation is done, packets routed by that route will simply be discarded. -<P> - -The -<B>--down</B> - -operation tears the specified connection down, -<I>except</I> - -that it leaves the route in place. -Unless and until an -<B>--unroute</B> - -operation is done, packets routed by that route will simply be discarded. -This permits establishing another connection to the same destination -without any ``window'' in which packets can pass without encryption. -<P> - -The -<B>--unroute</B> - -operation (and only the -<B>--unroute</B> - -operation) deletes any route established for a connection. -<P> - -In the -<B>--union</B> - -usage, each -<I>part</I> - -is the name of a partial connection specification in the configuration file, -and the union of all the partial specifications is the -connection specification used. -The effect is as if the contents of the partial specifications were -concatenated together; -restrictions on duplicate parameters, etc., do apply to the result. -(The same effect can now be had, more gracefully, using the -<B>also</B> - -parameter in connection descriptions; -see -<I><A HREF="ipsec.conf.5.html">ipsec.conf</A></I>(5) - -for details.) -<P> - -The -<B>--show</B> - -option turns on the -<B>-x</B> - -option of the shell used to execute the commands, -so each command is shown as it is executed. -<P> - -The -<B>--showonly</B> - -option causes -<I>manual</I> - -to show the commands it would run, on standard output, -and not run them. -<P> - -The -<B>--other</B> - -option causes -<I>manual</I> - -to pretend it is the other end of the connection. -This is probably not useful except in combination with -<B>--showonly</B>. - -<P> - -The -<B>--iam</B> - -option causes -<I>manual</I> - -to believe it is running on the host with the specified IP -<I>address</I>, - -and that it should use the specified -<I>interface</I> - -(normally it determines all this automatically, -based on what IPsec interfaces are up and how they are configured). -<P> - -The -<B>--config</B> - -option specifies a non-standard location for the FreeS/WAN IPsec -configuration file (default -<I>/etc/ipsec.conf</I>). - -<P> - -See -<I><A HREF="ipsec.conf.5.html">ipsec.conf</A></I>(5) - -for details of the configuration file. -Apart from the basic parameters which specify the endpoints and routing -of a connection (<B>left</B> -and -<B>right</B>, - -plus possibly -<B>leftsubnet</B>, - -<B>leftnexthop</B>, - -<B>leftfirewall</B>, - -their -<B>right</B> - -equivalents, -and perhaps -<B>type</B>), - -a non-<B>passthrough</B> -<I>manual</I> - -connection needs an -<B>spi</B> - -or -<B>spibase</B> - -parameter and some parameters specifying encryption, authentication, or -both, most simply -<B>esp</B>, - -<B>espenckey</B>, - -and -<B>espauthkey</B>. - -Moderately-secure keys can be obtained from -<I><A HREF="ipsec_ranbits.8.html">ipsec_ranbits</A></I>(8). - -For production use of manually-keyed connections, -it is strongly recommended that the keys be kept in a separate file -(with permissions -<B>rw-------</B>) - -using the -<B>include</B> - -and -<B>also</B> - -facilities of the configuration file (see -<I><A HREF="ipsec.conf.5.html">ipsec.conf</A></I>(5)). - -<P> - -If an -<B>spi</B> - -parameter is given, -<I>manual</I> - -uses that value as the SPI number for all the SAs -(which are in separate number spaces anyway). -If an -<B>spibase</B> - -parameter is given instead, -<I>manual</I> - -assigns SPI values by altering the bottom digit -of that value; -SAs going from left to right get even digits starting at 0, -SAs going from right to left get odd digits starting at 1. -Either way, it is suggested that manually-keyed connections use -three-digit SPIs with the first digit non-zero, -i.e. in the range -<B>0x100</B> - -through -<B>0xfff</B>; - -FreeS/WAN reserves those for manual keying and will not -attempt to use them for automatic keying (unless requested to, -presumably by a non-FreeS/WAN other end). -<A NAME="lbAE"> </A> -<H2>FILES</H2> - - - -/etc/ipsec.conf<TT> </TT>default IPsec configuration file<BR> -<BR> - -/var/run/ipsec.info<TT> </TT><B>%defaultroute</B> information<BR> -<A NAME="lbAF"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec.conf.5.html">ipsec.conf</A>(5), <A HREF="ipsec_spi.8.html">ipsec_spi</A>(8), <A HREF="ipsec_eroute.8.html">ipsec_eroute</A>(8), <A HREF="ipsec_spigrp.8.html">ipsec_spigrp</A>(8), -<A HREF="route.8.html">route</A>(8) -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -It's not nearly as generous about the syntax of subnets, -addresses, etc. as the usual FreeS/WAN user interfaces. -Four-component dotted-decimal must be used for all addresses. -It -<I>is</I> - -smart enough to translate bit-count netmasks to dotted-decimal form. -<P> - -If the connection specification for a connection is changed between an -<B>--up</B> - -and the ensuing -<B>--down</B>, - -chaos may ensue. -<P> - -The -<B>--up</B> - -operation is not smart enough to notice whether the connection is already up. -<P> - -<I>Manual</I> - -is not smart enough to reject insecure combinations of algorithms, -e.g. encryption with no authentication at all. -<P> - -Any non-IPsec route to the other end which is replaced by the -<B>--up</B> - -or -<B>--route</B> - -operation will not be re-established by -<B>--unroute</B>. - -Whether this is a feature or a bug depends on your viewpoint. -<P> - -The optional parameters which -override the automatic -<B>spibase</B>-based - -SPI assignment are a messy area of the code and bugs are likely. -<P> - -``Road warrior'' handling, -and other special forms of setup which -require negotiation between the two security gateways, -inherently cannot be done with -<I>manual</I>. - -<P> - -<I>Manual</I> - -generally lags behind -<I>auto</I> - -in support of various features, -even when implementation <I>would</I> be possible. -For example, currently it does not do IPComp content compression. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">SEE ALSO</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_maskof.3.html b/doc/manpage.d/ipsec_maskof.3.html deleted file mode 100644 index ea0f83f82..000000000 --- a/doc/manpage.d/ipsec_maskof.3.html +++ /dev/null @@ -1,238 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_INITSUBNET</TITLE> -</HEAD><BODY> -<H1>IPSEC_INITSUBNET</H1> -Section: C Library Functions (3)<BR>Updated: 12 March 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec initsubnet - initialize an ip_subnet -<BR> - -ipsec addrtosubnet - initialize a singleton ip_subnet -<BR> - -ipsec subnettypeof - get address type of an ip_subnet -<BR> - -ipsec masktocount - convert subnet mask to bit count -<BR> - -ipsec networkof - get base address of an ip_subnet -<BR> - -ipsec maskof - get subnet mask of an ip_subnet -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *initsubnet(const ip_address *addr,</B> - -<BR> - -<B>int maskbits, int clash, ip_subnet *dst);</B> - -<BR> - -<B>const char *addrtosubnet(const ip_address *addr,</B> - -<BR> - -<B>ip_subnet *dst);</B> - -<P> -<B>int subnettypeof(const ip_subnet *src);</B> - -<BR> - -<B>int masktocount(const ip_address *src);</B> - -<BR> - -<B>void networkof(const ip_subnet *src, ip_address *dst);</B> - -<BR> - -<B>void maskof(const ip_subnet *src, ip_address *dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -library uses an internal type -<I>ip_subnet</I> - -to contain a description of an IP subnet -(base address plus mask). -These functions provide basic tools for creating and examining this type. -<P> - -<I>Initsubnet</I> - -initializes a variable -<I>*dst</I> - -of type -<I>ip_subnet</I> - -from a base address and -a count of mask bits. -The -<I>clash</I> - -parameter specifies what to do if the base address includes -<B>1</B> - -bits outside the prefix specified by the mask -(that is, in the ``host number'' part of the address): -<DL COMPACT><DT><DD> -<DL COMPACT> -<DT>'0'<DD> -zero out host-number bits -<DT>'x'<DD> -non-zero host-number bits are an error -</DL> -</DL> - -<P> - -<I>Initsubnet</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<P> - -<I>Addrtosubnet</I> - -initializes an -<I>ip_subnet</I> - -variable -<I>*dst</I> - -to a ``singleton subnet'' containing the single address -<I>*addr</I>. - -It returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure. -<P> - -<I>Subnettypeof</I> - -returns the address type of a subnet, -normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -(The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file arranges to include the necessary headers for these -names to be known.) -<P> - -<I>Masktocount</I> - -converts a subnet mask, expressed as an address, to a bit count -suitable for use with -<I>initsubnet</I>. - -It returns -<B>-1</B> - -for error; see DIAGNOSTICS. -<P> - -<I>Networkof</I> - -fills in -<I>*dst</I> - -with the base address of subnet -<I>src</I>. - -<P> - -<I>Maskof</I> - -fills in -<I>*dst</I> - -with the subnet mask of subnet -<I>src</I>, - -expressed as an address. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_ttosubnet.3.html">ipsec_ttosubnet</A>(3), <A HREF="ipsec_rangetosubnet.3.html">ipsec_rangetosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>initsubnet</I> - -are: -unknown address family; -unknown -<I>clash</I> - -value; -impossible mask bit count; -non-zero host-number bits and -<I>clash</I> - -is -<B>'x'</B>. - -Fatal errors in -<I>addrtosubnet</I> - -are: -unknown address family. -Fatal errors in -<I>masktocount</I> - -are: -unknown address family; -mask bits not contiguous. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_masktobits.3.html b/doc/manpage.d/ipsec_masktobits.3.html deleted file mode 100644 index 6eccdd8d5..000000000 --- a/doc/manpage.d/ipsec_masktobits.3.html +++ /dev/null @@ -1,122 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_GOODMASK</TITLE> -</HEAD><BODY> -<H1>IPSEC_GOODMASK</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec goodmask - is this Internet subnet mask a valid one? -<BR> - -ipsec masktobits - convert Internet subnet mask to bit count -<BR> - -ipsec bitstomask - convert bit count to Internet subnet mask -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int goodmask(struct in_addr mask);</B> - -<BR> - -<B>int masktobits(struct in_addr mask);</B> - -<BR> - -<B>struct in_addr bitstomask(int n);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; -see -<I><A HREF="ipsec_masktocount.3.html">ipsec_masktocount</A></I>(3) - -for a partial replacement. -<P> - -<I>Goodmask</I> - -reports whether the subnet -<I>mask</I> - -is a valid one, -i.e. consists of a (possibly empty) sequence of -<B>1</B>s - -followed by a (possibly empty) sequence of -<B>0</B>s. - -<I>Masktobits</I> - -takes a (valid) subnet mask and returns the number of -<B>1</B> - -bits in it. -<I>Bitstomask</I> - -reverses this, -returning the subnet mask corresponding to bit count -<I>n</I>. - -<P> - -All masks are in network byte order. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -<I>Masktobits</I> - -returns -<B>-1</B> - -for an invalid mask. -<I>Bitstomask</I> - -returns an all-zeros mask for a negative or out-of-range -<I>n</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The error-reporting convention of -<I>bitstomask</I> - -is less than ideal; -zero is sometimes a legitimate mask. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_masktocount.3.html b/doc/manpage.d/ipsec_masktocount.3.html deleted file mode 100644 index ea0f83f82..000000000 --- a/doc/manpage.d/ipsec_masktocount.3.html +++ /dev/null @@ -1,238 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_INITSUBNET</TITLE> -</HEAD><BODY> -<H1>IPSEC_INITSUBNET</H1> -Section: C Library Functions (3)<BR>Updated: 12 March 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec initsubnet - initialize an ip_subnet -<BR> - -ipsec addrtosubnet - initialize a singleton ip_subnet -<BR> - -ipsec subnettypeof - get address type of an ip_subnet -<BR> - -ipsec masktocount - convert subnet mask to bit count -<BR> - -ipsec networkof - get base address of an ip_subnet -<BR> - -ipsec maskof - get subnet mask of an ip_subnet -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *initsubnet(const ip_address *addr,</B> - -<BR> - -<B>int maskbits, int clash, ip_subnet *dst);</B> - -<BR> - -<B>const char *addrtosubnet(const ip_address *addr,</B> - -<BR> - -<B>ip_subnet *dst);</B> - -<P> -<B>int subnettypeof(const ip_subnet *src);</B> - -<BR> - -<B>int masktocount(const ip_address *src);</B> - -<BR> - -<B>void networkof(const ip_subnet *src, ip_address *dst);</B> - -<BR> - -<B>void maskof(const ip_subnet *src, ip_address *dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -library uses an internal type -<I>ip_subnet</I> - -to contain a description of an IP subnet -(base address plus mask). -These functions provide basic tools for creating and examining this type. -<P> - -<I>Initsubnet</I> - -initializes a variable -<I>*dst</I> - -of type -<I>ip_subnet</I> - -from a base address and -a count of mask bits. -The -<I>clash</I> - -parameter specifies what to do if the base address includes -<B>1</B> - -bits outside the prefix specified by the mask -(that is, in the ``host number'' part of the address): -<DL COMPACT><DT><DD> -<DL COMPACT> -<DT>'0'<DD> -zero out host-number bits -<DT>'x'<DD> -non-zero host-number bits are an error -</DL> -</DL> - -<P> - -<I>Initsubnet</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<P> - -<I>Addrtosubnet</I> - -initializes an -<I>ip_subnet</I> - -variable -<I>*dst</I> - -to a ``singleton subnet'' containing the single address -<I>*addr</I>. - -It returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure. -<P> - -<I>Subnettypeof</I> - -returns the address type of a subnet, -normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -(The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file arranges to include the necessary headers for these -names to be known.) -<P> - -<I>Masktocount</I> - -converts a subnet mask, expressed as an address, to a bit count -suitable for use with -<I>initsubnet</I>. - -It returns -<B>-1</B> - -for error; see DIAGNOSTICS. -<P> - -<I>Networkof</I> - -fills in -<I>*dst</I> - -with the base address of subnet -<I>src</I>. - -<P> - -<I>Maskof</I> - -fills in -<I>*dst</I> - -with the subnet mask of subnet -<I>src</I>, - -expressed as an address. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_ttosubnet.3.html">ipsec_ttosubnet</A>(3), <A HREF="ipsec_rangetosubnet.3.html">ipsec_rangetosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>initsubnet</I> - -are: -unknown address family; -unknown -<I>clash</I> - -value; -impossible mask bit count; -non-zero host-number bits and -<I>clash</I> - -is -<B>'x'</B>. - -Fatal errors in -<I>addrtosubnet</I> - -are: -unknown address family. -Fatal errors in -<I>masktocount</I> - -are: -unknown address family; -mask bits not contiguous. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_networkof.3.html b/doc/manpage.d/ipsec_networkof.3.html deleted file mode 100644 index ea0f83f82..000000000 --- a/doc/manpage.d/ipsec_networkof.3.html +++ /dev/null @@ -1,238 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_INITSUBNET</TITLE> -</HEAD><BODY> -<H1>IPSEC_INITSUBNET</H1> -Section: C Library Functions (3)<BR>Updated: 12 March 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec initsubnet - initialize an ip_subnet -<BR> - -ipsec addrtosubnet - initialize a singleton ip_subnet -<BR> - -ipsec subnettypeof - get address type of an ip_subnet -<BR> - -ipsec masktocount - convert subnet mask to bit count -<BR> - -ipsec networkof - get base address of an ip_subnet -<BR> - -ipsec maskof - get subnet mask of an ip_subnet -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *initsubnet(const ip_address *addr,</B> - -<BR> - -<B>int maskbits, int clash, ip_subnet *dst);</B> - -<BR> - -<B>const char *addrtosubnet(const ip_address *addr,</B> - -<BR> - -<B>ip_subnet *dst);</B> - -<P> -<B>int subnettypeof(const ip_subnet *src);</B> - -<BR> - -<B>int masktocount(const ip_address *src);</B> - -<BR> - -<B>void networkof(const ip_subnet *src, ip_address *dst);</B> - -<BR> - -<B>void maskof(const ip_subnet *src, ip_address *dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -library uses an internal type -<I>ip_subnet</I> - -to contain a description of an IP subnet -(base address plus mask). -These functions provide basic tools for creating and examining this type. -<P> - -<I>Initsubnet</I> - -initializes a variable -<I>*dst</I> - -of type -<I>ip_subnet</I> - -from a base address and -a count of mask bits. -The -<I>clash</I> - -parameter specifies what to do if the base address includes -<B>1</B> - -bits outside the prefix specified by the mask -(that is, in the ``host number'' part of the address): -<DL COMPACT><DT><DD> -<DL COMPACT> -<DT>'0'<DD> -zero out host-number bits -<DT>'x'<DD> -non-zero host-number bits are an error -</DL> -</DL> - -<P> - -<I>Initsubnet</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<P> - -<I>Addrtosubnet</I> - -initializes an -<I>ip_subnet</I> - -variable -<I>*dst</I> - -to a ``singleton subnet'' containing the single address -<I>*addr</I>. - -It returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure. -<P> - -<I>Subnettypeof</I> - -returns the address type of a subnet, -normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -(The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file arranges to include the necessary headers for these -names to be known.) -<P> - -<I>Masktocount</I> - -converts a subnet mask, expressed as an address, to a bit count -suitable for use with -<I>initsubnet</I>. - -It returns -<B>-1</B> - -for error; see DIAGNOSTICS. -<P> - -<I>Networkof</I> - -fills in -<I>*dst</I> - -with the base address of subnet -<I>src</I>. - -<P> - -<I>Maskof</I> - -fills in -<I>*dst</I> - -with the subnet mask of subnet -<I>src</I>, - -expressed as an address. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_ttosubnet.3.html">ipsec_ttosubnet</A>(3), <A HREF="ipsec_rangetosubnet.3.html">ipsec_rangetosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>initsubnet</I> - -are: -unknown address family; -unknown -<I>clash</I> - -value; -impossible mask bit count; -non-zero host-number bits and -<I>clash</I> - -is -<B>'x'</B>. - -Fatal errors in -<I>addrtosubnet</I> - -are: -unknown address family. -Fatal errors in -<I>masktocount</I> - -are: -unknown address family; -mask bits not contiguous. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_newhostkey.8.html b/doc/manpage.d/ipsec_newhostkey.8.html deleted file mode 100644 index e6cf302bf..000000000 --- a/doc/manpage.d/ipsec_newhostkey.8.html +++ /dev/null @@ -1,196 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_NEWHOSTKEY</TITLE> -</HEAD><BODY> -<H1>IPSEC_NEWHOSTKEY</H1> -Section: Maintenance Commands (8)<BR>Updated: 4 March 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec newhostkey - generate a new host authentication key -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>newhostkey</B> - -<B>--output</B> - -filename -[ -<B>--quiet</B> - -] -<B>\</B> - -<BR> - - -[ -<B>--bits</B> - -n -] -[ -<B>--hostname</B> - -host -] -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Newhostkey</I> - -outputs (into -<I>filename</I>, - -which can be `<B>-</B>' for standard output) -an RSA private key suitable for this host, -in -<I>/etc/ipsec.secrets</I> - -format -(see -<I><A HREF="ipsec.secrets.5.html">ipsec.secrets</A></I>(5)). - -Normally, -<I>newhostkey</I> - -invokes -<I>rsasigkey</I> - -(see -<I><A HREF="ipsec_rsasigkey.8.html">ipsec_rsasigkey</A></I>(8)) - -with the -<B>--verbose</B> - -option, so a narrative of what is being done appears on standard error. -<P> - -The -<B>--output</B> - -specifier, although it is syntactically an option and can appear at -any point among the options (it doesn't have to be first), -is not optional. -The specified -<I>filename</I> - -is created under umask -<B>077</B> - -if nonexistent; -if it already exists and is non-empty, -a warning message about that is sent to standard error, -and the output is appended to the file. -<P> - -The -<B>--quiet</B> - -option suppresses both the -<I>rsasigkey</I> - -narrative and the existing-file warning message. -<P> - -The -<B>--bits</B> - -option specifies the number of bits in the key; -the current default is 2192 and we do not recommend use of anything -shorter unless unusual constraints demand it. -<P> - -The -<B>--hostname</B> - -option is passed through to -<I>rsasigkey</I> - -to tell it what host name to label the output with -(via its -<B>--hostname</B> - -option). -<P> - -The output format is that of -<I>rsasigkey</I>, - -with bracketing added to complete the -<I>ipsec.secrets</I> - -format. -In the usual case, where -<I>ipsec.secrets</I> - -contains only the host's own private key, -the output of -<I>newhostkey</I> - -is sufficient as a complete -<I>ipsec.secrets</I> - -file. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.secrets.5.html">ipsec.secrets</A>(5), <A HREF="ipsec_rsasigkey.8.html">ipsec_rsasigkey</A>(8) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Henry Spencer. -<A NAME="lbAG"> </A> -<H2>BUGS</H2> - -As with -<I>rsasigkey</I>, - -the run time is difficult to predict, -since depletion of the system's randomness pool can cause -arbitrarily long waits for random bits, -and the prime-number searches can also take unpredictable -(and potentially large) amounts of CPU time. -See -<I><A HREF="ipsec_rsasigkey.8.html">ipsec_rsasigkey</A></I>(8) - -for some typical performance numbers. -<P> - -A higher-level tool which could handle the clerical details -of changing to a new key would be helpful. -<P> - -The requirement for -<B>--output</B> - -is a blemish, -but private keys are extremely sensitive information -and unusual precautions seem justified. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -<DT><A HREF="#lbAG">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_optionsfrom.3.html b/doc/manpage.d/ipsec_optionsfrom.3.html deleted file mode 100644 index 05d045e4d..000000000 --- a/doc/manpage.d/ipsec_optionsfrom.3.html +++ /dev/null @@ -1,275 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_OPTIONSFROM</TITLE> -</HEAD><BODY> -<H1>IPSEC_OPTIONSFROM</H1> -Section: C Library Functions (3)<BR>Updated: 16 Oct 1998<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec optionsfrom - read additional ``command-line'' options from file -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *optionsfrom(char *filename, int *argcp,</B> - -<BR> - -<B>char ***argvp, int optind, FILE *errsto);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Optionsfrom</I> - -is called from within a -<I><A HREF="getopt_long.3.html">getopt_long</A></I>(3) - -scan, -as the result of the appearance of an option (preferably -<B>--optionsfrom</B>) - -to insert additional ``command-line'' arguments -into the scan immediately after -the option. -Typically this would be done to pick up options which are -security-sensitive and should not be visible to -<I><A HREF="ps.1.html">ps</A></I>(1) - -and similar commands, -and hence cannot be supplied as part -of the actual command line or the environment. -<P> - -<I>Optionsfrom</I> - -reads the additional arguments from the specified -<I>filename</I>, - -allocates a new argument vector to hold pointers to the existing -arguments plus the new ones, -and amends -<I>argc</I> - -and -<I>argv</I> - -(via the pointers -<I>argcp</I> - -and -<I>argvp</I>, - -which must point to the -<I>argc</I> - -and -<I>argv</I> - -being supplied to -<I><A HREF="getopt_long.3.html">getopt_long</A></I>(3)) - -accordingly. -<I>Optind</I> - -must be the index, in the original argument vector, -of the next argument. -<P> - -If -<I>errsto</I> - -is NULL, -<I>optionsfrom</I> - -returns NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -If -<I>errsto</I> - -is non-NULL and an error occurs, -<I>optionsfrom</I> - -prints a suitable complaint onto the -<I>errsto</I> - -descriptor and invokes -<I>exit</I> - -with an exit status of 2; -this is a convenience for cases where more sophisticated -responses are not required. -<P> - -The text of existing arguments is not disturbed by -<I>optionsfrom</I>, - -so pointers to them and into them remain valid. -<P> - -The file of additional arguments is an ASCII text file. -Lines consisting solely of white space, -and lines beginning with -<B>#</B>, - -are comments and are ignored. -Otherwise, a line which does not begin with -<B>-</B> - -is taken to be a single argument; -if it both begins and ends with double-quote ("), -those quotes are stripped off (note, no other processing is done within -the line!). -A line beginning with -<B>-</B> - -is considered to contain multiple arguments separated by white space. -<P> - -Because -<I>optionsfrom</I> - -reads its entire file before the -<I><A HREF="getopt_long.3.html">getopt_long</A></I>(3) - -scan is resumed, an -<I>optionsfrom</I> - -file can contain another -<B>--optionsfrom</B> - -option. -Obviously, infinite loops are possible here. -If -<I>errsto</I> - -is non-NULL, -<I>optionsfrom</I> - -considers it an error to be called more than 100 times. -If -<I>errsto</I> - -is NULL, -loop detection is up to the caller -(and the internal loop counter is zeroed out). -<A NAME="lbAE"> </A> -<H2>EXAMPLE</H2> - -A reasonable way to invoke -<I>optionsfrom</I> - -would be like so: -<P> - -<PRE> -<B>#include <<A HREF="file:/usr/include/getopt.h">getopt.h</A>> - -struct option opts[] = { - /* ... */ - "optionsfrom", 1, NULL, '+', - /* ... */ -}; - -int -main(argc, argv) -int argc; -char *argv[]; -{ - int opt; - extern char *optarg; - extern int optind; - - while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF) - switch (opt) { - /* ... */ - case '+': /* optionsfrom */ - optionsfrom(optarg, &argc, &argv, optind, stderr); - /* does not return on error */ - break; - /* ... */ - } - /* ... */ -</B></PRE> - -<A NAME="lbAF"> </A> -<H2>SEE ALSO</H2> - -<A HREF="getopt_long.3.html">getopt_long</A>(3) -<A NAME="lbAG"> </A> -<H2>DIAGNOSTICS</H2> - -Errors in -<I>optionsfrom</I> - -are: -unable to open file; -attempt to allocate temporary storage for argument or -argument vector failed; -read error in file; -line too long. -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAI"> </A> -<H2>BUGS</H2> - -The double-quote convention is rather simplistic. -<P> - -Line length is currently limited to 1023 bytes, -and there is no continuation convention. -<P> - -The restriction of error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -<P> - -There is a certain element of unwarranted chumminess with -the insides of -<I><A HREF="getopt_long.3.html">getopt_long</A></I>(3) - -here. -No non-public interfaces are actually used, but -<I>optionsfrom</I> - -does rely on -<I><A HREF="getopt_long.3.html">getopt_long</A></I>(3) - -being well-behaved in certain ways that are not actually -promised by the specs. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">EXAMPLE</A><DD> -<DT><A HREF="#lbAF">SEE ALSO</A><DD> -<DT><A HREF="#lbAG">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -<DT><A HREF="#lbAI">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_pf_key.5.html b/doc/manpage.d/ipsec_pf_key.5.html deleted file mode 100644 index 420c12900..000000000 --- a/doc/manpage.d/ipsec_pf_key.5.html +++ /dev/null @@ -1,176 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_PF_KEY</TITLE> -</HEAD><BODY> -<H1>IPSEC_PF_KEY</H1> -Section: File Formats (5)<BR>Updated: 29 Jun 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec_pf_key - lists PF_KEY sockets registered with KLIPS -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>cat</B> - -<B>/proc/net/pf_key</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>/proc/net/pf_key</I> - -is a read-only file which lists the presently open PF_KEY sockets on the -local system and their parameters. -<P> - -Each line lists one PF_KEY socket. -A table entry consists of: -<DL COMPACT> -<DT>+<DD> -sock pointer (sock) -<DT>+<DD> -PID of the socket owner (pid) -<DT>+<DD> -flag to indicate if the socket is dead (d) -<DT>+<DD> -socket wait queue (sleep) -<DT>+<DD> -socket pointer (socket) -<DT>+<DD> -next socket in chain (next) -<DT>+<DD> -previous socket in chain (prev) -<DT>+<DD> -last socket error (e) -<DT>+<DD> -pointer to destruct routine (destruct) -<DT>+<DD> -is this a reused socket (r) -<DT>+<DD> -has this socket been zapped (z) -<DT>+<DD> -socket family to which this socket belongs (fa) -<DT>+<DD> -local port number (n) -<DT>+<DD> -protocol version number (p) -<DT>+<DD> -Receive queue bytes committed (r) -<DT>+<DD> -Transmit queue bytes committed (w) -<DT>+<DD> -option memory allocations (o) -<DT>+<DD> -size of send buffer in bytes (sndbf) -<DT>+<DD> -timestamp in seconds (stamp) -<DT>+<DD> -socket flags (Flags) -<DT>+<DD> -socket type (Type) -<DT>+<DD> -connection state (St) -<B>.SH</B>EXAMPLES - -<DT> -<DD> -<DT><B>c3b8c140 3553 0 c0599818 c05997fc 0 0 0 0 1 0 15 0 2 0 0 0 65535 0.103232 00000000 00000003 01</B> - -<DD> -</DL> -<P> - -shows that there is one pf_key socket set up that starts at -<B>c3b8c140</B>, - -whose owning process has PID -<B>3553</B>, - -the socket is not dead, its wait queue is at -<B>c0599818</B>, - -whose owning socket is at -<B>c05997fc</B>, - -with no other sockets in the chain, no errors, no destructor, it is a -reused socket which has not been zapped, from protocol family -<B>15</B> - -(PF_KEY), local port number -<B>0</B>, - -protocol socket version -<B>2</B>, - -no memory allocated to transmit, receive or option queues, a send buffer -of almost -<B>64kB</B>, - -a timestamp of -<B>0.103232</B>, - -no flags set, type -<B>3</B>, - -in state -<B>1</B>. - -<A NAME="lbAE"> </A> -<H2>FILES</H2> - -/proc/net/pf_key -<A NAME="lbAF"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_eroute.5.html">ipsec_eroute</A>(5), <A HREF="ipsec_spi.5.html">ipsec_spi</A>(5), -<A HREF="ipsec_spigrp.5.html">ipsec_spigrp</A>(5), <A HREF="ipsec_klipsdebug.5.html">ipsec_klipsdebug</A>(5), <A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A>(8), <A HREF="ipsec_version.5.html">ipsec_version</A>(5) -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Richard Guy Briggs. - - - - - - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">SEE ALSO</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_pf_key.8.html b/doc/manpage.d/ipsec_pf_key.8.html deleted file mode 100644 index e40cfb15b..000000000 --- a/doc/manpage.d/ipsec_pf_key.8.html +++ /dev/null @@ -1,122 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_PF_KEY</TITLE> -</HEAD><BODY> -<H1>IPSEC_PF_KEY</H1> -Section: User Commands (1)<BR>Updated: 17 Oct 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -pf_key - shows pfkey messages emitted by the kernel -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>pf_key</B> - -<B>--ah</B> - -<B>--esp</B> - -<B>--ipip</B> - -<B>--ipcomp</B> - -<B>--daemon </B> - -<I>file</I> - -<B>hmac-md5-96</B>|<B>hmac-sha1-96</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<B>pf_key</B> - -is a program to open a PF_KEY socket and print all messages that are received -from it. With no options, it will register itself to receive key requests for -AH, ESP, IPIP and IPCOMP security associations. If given more specific -options, then it will listen only to those protocols which are listed. -<P> - -If the messages are recognized, the messages will be decoded. -<P> - -If the option -<B>--daemon</B> - -is provided, then after doing the registrations, the program will fork -into the background. The provided file will be opened and the process ID of -the background process will be written to it. This option is present to -present race conditions in regression testing. -<A NAME="lbAE"> </A> -<H2>EXAMPLES</H2> - -<DL COMPACT> -<DT> -<DD> -</DL> -<A NAME="lbAF"> </A> -<H2>FILES</H2> - -/proc/net/pf_key -<A NAME="lbAG"> </A> -<H2>SEE ALSO</H2> - -<A HREF="pf_key.5.html">pf_key</A>(5), <A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_eroute.5.html">ipsec_eroute</A>(5), <A HREF="ipsec_spi.5.html">ipsec_spi</A>(5), -<A HREF="ipsec_spigrp.5.html">ipsec_spigrp</A>(5), <A HREF="ipsec_klipsdebug.5.html">ipsec_klipsdebug</A>(5), <A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A>(8), <A HREF="ipsec_version.5.html">ipsec_version</A>(5) -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael Richardson <<A HREF="mailto:mcr@freeswan.org">mcr@freeswan.org</A>> - - - - - - - - - - - - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">EXAMPLES</A><DD> -<DT><A HREF="#lbAF">FILES</A><DD> -<DT><A HREF="#lbAG">SEE ALSO</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_pluto.8.html b/doc/manpage.d/ipsec_pluto.8.html deleted file mode 100644 index 2e2ce4c2f..000000000 --- a/doc/manpage.d/ipsec_pluto.8.html +++ /dev/null @@ -1,1824 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_PLUTO</TITLE> -</HEAD><BODY> -<H1>IPSEC_PLUTO</H1> -Section: Maintenance Commands (8)<BR>Updated: 28 March 1999<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec pluto - IPsec IKE keying daemon -<BR> - -ipsec whack - control interface for IPSEC keying daemon -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - - - -<DL COMPACT> -<DT> -<B> -<DD>ipsec pluto -[--help] -[--version] -[--optionsfrom </B><I>filename</I>] -[--nofork] -[--stderrlog] -[--noklips] -[--uniqueids] -[<B>--interface</B> <I>interfacename</I>] -[--ikeport <I>portnumber</I>] -[--ctlbase <I>path</I>] -[--secretsfile <I>secrets-file</I>] -[--adns <I>pathname</I>] -[--lwdnsq <I>pathname</I>] -[--perpeerlog] -[--perpeerlogbase <I>dirname</I>] -[--debug-none] -[--debug-all] -[--debug-raw] -[--debug-crypt] -[--debug-parsing] -[--debug-emitting] -[--debug-control] -[--debug-lifecycle] -[--debug-klips] -[--debug-dns] -[--debug-oppo] -[--debug-private] -<DT> -<B> -<DD>ipsec whack -[--help] -[--version] -<DT> - -<DD>ipsec whack ---name </B><I>connection-name</I> -<BR> - -[--id <I>id</I>] [--host <I>ip-address</I>] -[--ikeport <I>port-number</I>] -[--nexthop <I>ip-address</I>] -[--client <I>subnet</I>] -[--dnskeyondemand] -[--updown <I>updown</I>] -<BR> - ---to -<BR> - -[--id <I>id</I>] -[--host <I>ip-address</I>] -[--ikeport <I>port-number</I>] -[--nexthop <I>ip-address</I>] -[--client <I>subnet</I>] -[--dnskeyondemand] -[--updown <I>updown</I>] -<BR> - -[--psk] -[--rsasig] -[--encrypt] -[--authenticate] -[--compress] -[--tunnel] -[--pfs] -[--disablearrivalcheck] -[--ipv4] -[--ipv6] -[--tunnelipv4] -[--tunnelipv6] -[--ikelifetime <I>seconds</I>] -[--ipseclifetime <I>seconds</I>] -[--rekeymargin <I>seconds</I>] -[--rekeyfuzz <I>percentage</I>] -[--keyingtries <I>count</I>] -[--dontrekey] -[--delete] -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---keyid </B><I>id</I> -[--addkey] -[--pubkeyrsa <I>key</I>] -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---myid </B><I>id</I> -<DT> -<B> -<DD>ipsec whack ---listen|--unlisten -[--ctlbase </B><I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---route|--unroute ---name </B><I>connection-name</I> -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---initiate|--terminate ---name </B><I>connection-name</I> -[--asynchronous] -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack -[--tunnelipv4] -[--tunnelipv6] ---oppohere </B><I>ip-address</I> ---oppothere <I>ip-address</I> -<DT> -<B> -<DD>ipsec whack ---delete ---name </B><I>connection-name</I> -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---deletestate </B><I>state-number</I> -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack -[--name </B><I>connection-name</I>] -[--debug-none] -[--debug-all] -[--debug-raw] -[--debug-crypt] -[--debug-parsing] -[--debug-emitting] -[--debug-control] -[--debug-lifecycle] -[--debug-klips] -[--debug-dns] -[--debug-oppo] -[--debug-private] -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---status -[--ctlbase </B><I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---shutdown -[--ctlbase </B><I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] - - - -</DL> -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<B>pluto</B> - -is an IKE (``IPsec Key Exchange'') daemon. -<B>whack</B> - -is an auxiliary program to allow requests to be made to a running -<B>pluto</B>. - -<P> - -<B>pluto</B> - -is used to automatically build shared ``security associations'' on a -system that has IPsec, the secure IP protocol. -In other words, -<B>pluto</B> - -can eliminate much of the work of manual keying. -The actual -secure transmission of packets is the responsibility of other parts of -the system (see -<B>KLIPS</B>, - -the companion implementation of IPsec). -<I><A HREF="ipsec_auto.8.html">ipsec_auto</A></I>(8) provides a more convenient interface to -<B>pluto</B> and <B>whack</B>. -<A NAME="lbAE"> </A> -<H3>IKE's Job</H3> - -<P> - -A <I>Security Association</I> (<I>SA</I>) is an agreement between two network nodes on -how to process certain traffic between them. This processing involves -encapsulation, authentication, encryption, or compression. -<P> - -IKE can be deployed on a network node to negotiate Security -Associations for that node. These IKE implementations can only -negotiate with other IKE implementations, so IKE must be on each node -that is to be an endpoint of an IKE-negotiated Security Association. -No other nodes need to be running IKE. -<P> - -An IKE instance (i.e. an IKE implementation on a particular network -node) communicates with another IKE instance using UDP IP packets, so -there must be a route between the nodes in each direction. -<P> - -The negotiation of Security Associations requires a number of choices -that involve tradeoffs between security, convenience, trust, and -efficiency. These are policy issues and are normally specified to the -IKE instance by the system administrator. -<P> - -IKE deals with two kinds of Security Associations. The first part of -a negotiation between IKE instances is to build an ISAKMP SA. An -ISAKMP SA is used to protect communication between the two IKEs. -IPsec SAs can then be built by the IKEs - these are used to carry -protected IP traffic between the systems. -<P> - -The negotiation of the ISAKMP SA is known as Phase 1. In theory, -Phase 1 can be accomplished by a couple of different exchange types, -but we only implement one called Main Mode (we don't implement -Aggressive Mode). -<P> - -Any negotiation under the protection of an ISAKMP SA, including the -negotiation of IPsec SAs, is part of Phase 2. The exchange type -that we use to negotiate an IPsec SA is called Quick Mode. -<P> - -IKE instances must be able to authenticate each other as part of their -negotiation of an ISAKMP SA. This can be done by several mechanisms -described in the draft standards. -<P> - -IKE negotiation can be initiated by any instance with any other. If -both can find an agreeable set of characteristics for a Security -Association, and both recognize each others authenticity, they can set -up a Security Association. The standards do not specify what causes -an IKE instance to initiate a negotiation. -<P> - -In summary, an IKE instance is prepared to automate the management of -Security Associations in an IPsec environment, but a number of issues -are considered policy and are left in the system administrator's hands. -<A NAME="lbAF"> </A> -<H3>Pluto</H3> - -<P> - -<B>pluto</B> is an implementation of IKE. It runs as a daemon on a network -node. Currently, this network node must be a LINUX system running the -<B>KLIPS</B> implementation of IPsec. -<P> - -<B>pluto</B> only implements a subset of IKE. This is enough for it to -interoperate with other instances of <B>pluto</B>, and many other IKE -implementations. We are working on implementing more of IKE. -<P> - -The policy for acceptable characteristics for Security Associations is -mostly hardwired into the code of <B>pluto</B> (spdb.c). Eventually -this will be moved into a security policy database with reasonable -expressive power and more convenience. -<P> - -<B>pluto</B> uses shared secrets or RSA signatures to authenticate -peers with whom it is negotiating. -<P> - -<B>pluto</B> initiates negotiation of a Security Association when it is -manually prodded: the program <B>whack</B> is run to trigger this. -It will also initiate a negotiation when <B>KLIPS</B> traps an outbound packet -for Opportunistic Encryption. -<P> - -<B>pluto</B> implements ISAKMP SAs itself. After it has negotiated the -characteristics of an IPsec SA, it directs <B>KLIPS</B> to implement it. -It also invokes a script to adjust any firewall and issue <I><A HREF="route.8.html">route</A></I>(8) -commands to direct IP packets through <B>KLIPS</B>. -<P> - -When <B>pluto</B> shuts down, it closes all Security Associations. -<A NAME="lbAG"> </A> -<H3>Before Running Pluto</H3> - -<P> - -<B>pluto</B> runs as a daemon with userid root. Before running it, a few -things must be set up. -<P> - -<B>pluto</B> requires <B>KLIPS</B>, the FreeS/WAN implementation of IPsec. -All of the components of <B>KLIPS</B> and <B>pluto</B> should be installed. -<P> - -<B>pluto</B> supports multiple public networks (that is, networks -that are considered insecure and thus need to have their traffic -encrypted or authenticated). It discovers the -public interfaces to use by looking at all interfaces that are -configured (the <B>--interface</B> option can be used to limit -the interfaces considered). -It does this only when <B>whack</B> tells it to --listen, -so the interfaces must be configured by then. Each interface with a name of the form -<B>ipsec</B>[<B>0</B>-<B>9</B>] is taken as a <B>KLIPS</B> virtual public interface. -Another network interface with the same IP address (there should be only -one) is taken as the corresponding real public -interface. <I><A HREF="ifconfig.8.html">ifconfig</A></I>(8) with the <B>-a</B> flag will show -the name and status of each network interface. -<P> - -<B>pluto</B> requires a database of preshared secrets and RSA private keys. -This is described in the -<I><A HREF="ipsec.secrets.5.html">ipsec.secrets</A></I>(5). - -<B>pluto</B> is told of RSA public keys via <B>whack</B> commands. -If the connection is Opportunistic, and no RSA public key is known, -<B>pluto</B> will attempt to fetch RSA keys using the Domain Name System. -<A NAME="lbAH"> </A> -<H3>Setting up <B>KLIPS</B> for <B>pluto</B></H3> - -<P> - -The most basic network topology that <B>pluto</B> supports has two security -gateways negotiating on behalf of client subnets. The diagram of RGB's -testbed is a good example (see <I>klips/doc/rgb_setup.txt</I>). -<P> - -The file <I>INSTALL</I> in the base directory of this distribution -explains how to start setting up the whole system, including <B>KLIPS</B>. -<P> - -Make sure that the security gateways have routes to each other. This -is usually covered by the default route, but may require issuing -<I><A HREF="route.8.html">route</A></I>(8) - -commands. The route must go through a particular IP -interface (we will assume it is <I>eth0</I>, but it need not be). The -interface that connects the security gateway to its client must be a -different one. -<P> - -It is necessary to issue a -<I><A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A></I>(8) - -command on each gateway. The required command is: -<P> - ipsec tncfg --attach --virtual ipsec0 --physical eth0 -<P> -A command to set up the ipsec0 virtual interface will also need to be -run. It will have the same parameters as the command used to set up -the physical interface to which it has just been connected using -<I><A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A></I>(8). - -<A NAME="lbAI"> </A> -<H3>ipsec.secrets file</H3> - -<P> - -A <B>pluto</B> daemon and another IKE daemon (for example, another instance -of <B>pluto</B>) must convince each other that they are who they are supposed -to be before any negotiation can succeed. This authentication is -accomplished by using either secrets that have been shared beforehand -(manually) or by using RSA signatures. There are other techniques, -but they have not been implemented in <B>pluto</B>. -<P> - -The file <I>/etc/ipsec.secrets</I> is used to keep preshared secret keys -and RSA private keys for -authentication with other IKE daemons. For debugging, there is an -argument to the <B>pluto</B> command to use a different file. -This file is described in -<I><A HREF="ipsec.secrets.5.html">ipsec.secrets</A></I>(5). - -<A NAME="lbAJ"> </A> -<H3>Running Pluto</H3> - -<P> - -To fire up the daemon, just type <B>pluto</B> (be sure to be running as -the superuser). -The default IKE port number is 500, the UDP port assigned by IANA for IKE Daemons. -<B>pluto</B> must be run by the superuser to be able to use the UDP 500 port. -<P> - -<B>pluto</B> attempts to create a lockfile with the name -<I>/var/run/pluto.pid</I>. If the lockfile cannot be created, -<B>pluto</B> exits - this prevents multiple <B>pluto</B>s from -competing Any ``leftover'' lockfile must be removed before -<B>pluto</B> will run. <B>pluto</B> writes its pid into this file so -that scripts can find it. This lock will not function properly if it -is on an NFS volume (but sharing locks on multiple machines doesn't -make sense anyway). -<P> - -<B>pluto</B> then forks and the parent exits. This is the conventional -``daemon fork''. It can make debugging awkward, so there is an option -to suppress this fork. -<P> - -All logging, including diagnostics, is sent to -<I><A HREF="syslog.3.html">syslog</A></I>(3) - -with facility=authpriv; -it decides where to put these messages (possibly in /var/log/secure). -Since this too can make debugging awkward, there is an option to -steer logging to stderr. -<P> - -If the <B>--perpeerlog</B> option is given, then pluto will open -a log file per connection. By default, this is in /var/log/pluto/peer, -in a subdirectory formed by turning all dot (.) [IPv4} or colon (:) -[IPv6] into slashes (/). -<P> - -The base directory can be changed with the <B>--perpeerlogbase</B>. -<P> - -Once <B>pluto</B> is started, it waits for requests from <B>whack</B>. -<A NAME="lbAK"> </A> -<H3>Pluto's Internal State</H3> - -<P> - -To understand how to use <B>pluto</B>, it is helpful to understand a little -about its internal state. Furthermore, the terminology is needed to decipher -some of the diagnostic messages. -<P> - -The <I>(potential) connection</I> database describes attributes of a -connection. These include the IP addresses of the hosts and client -subnets and the security characteristics desired. <B>pluto</B> -requires this information (simply called a connection) before it can -respond to a request to build an SA. Each connection is given a name -when it is created, and all references are made using this name. -<P> - -During the IKE exchange to build an SA, the information about the -negotiation is represented in a <I>state object</I>. Each state object -reflects how far the negotiation has reached. Once the negotiation is -complete and the SA established, the state object remains to represent -the SA. When the SA is terminated, the state object is discarded. -Each State object is given a serial number and this is used to refer -to the state objects in logged messages. -<P> - -Each state object corresponds to a connection and can be thought of -as an instantiation of that connection. -At any particular time, there may be any number of state objects -corresponding to a particular connection. -Often there is one representing an ISAKMP SA and another representing -an IPsec SA. -<P> - -<B>KLIPS</B> hooks into the routing code in a LINUX kernel. -Traffic to be processed by an IPsec SA must be directed through -<B>KLIPS</B> by routing commands. Furthermore, the processing to be -done is specified by <I>ipsec <A HREF="eroute.8.html">eroute</A>(8)</I> commands. -<B>pluto</B> takes the responsibility of managing both of these special -kinds of routes. -<P> - -Each connection may be routed, and must be while it has an IPsec SA. -The connection specifies the characteristics of the route: the -interface on this machine, the ``gateway'' (the nexthop), -and the peer's client subnet. Two -connections may not be simultaneously routed if they are for the same -peer's client subnet but use different interfaces or gateways -(<B>pluto</B>'s logic does not reflect any advanced routing capabilities). -<P> - -Each eroute is associated with the state object for an IPsec SA -because it has the particular characteristics of the SA. -Two eroutes conflict if they specify the identical local -and remote clients (unlike for routes, the local clients are -taken into account). -<P> - -When <B>pluto</B> needs to install a route for a connection, -it must make sure that no conflicting route is in use. If another -connection has a conflicting route, that route will be taken down, as long -as there is no IPsec SA instantiating that connection. -If there is such an IPsec SA, the attempt to install a route will fail. -<P> - -There is an exception. If <B>pluto</B>, as Responder, needs to install -a route to a fixed client subnet for a connection, and there is -already a conflicting route, then the SAs using the route are deleted -to make room for the new SAs. The rationale is that the new -connection is probably more current. The need for this usually is a -product of Road Warrior connections (these are explained later; they -cannot be used to initiate). -<P> - -When <B>pluto</B> needs to install an eroute for an IPsec SA (for a -state object), first the state object's connection must be routed (if -this cannot be done, the eroute and SA will not be installed). -If a conflicting eroute is already in place for another connection, -the eroute and SA will not be installed (but note that the routing -exception mentioned above may have already deleted potentially conflicting SAs). -If another IPsec -SA for the same connection already has an eroute, all its outgoing traffic -is taken over by the new eroute. The incoming traffic will still be -processed. This characteristic is exploited during rekeying. -<P> - -All of these routing characteristics are expected change when -<B>KLIPS</B> is modified to use the firewall hooks in the LINUX 2.4.x -kernel. -<A NAME="lbAL"> </A> -<H3>Using Whack</H3> - -<P> - -<B>whack</B> is used to command a running <B>pluto</B>. -<B>whack</B> uses a UNIX domain socket to speak to <B>pluto</B> -(by default, <I>/var/pluto.ctl</I>). -<P> - -<B>whack</B> has an intricate argument syntax. -This syntax allows many different functions to be specified. -The help form shows the usage or version information. -The connection form gives <B>pluto</B> a description of a potential connection. -The public key form informs <B>pluto</B> of the RSA public key for a potential peer. -The delete form deletes a connection description and all SAs corresponding -to it. -The listen form tells <B>pluto</B> to start or stop listening on the public interfaces -for IKE requests from peers. -The route form tells <B>pluto</B> to set up routing for a connection; -the unroute form undoes this. -The initiate form tells <B>pluto</B> to negotiate an SA corresponding to a connection. -The terminate form tells <B>pluto</B> to remove all SAs corresponding to a connection, -including those being negotiated. -The status form displays the <B>pluto</B>'s internal state. -The debug form tells <B>pluto</B> to change the selection of debugging output -``on the fly''. The shutdown form tells -<B>pluto</B> to shut down, deleting all SAs. -<P> - -Most options are specific to one of the forms, and will be described -with that form. There are three options that apply to all forms. -<DL COMPACT> -<DT><B>--ctlbase</B> <I>path</I><DD> -<I>path</I>.ctl is used as the UNIX domain socket for talking -to <B>pluto</B>. -This option facilitates debugging. -<DT><B>--optionsfrom</B> <I>filename</I><DD> -adds the contents of the file to the argument list. -<DT><B>--label</B> <I>string</I><DD> -adds the string to all error messages generated by <B>whack</B>. -</DL> -<P> - -The help form of <B>whack</B> is self-explanatory. -<DL COMPACT> -<DT><B>--help</B><DD> -display the usage message. -<DT><B>--version</B><DD> -display the version of <B>whack</B>. -</DL> -<P> - -The connection form describes a potential connection to <B>pluto</B>. -<B>pluto</B> needs to know what connections can and should be negotiated. -When <B>pluto</B> is the initiator, it needs to know what to propose. -When <B>pluto</B> is the responder, it needs to know enough to decide whether -is is willing to set up the proposed connection. -<P> - -The description of a potential connection can specify a large number -of details. Each connection has a unique name. This name will appear -in a updown shell command, so it should not contain punctuation -that would make the command ill-formed. -<DL COMPACT> -<DT><B>--name</B> <I>connection-name</I><DD> -</DL> -<P> - -The topology of -a connection is symmetric, so to save space here is half a picture: -<P> - client_subnet<-->host:ikeport<-->nexthop<--- -<P> -A similar trick is used in the flags. The same flag names are used for -both ends. Those before the <B>--to</B> flag describe the left side -and those afterwards describe the right side. When <B>pluto</B> attempts -to use the connection, it decides whether it is the left side or the right -side of the connection, based on the IP numbers of its interfaces. -<DL COMPACT> -<DT><B>--id</B> <I>id</I><DD> -the identity of the end. Currently, this can be an IP address (specified -as dotted quad or as a Fully Qualified Domain Name, which will be resolved -immediately) or as a Fully Qualified Domain Name itself (prefixed by ``@'' -to signify that it should not be resolved), or as <A HREF="mailto:user@FQDN">user@FQDN</A>, or as the -magic value <B>%myid</B>. -<B>Pluto</B> only authenticates the identity, and does not use it for -addressing, so, for example, an IP address need not be the one to which -packets are to be sent. If the option is absent, the -identity defaults to the IP address specified by <B>--host</B>. -<B>%myid</B> allows the identity to be separately specified (by the <B>pluto</B> or <B>whack</B> option <B>--myid</B> -or by the <B><A HREF="ipsec.conf.5.html">ipsec.conf</A></B>(5) <B>config setup</B> parameter myid). -Otherwise, <B>pluto</B> tries to guess what <B>%myid</B> should stand for: -the IP address of <B>%defaultroute</B>, if it is supported by a suitable TXT record in the reverse domain for that IP address, -or the system's hostname, if it is supported by a suitable TXT record in its forward domain. - -<DT><B>--host</B> <I>ip-address</I><DD> -<DT><B>--host</B> <B>%any</B><DD> -<DT><B>--host</B> <B>%opportunistic</B><DD> -the IP address of the end (generally the public interface). -If <B>pluto</B> is to act as a responder -for IKE negotiations initiated from unknown IP addresses (the -``Road Warrior'' case), the -IP address should be specified as <B>%any</B> (currently, -the obsolete notation <B>0.0.0.0</B> is also accepted for this). -If <B>pluto</B> is to opportunistically initiate the connection, -use <B>%opportunistic</B> -<DT><B>--ikeport</B> <I>port-number</I><DD> -the UDP port that IKE listens to on that host. The default is 500. -(<B>pluto</B> on this machine uses the port specified by its own command -line argument, so this only affects where <B>pluto</B> sends messages.) -<DT><B>--nexthop</B> <I>ip-address</I><DD> -where to route packets for the peer's client (presumably for the peer too, -but it will not be used for this). -When <B>pluto</B> installs an IPsec SA, it issues a route command. -It uses the nexthop as the gateway. -The default is the peer's IP address (this can be explicitly written as -<B>%direct</B>; the obsolete notation <B>0.0.0.0</B> is accepted). -This option is necessary if <B>pluto</B>'s host's interface used for sending -packets to the peer is neither point-to-point nor directly connected to the -peer. -<DT><B>--client</B> <I>subnet</I><DD> -the subnet for which the IPsec traffic will be destined. If not specified, -the host will be the client. -The subnet can be specified in any of the forms supported by <I><A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A></I>(3). -The general form is <I>address</I>/<I>mask</I>. The <I>address</I> can be either -a domain name or four decimal numbers (specifying octets) separated by dots. -The most convenient form of the <I>mask</I> is a decimal integer, specifying -the number of leading one bits in the mask. So, for example, 10.0.0.0/8 -would specify the class A network ``Net 10''. -<DT><B>--dnskeyondemand]</B><DD> -specifies that when an RSA public key is needed to authenticate this -host, and it isn't already known, fetch it from DNS. -<DT><B>--updown</B> <I>updown</I><DD> -specifies an external shell command to be run whenever <B>pluto</B> -brings up or down a connection. -The script is used to build a shell command, so it may contain positional -parameters, but ought not to have punctuation that would cause the -resulting command to be ill-formed. -The default is <I>ipsec _updown</I>. -<DT><B>--to</B><DD> -separates the specification of the left and right ends of the connection. -</DL> -<P> - -The potential connection description also specifies characteristics of -rekeying and security. -<DL COMPACT> -<DT><B>--psk</B><DD> -Propose and allow preshared secret authentication for IKE peers. This authentication -requires that each side use the same secret. May be combined with <B>--rsasig</B>; -at least one must be specified. -<DT><B>--rsasig</B><DD> -Propose and allow RSA signatures for authentication of IKE peers. This authentication -requires that each side have have a private key of its own and know the -public key of its peer. May be combined with <B>--psk</B>; -at least one must be specified. -<DT><B>--encrypt</B><DD> -All proposed or accepted IPsec SAs will include non-null ESP. -The actual choices of transforms are wired into <B>pluto</B>. -<DT><B>--authenticate</B><DD> -All proposed IPsec SAs will include AH. -All accepted IPsec SAs will include AH or ESP with authentication. -The actual choices of transforms are wired into <B>pluto</B>. -Note that this has nothing to do with IKE authentication. -<DT><B>--compress</B><DD> -All proposed IPsec SAs will include IPCOMP (compression). -This will be ignored if KLIPS is not configured with IPCOMP support. -<DT><B>--tunnel</B><DD> -the IPsec SA should use tunneling. Implicit if the SA is for clients. -Must only be used with <B>--authenticate</B> or <B>--encrypt</B>. -<DT><B>--ipv4</B><DD> -The host addresses will be interpreted as IPv4 addresses. This is the -default. Note that for a connection, all host addresses must be of -the same Address Family (IPv4 and IPv6 use different Address Families). -<DT><B>--ipv6</B><DD> -The host addresses (including nexthop) will be interpreted as IPv6 addresses. -Note that for a connection, all host addresses must be of -the same Address Family (IPv4 and IPv6 use different Address Families). -<DT><B>--tunnelipv4</B><DD> -The client addresses will be interpreted as IPv4 addresses. The default is -to match what the host will be. This does not imply <B>--tunnel</B> so the -flag can be safely used when no tunnel is actually specified. -Note that for a connection, all tunnel addresses must be of the same -Address Family. -<DT><B>--tunnelipv6</B><DD> -The client addresses will be interpreted as IPv6 addresses. The default is -to match what the host will be. This does not imply <B>--tunnel</B> so the -flag can be safely used when no tunnel is actually specified. -Note that for a connection, all tunnel addresses must be of the same -Address Family. -<DT><B>--pfs</B><DD> -There should be Perfect Forward Secrecy - new keying material will -be generated for each IPsec SA rather than being derived from the ISAKMP -SA keying material. -Since the group to be used cannot be negotiated (a dubious feature of the -standard), <B>pluto</B> will propose the same group that was used during Phase 1. -We don't implement a stronger form of PFS which would require that the -ISAKMP SA be deleted after the IPSEC SA is negotiated. -<DT><B>--disablearrivalcheck</B><DD> -If the connection is a tunnel, allow packets arriving through the tunnel -to have any source and destination addresses. -</DL> -<P> - -If none of the <B>--encrypt</B>, <B>--authenticate</B>, <B>--compress</B>, -or <B>--pfs</B> flags is given, the initiating the connection will -only build an ISAKMP SA. For such a connection, client subnets have -no meaning and must not be specified. -<P> - -More work is needed to allow for flexible policies. Currently -policy is hardwired in the source file spdb.c. The ISAKMP SAs may use -Oakley groups MODP1024 and MODP1536; 3DES encryption; SHA1-96 -and MD5-96 authentication. The IPsec SAs may use 3DES and -MD5-96 or SHA1-96 for ESP, or just MD5-96 or SHA1-96 for AH. -IPCOMP Compression is always Deflate. -<DL COMPACT> -<DT><B>--ikelifetime</B> <I>seconds</I><DD> -how long <B>pluto</B> will propose that an ISAKMP SA be allowed to live. -The default is 3600 (one hour) and the maximum is 28800 (8 hours). -This option will not affect what is accepted. -<B>pluto</B> will reject proposals that exceed the maximum. -<DT><B>--ipseclifetime</B> <I>seconds</I><DD> -how long <B>pluto</B> will propose that an IPsec SA be allowed to live. -The default is 28800 (eight hours) and the maximum is 86400 (one day). -This option will not affect what is accepted. -<B>pluto</B> will reject proposals that exceed the maximum. -<DT><B>--rekeymargin</B> <I>seconds</I><DD> -how long before an SA's expiration should <B>pluto</B> try to negotiate -a replacement SA. This will only happen if <B>pluto</B> was the initiator. -The default is 540 (nine minutes). -<DT><B>--rekeyfuzz</B> <I>percentage</I><DD> -maximum size of random component to add to rekeymargin, expressed as -a percentage of rekeymargin. <B>pluto</B> will select a delay uniformly -distributed within this range. By default, the percentage will be 100. -If greater determinism is desired, specify 0. It may be appropriate -for the percentage to be much larger than 100. -<DT><B>--keyingtries</B> <I>count</I><DD> -how many times <B>pluto</B> should try to negotiate an SA, -either for the first time or for rekeying. -A value of 0 is interpreted as a very large number: never give up. -The default is three. -<DT><B>--dontrekey</B><DD> -A misnomer. -Only rekey a connection if we were the Initiator and there was recent -traffic on the existing connection. -This applies to Phase 1 and Phase 2. -This is currently the only automatic way for a connection to terminate. -It may be useful with Road Warrior or Opportunistic connections. -<BR> - -Since SA lifetime negotiation is take-it-or-leave it, a Responder -normally uses the shorter of the negotiated or the configured lifetime. -This only works because if the lifetime is shorter than negotiated, -the Responder will rekey in time so that everything works. -This interacts badly with <B>--dontrekey</B>. In this case, -the Responder will end up rekeying to rectify a shortfall in an IPsec SA -lifetime; for an ISAKMP SA, the Responder will accept the negotiated -lifetime. -<DT><B>--delete</B><DD> -when used in the connection form, it causes any previous connection -with this name to be deleted before this one is added. Unlike a -normal delete, no diagnostic is produced if there was no previous -connection to delete. Any routing in place for the connection is undone. -</DL> -<P> - -The delete form deletes a named connection description and any -SAs established or negotiations initiated using this connection. -Any routing in place for the connection is undone. -<DL COMPACT> -<DT><B>--delete</B><DD> -<DT><B>--name</B> <I>connection-name</I><DD> -</DL> -<P> - -The deletestate form deletes the state object with the specified serial number. -This is useful for selectively deleting instances of connections. -<DL COMPACT> -<DT><B>--deletestate</B> <I>state-number</I><DD> -</DL> -<P> - -The route form of the <B>whack</B> command tells <B>pluto</B> to set up -routing for a connection. -Although like a traditional route, it uses an ipsec device as a -virtual interface. -Once routing is set up, no packets will be -sent ``in the clear'' to the peer's client specified in the connection. -A TRAP shunt eroute will be installed; if outbound traffic is caught, -Pluto will initiate the connection. -An explicit <B>whack</B> route is not always needed: if it hasn't been -done when an IPsec SA is being installed, one will be automatically attempted. -<P> - -When a routing is attempted for a connection, there must not already -be a routing for a different connection with the same subnet but different -interface or destination, or if -there is, it must not be being used by an IPsec SA. Otherwise the -attempt will fail. -<DL COMPACT> -<DT><B>--route</B><DD> -<DT><B>--name</B> <I>connection-name</I><DD> -</DL> -<P> - -The unroute form of the <B>whack</B> command tells <B>pluto</B> to undo -a routing. <B>pluto</B> will refuse if an IPsec SA is using the connection. -If another connection is sharing the same routing, it will be left in place. -Without a routing, packets will be sent without encryption or authentication. -<DL COMPACT> -<DT><B>--unroute</B><DD> -<DT><B>--name</B> <I>connection-name</I><DD> -</DL> -<P> - -The initiate form tells <B>pluto</B> to initiate a negotiation with another -<B>pluto</B> (or other IKE daemon) according to the named connection. -Initiation requires a route that <B>--route</B> would provide; -if none is in place at the time an IPsec SA is being installed, -<B>pluto</B> attempts to set one up. -<DL COMPACT> -<DT><B>--initiate</B><DD> -<DT><B>--name</B> <I>connection-name</I><DD> -<DT><B>--asynchronous<DD> -</DL> -<P> - -The initiate form of the whack</B> command will relay back from -<B>pluto</B> status information via the UNIX domain socket (unless ---asynchronous is specified). The status information is meant to -look a bit like that from <B>FTP</B>. Currently <B>whack</B> simply -copies this to stderr. When the request is finished (eg. the SAs are -established or <B>pluto</B> gives up), <B>pluto</B> closes the channel, -causing <B>whack</B> to terminate. -<P> - -The opportunistic initiate form is mainly used for debugging. -<DL COMPACT> -<DT><B>--tunnelipv4</B><DD> -<DT><B>--tunnelipv6</B><DD> -<DT><B>--oppohere</B> <I>ip-address</I><DD> -<DT><B>--oppothere</B> <I>ip-address</I><DD> -</DL> -<P> - -This will cause <B>pluto</B> to attempt to opportunistically initiate a -connection from here to the there, even if a previous attempt -had been made. -The whack log will show the progress of this attempt. -<P> - -The terminate form tells <B>pluto</B> to delete any SAs that use the specified -connection and to stop any negotiations in process. -It does not prevent new negotiations from starting (the delete form -has this effect). -<DL COMPACT> -<DT><B>--terminate</B><DD> -<DT><B>--name</B> <I>connection-name</I><DD> -</DL> -<P> - -The public key for informs <B>pluto</B> of the RSA public key for a potential peer. -Private keys must be kept secret, so they are kept in -<I><A HREF="ipsec.secrets.5.html">ipsec.secrets</A></I>(5). - -<DL COMPACT> -<DT><B>--keyid </B><I>id</I><DD> -specififies the identity of the peer for which a public key should be used. -Its form is identical to the identity in the connection. -If no public key is specified, <B>pluto</B> attempts to find KEY records -from DNS for the id (if a FQDN) or through reverse lookup (if an IP address). -Note that there several interesting ways in which this is not secure. -<DT><B>--addkey</B><DD> -specifies that the new key is added to the collection; otherwise the -new key replaces any old ones. -<DT><B>--pubkeyrsa </B><I>key</I><DD> -specifies the value of the RSA public key. It is a sequence of bytes -as described in RFC 2537 ``RSA/MD5 KEYs and SIGs in the Domain Name System (DNS)''. -It is denoted in a way suitable for <I><A HREF="ipsec_ttodata.3.html">ipsec_ttodata</A></I>(3). -For example, a base 64 numeral starts with 0s. -</DL> -<P> - -The listen form tells <B>pluto</B> to start listening for IKE requests -on its public interfaces. To avoid race conditions, it is normal to -load the appropriate connections into <B>pluto</B> before allowing it -to listen. If <B>pluto</B> isn't listening, it is pointless to -initiate negotiations, so it will refuse requests to do so. Whenever -the listen form is used, <B>pluto</B> looks for public interfaces and -will notice when new ones have been added and when old ones have been -removed. This is also the trigger for <B>pluto</B> to read the -<I>ipsec.secrets</I> file. So listen may useful more than once. -<DL COMPACT> -<DT><B>--listen</B><DD> -start listening for IKE traffic on public interfaces. -<DT><B>--unlisten</B><DD> -stop listening for IKE traffic on public interfaces. -</DL> -<P> - -The status form will display information about the internal state of -<B>pluto</B>: information about each potential connection, about -each state object, and about each shunt that <B>pluto</B> is managing -without an associated connection. -<DL COMPACT> -<DT><B>--status</B><DD> -</DL> -<P> - -The shutdown form is the proper way to shut down <B>pluto</B>. -It will tear down the SAs on this machine that <B>pluto</B> has negotiated. -It does not inform its peers, so the SAs on their machines remain. -<DL COMPACT> -<DT><B>--shutdown</B><DD> -</DL> -<A NAME="lbAM"> </A> -<H3>Examples</H3> - -<P> - -It would be normal to start <B>pluto</B> in one of the system initialization -scripts. It needs to be run by the superuser. Generally, no arguments are needed. -To run in manually, the superuser can simply type -<P> - ipsec pluto -<P> -The command will immediately return, but a <B>pluto</B> process will be left -running, waiting for requests from <B>whack</B> or a peer. -<P> - -Using <B>whack</B>, several potential connections would be described: -<DL COMPACT> -<DT> - - ipsec whack --name silly ---host 127.0.0.1 --to --host 127.0.0.2 ---ikelifetime 900 --ipseclifetime 800 --keyingtries 3 - -</DL> -<P> - -<DD>Since this silly connection description specifies neither encryption, -authentication, nor tunneling, it could only be used to establish -an ISAKMP SA. -<DL COMPACT> -<DT> - - ipsec whack --name secret --host 10.0.0.1 --client 10.0.1.0/24 ---to --host 10.0.0.2 --client 10.0.2.0/24 ---encrypt - -</DL> -<P> - -<DD>This is something that must be done on both sides. If the other -side is <B>pluto</B>, the same <B>whack</B> command could be used on it -(the command syntax is designed to not distinguish which end is ours). -<P> - -Now that the connections are specified, <B>pluto</B> is ready to handle -requests and replies via the public interfaces. We must tell it to discover -those interfaces and start accepting messages from peers: -<P> - ipsec whack --listen -<P> - -If we don't immediately wish to bring up a secure connection between -the two clients, we might wish to prevent insecure traffic. -The routing form asks <B>pluto</B> to cause the packets sent from -our client to the peer's client to be routed through the ipsec0 -device; if there is no SA, they will be discarded: -<P> - ipsec whack --route secret -<P> - -Finally, we are ready to get <B>pluto</B> to initiate negotiation -for an IPsec SA (and implicitly, an ISAKMP SA): -<P> - ipsec whack --initiate --name secret -<P> -A small log of interesting events will appear on standard output -(other logging is sent to syslog). -<P> - -<B>whack</B> can also be used to terminate <B>pluto</B> cleanly, tearing down -all SAs that it has negotiated. -<P> - ipsec whack --shutdown -<P> -Notification of any IPSEC SA deletion, but not ISAKMP SA deletion -is sent to the peer. Unfortunately, such Notification is not reliable. -Furthermore, <B>pluto</B> itself ignores Notifications. -<A NAME="lbAN"> </A> -<H3>The updown command</H3> - -<P> - -Whenever <B>pluto</B> brings a connection up or down, it invokes -the updown command. This command is specified using the <B>--updown</B> -option. This allows for customized control over routing and firewall manipulation. -<P> - -The updown is invoked for five different operations. Each of -these operations can be for our client subnet or for our host itself. -<DL COMPACT> -<DT><B>prepare-host</B> or <B>prepare-client</B><DD> -is run before bringing up a new connection if no other connection -with the same clients is up. Generally, this is useful for deleting a -route that might have been set up before <B>pluto</B> was run or -perhaps by some agent not known to <B>pluto</B>. -<DT><B>route-host</B> or <B>route-client</B><DD> -is run when bringing up a connection for a new peer client subnet -(even if <B>prepare-host</B> or <B>prepare-client</B> was run). The -command should install a suitable route. Routing decisions are based -only on the destination (peer's client) subnet address, unlike eroutes -which discriminate based on source too. -<DT><B>unroute-host</B> or <B>unroute-client</B><DD> -is run when bringing down the last connection for a particular peer -client subnet. It should undo what the <B>route-host</B> or <B>route-client</B> -did. -<DT><B>up-host</B> or <B>up-client</B><DD> -is run when bringing up a tunnel eroute with a pair of client subnets -that does not already have a tunnel eroute. -This command should install firewall rules as appropriate. -It is generally a good idea to allow IKE messages (UDP port 500) -travel between the hosts. -<DT><B>down-host</B> or <B>down-client</B><DD> -is run when bringing down the eroute for a pair of client subnets. -This command should delete firewall rules as appropriate. Note that -there may remain some inbound IPsec SAs with these client subnets. -</DL> -<P> - -The script is passed a large number of environment variables to specify -what needs to be done. -<DL COMPACT> -<DT><B>PLUTO_VERSION</B><DD> -indicates what version of this interface is being used. This document -describes version 1.1. This is upwardly compatible with version 1.0. -<DT><B>PLUTO_VERB</B><DD> -specifies the name of the operation to be performed -(<B>prepare-host</B>,r <B>prepare-client</B>, -<B>up-host</B>, <B>up-client</B>, -<B>down-host</B>, or <B>down-client</B>). If the address family for -security gateway to security gateway communications is IPv6, then -a suffix of -v6 is added to the verb. -<DT><B>PLUTO_CONNECTION</B><DD> -is the name of the connection for which we are routing. -<DT><B>PLUTO_NEXT_HOP</B><DD> -is the next hop to which packets bound for the peer must be sent. -<DT><B>PLUTO_INTERFACE</B><DD> -is the name of the ipsec interface to be used. -<DT><B>PLUTO_ME</B><DD> -is the IP address of our host. -<DT><B>PLUTO_MY_CLIENT</B><DD> -is the IP address / count of our client subnet. -If the client is just the host, this will be the host's own IP address / max -(where max is 32 for IPv4 and 128 for IPv6). -<DT><B>PLUTO_MY_CLIENT_NET</B><DD> -is the IP address of our client net. -If the client is just the host, this will be the host's own IP address. -<DT><B>PLUTO_MY_CLIENT_MASK</B><DD> -is the mask for our client net. -If the client is just the host, this will be 255.255.255.255. -<DT><B>PLUTO_PEER</B><DD> -is the IP address of our peer. -<DT><B>PLUTO_PEER_CLIENT</B><DD> -is the IP address / count of the peer's client subnet. -If the client is just the peer, this will be the peer's own IP address / max -(where max is 32 for IPv4 and 128 for IPv6). -<DT><B>PLUTO_PEER_CLIENT_NET</B><DD> -is the IP address of the peer's client net. -If the client is just the peer, this will be the peer's own IP address. -<DT><B>PLUTO_PEER_CLIENT_MASK</B><DD> -is the mask for the peer's client net. -If the client is just the peer, this will be 255.255.255.255. -</DL> -<P> - -All output sent by the script to stderr or stdout is logged. The -script should return an exit status of 0 if and only if it succeeds. -<P> - -<B>Pluto</B> waits for the script to finish and will not do any other -processing while it is waiting. -The script may assume that <B>pluto</B> will not change anything -while the script runs. -The script should avoid doing anything that takes much time and it -should not issue any command that requires processing by <B>pluto</B>. -Either of these activities could be performed by a background -subprocess of the script. -<A NAME="lbAO"> </A> -<H3>Rekeying</H3> - -<P> - -When an SA that was initiated by <B>pluto</B> has only a bit of -lifetime left, -<B>pluto</B> will initiate the creation of a new SA. This applies to -ISAKMP and IPsec SAs. -The rekeying will be initiated when the SA's remaining lifetime is -less than the rekeymargin plus a random percentage, between 0 and -rekeyfuzz, of the rekeymargin. -<P> - -Similarly, when an SA that was initiated by the peer has only a bit of -lifetime left, <B>pluto</B> will try to initiate the creation of a -replacement. -To give preference to the initiator, this rekeying will only be initiated -when the SA's remaining lifetime is half of rekeymargin. -If rekeying is done by the responder, the roles will be reversed: the -responder for the old SA will be the initiator for the replacement. -The former initiator might also initiate rekeying, so there may -be redundant SAs created. -To avoid these complications, make sure that rekeymargin is generous. -<P> - -One risk of having the former responder initiate is that perhaps -none of its proposals is acceptable to the former initiator -(they have not been used in a successful negotiation). -To reduce the chances of this happening, and to prevent loss of security, -the policy settings are taken from the old SA (this is the case even if -the former initiator is initiating). -These may be stricter than those of the connection. -<P> - -<B>pluto</B> will not rekey an SA if that SA is not the most recent of its -type (IPsec or ISAKMP) for its potential connection. -This avoids creating redundant SAs. -<P> - -The random component in the rekeying time (rekeyfuzz) is intended to -make certain pathological patterns of rekeying unstable. If both -sides decide to rekey at the same time, twice as many SAs as necessary -are created. This could become a stable pattern without the -randomness. -<P> - -Another more important case occurs when a security gateway has SAs -with many other security gateways. Each of these connections might -need to be rekeyed at the same time. This would cause a high peek -requirement for resources (network bandwidth, CPU time, entropy for -random numbers). The rekeyfuzz can be used to stagger the rekeying -times. -<P> - -Once a new set of SAs has been negotiated, <B>pluto</B> will never send -traffic on a superseded one. Traffic will be accepted on an old SA -until it expires. -<A NAME="lbAP"> </A> -<H3>Selecting a Connection When Responding: Road Warrior Support</H3> - -<P> - -When <B>pluto</B> receives an initial Main Mode message, it needs to -decide which connection this message is for. It picks based solely on -the source and destination IP addresses of the message. There might -be several connections with suitable IP addresses, in which case one -of them is arbitrarily chosen. (The ISAKMP SA proposal contained in -the message could be taken into account, but it is not.) -<P> - -The ISAKMP SA is negotiated before the parties pass further -identifying information, so all ISAKMP SA characteristics specified in -the connection description should be the same for every connection -with the same two host IP addresses. At the moment, the only -characteristic that might differ is authentication method. -<P> - -Up to this point, -all configuring has presumed that the IP addresses -are known to all parties ahead of time. This will not work -when either end is mobile (or assigned a dynamic IP address for other -reasons). We call this situation ``Road Warrior''. It is fairly tricky -and has some important limitations, most of which are features of -the IKE protocol. -<P> - -Only the initiator may be mobile: -the initiator may have an IP number unknown to the responder. When -the responder doesn't recognize the IP address on the first Main Mode -packet, it looks for a connection with itself as one end and <B>%any</B> -as the other. -If it cannot find one, it refuses to negotiate. If it -does find one, it creates a temporary connection that is a duplicate -except with the <B>%any</B> replaced by the source IP address from the -packet; if there was no identity specified for the peer, the new IP -address will be used. -<P> - -When <B>pluto</B> is using one of these temporary connections and -needs to find the preshared secret or RSA private key in <I>ipsec.secrets</I>, -and and the connection specified no identity for the peer, <B>%any</B> -is used as its identity. After all, the real IP address was apparently -unknown to the configuration, so it is unreasonable to require that -it be used in this table. -<P> - -Part way into the Phase 1 (Main Mode) negotiation using one of these -temporary connection descriptions, <B>pluto</B> will be receive an -Identity Payload. At this point, <B>pluto</B> checks for a more -appropriate connection, one with an identity for the peer that matches -the payload but which would use the same keys so-far used for -authentication. If it finds one, it will switch to using this better -connection (or a temporary derived from this, if it has <B>%any</B> -for the peer's IP address). It may even turn out that no connection -matches the newly discovered identity, including the current connection; -if so, <B>pluto</B> terminates negotiation. -<P> - -Unfortunately, if preshared secret authentication is being used, the -Identity Payload is encrypted using this secret, so the secret must be -selected by the responder without knowing this payload. This -limits there to being at most one preshared secret for all Road Warrior -systems connecting to a host. RSA Signature authentications does not -require that the responder know how to select the initiator's public key -until after the initiator's Identity Payload is decoded (using the -responder's private key, so that must be preselected). -<P> - -When <B>pluto</B> is responding to a Quick Mode negotiation via one of these -temporary connection descriptions, it may well find that the subnets -specified by the initiator don't match those in the temporary -connection description. If so, it will look for a connection with -matching subnets, its own host address, a peer address of <B>%any</B> -and matching identities. -If it finds one, a new temporary connection is derived from this one -and used for the Quick Mode negotiation of IPsec SAs. If it does not -find one, <B>pluto</B> terminates negotiation. -<P> - -Be sure to specify an appropriate nexthop for the responder -to send a message to the initiator: <B>pluto</B> has no way of guessing -it (if forwarding isn't required, use an explicit <B>%direct</B> as the nexthop -and the IP address of the initiator will be filled in; the obsolete -notation <B>0.0.0.0</B> is still accepted). -<P> - -<B>pluto</B> has no special provision for the initiator side. The current -(possibly dynamic) IP address and nexthop must be used in defining -connections. These must be -properly configured each time the initiator's IP address changes. -<B>pluto</B> has no mechanism to do this automatically. -<P> - -Although we call this Road Warrior Support, it could also be used to -support encrypted connections with anonymous initiators. The -responder's organization could announce the preshared secret that would be used -with unrecognized initiators and let anyone connect. Of course the initiator's -identity would not be authenticated. -<P> - -If any Road Warrior connections are supported, <B>pluto</B> cannot -reject an exchange initiated by an unknown host until it has -determined that the secret is not shared or the signature is invalid. -This must await the -third Main Mode message from the initiator. If no Road Warrior -connection is supported, the first message from an unknown source -would be rejected. This has implications for ease of debugging -configurations and for denial of service attacks. -<P> - -Although a Road Warrior connection must be initiated by the mobile -side, the other side can and will rekey using the temporary connection -it has created. If the Road Warrior wishes to be able to disconnect, -it is probably wise to set <B>--keyingtries</B> to 1 in the -connection on the non-mobile side to prevent it trying to rekey the -connection. Unfortunately, there is no mechanism to unroute the -connection automatically. -<A NAME="lbAQ"> </A> -<H3>Debugging</H3> - -<P> - -<B>pluto</B> accepts several optional arguments, useful mostly for debugging. -Except for <B>--interface</B>, each should appear at most once. -<DL COMPACT> -<DT><B>--interface</B> <I>interfacename</I><DD> -specifies that the named real public network interface should be considered. -The interface name specified should not be <B>ipsec</B><I>N</I>. -If the option doesn't appear, all interfaces are considered. -To specify several interfaces, use the option once for each. -One use of this option is to specify which interface should be used -when two or more share the same IP address. -<DT><B>--ikeport</B> <I>port-number</I><DD> -changes the UDP port that <B>pluto</B> will use -(default, specified by IANA: 500) -<DT><B>--ctlbase</B> <I>path</I><DD> -basename for control files. -<I>path</I>.ctl is the socket through which <B>whack</B> communicates with -<B>pluto</B>. -<I>path</I>.pid is the lockfile to prevent multiple <B>pluto</B> instances. -The default is <I>/var/run/pluto</I>). -<DT><B>--secretsfile</B> <I>file</I><DD> -specifies the file for authentication secrets -(default: <I>/etc/ipsec.secrets</I>). -This name is subject to ``globbing'' as in <I><A HREF="sh.1.html">sh</A></I>(1), -so every file with a matching name is processed. -Quoting is generally needed to prevent the shell from doing the globbing. -<DT><B>--adns</B> <I>pathname</I><DD> -<DT><B>--lwdnsq</B> <I>pathname</I><DD> -specifies where to find <B>pluto</B>'s helper program for asynchronous DNS lookup. -<B>pluto</B> can be built to use one of two helper programs: <B>_pluto_adns</B> -or <B>lwdnsq</B>. You must use the program for which it was built. -By default, <B>pluto</B> will look for the program in -<B>$IPSEC_DIR</B> (if that environment variable is defined) or, failing that, -in the same directory as <B>pluto</B>. -<DT><B>--nofork</B><DD> -disable ``daemon fork'' (default is to fork). In addition, after the -lock file and control socket are created, print the line ``Pluto -initialized'' to standard out. -<DT><B>--noklips</B><DD> -don't actually implement negotiated IPsec SAs -<DT><B>--uniqueids</B><DD> -if this option has been selected, whenever a new ISAKMP SA is -established, any connection with the same Peer ID but a different -Peer IP address is unoriented (causing all its SAs to be deleted). -This helps clean up dangling SAs when a connection is lost and -then regained at another IP address. -<DT><B>--stderrlog</B><DD> -log goes to standard out {default is to use <I><A HREF="syslogd.8.html">syslogd</A></I>(8)) -</DL> -<P> - -For example -<DL COMPACT> -<DT>pluto --secretsfile ipsec.secrets --ctlbase pluto.base --ikeport 8500 --nofork --noklips --stderrlog<DD> -</DL> -<P> - -lets one test <B>pluto</B> without using the superuser account. -<P> - -<B>pluto</B> is willing to produce a prodigious amount of debugging -information. To do so, it must be compiled with -DDEBUG. There are -several classes of debugging output, and <B>pluto</B> may be directed to -produce a selection of them. All lines of -debugging output are prefixed with ``| '' to distinguish them from error -messages. -<P> - -When <B>pluto</B> is invoked, it may be given arguments to specify -which classes to output. The current options are: -<DL COMPACT> -<DT><B>--debug-raw</B><DD> -show the raw bytes of messages -<DT><B>--debug-crypt</B><DD> -show the encryption and decryption of messages -<DT><B>--debug-parsing</B><DD> -show the structure of input messages -<DT><B>--debug-emitting</B><DD> -show the structure of output messages -<DT><B>--debug-control</B><DD> -show <B>pluto</B>'s decision making -<DT><B>--debug-lifecycle</B><DD> -[this option is temporary] log more detail of lifecycle of SAs -<DT><B>--debug-klips</B><DD> -show <B>pluto</B>'s interaction with <B>KLIPS</B> -<DT><B>--debug-dns</B><DD> -show <B>pluto</B>'s interaction with <B>DNS</B> for KEY and TXT records -<DT><B>--debug-oppo</B><DD> -show why <B>pluto</B> didn't find a suitable DNS TXT record to authorize opportunistic initiation -<DT><B>--debug-all</B><DD> -all of the above -<DT><B>--debug-private</B><DD> -allow debugging output with private keys. -<DT><B>--debug-none</B><DD> -none of the above -</DL> -<P> - -The debug form of the -<B>whack</B> command will change the selection in a running -<B>pluto</B>. -If a connection name is specified, the flags are added whenever -<B>pluto</B> has identified that it is dealing with that connection. -Unfortunately, this is often part way into the operation being observed. -<P> - -For example, to start a <B>pluto</B> with a display of the structure of input -and output: -<DL COMPACT> -<DT><DD> -pluto --debug-emitting --debug-parsing -</DL> -<P> - -To later change this <B>pluto</B> to only display raw bytes: -<DL COMPACT> -<DT><DD> -whack --debug-raw -</DL> -<P> - -For testing, SSH's IKE test page is quite useful: -<DL COMPACT> -<DT><DD> -<I><A HREF="http://isakmp-test.ssh.fi/">http://isakmp-test.ssh.fi/</A></I> -</DL> -<P> - -Hint: ISAKMP SAs are often kept alive by IKEs even after the IPsec SA -is established. This allows future IPsec SA's to be negotiated -directly. If one of the IKEs is restarted, the other may try to use -the ISAKMP SA but the new IKE won't know about it. This can lead to -much confusion. <B>pluto</B> is not yet smart enough to get out of such a -mess. -<A NAME="lbAR"> </A> -<H3>Pluto's Behaviour When Things Go Wrong</H3> - -<P> - -When <B>pluto</B> doesn't understand or accept a message, it just -ignores the message. It is not yet capable of communicating the -problem to the other IKE daemon (in the future it might use -Notifications to accomplish this in many cases). It does log a diagnostic. -<P> - -When <B>pluto</B> gets no response from a message, it resends the same -message (a message will be sent at most three times). This is -appropriate: UDP is unreliable. -<P> - -When pluto gets a message that it has already seen, there are many -cases when it notices and discards it. This too is appropriate for UDP. -<P> - -Combine these three rules, and you can explain many apparently -mysterious behaviours. In a <B>pluto</B> log, retrying isn't usually the -interesting event. The critical thing is either earlier (<B>pluto</B> -got a message which it didn't like and so ignored, so it was still -awaiting an acceptable message and got impatient) or on the other -system (<B>pluto</B> didn't send a reply because it wasn't happy with -the previous message). -<A NAME="lbAS"> </A> -<H3>Notes</H3> - -<P> - -If <B>pluto</B> is compiled without -DKLIPS, it negotiates Security -Associations but never ask the kernel to put them in place and never -makes routing changes. This allows <B>pluto</B> to be tested on systems -without <B>KLIPS</B>, but makes it rather useless. -<P> - -Each IPsec SA is assigned an SPI, a 32-bit number used to refer to the SA. -The IKE protocol lets the destination of the SA choose the SPI. -The range 0 to 0xFF is reserved for IANA. -<B>Pluto</B> also avoids choosing an SPI in the range 0x100 to 0xFFF, -leaving these SPIs free for manual keying. -Remember that the peer, if not <B>pluto</B>, may well chose -SPIs in this range. -<A NAME="lbAT"> </A> -<H3>Policies</H3> - -<P> - -This catalogue of policies may be of use when trying to configure -<B>Pluto</B> and another IKE implementation to interoperate. -<P> - -In Phase 1, only Main Mode is supported. We are not sure that -Aggressive Mode is secure. For one thing, it does not support -identity protection. It may allow more severe Denial Of Service -attacks. -<P> - -No Informational Exchanges are supported. These are optional and -since their delivery is not assured, they must not matter. -It is the case that some IKE implementations won't interoperate -without Informational Exchanges, but we feel they are broken. -<P> - -No Informational Payloads are supported. These are optional, but -useful. It is of concern that these payloads are not authenticated in -Phase 1, nor in those Phase 2 messages authenticated with <A HREF="HASH.3.html">HASH</A>(3). -<DL COMPACT> -<DT>*<DD> -Diffie Hellman Groups MODP 1024 and MODP 1536 (2 and 5) -are supported. -Group MODP768 (1) is not supported because it is too weak. -<DT>*<DD> -Host authetication can be done by RSA Signatures or Pre-Shared -Secrets. -<DT>*<DD> -3DES CBC (Cypher Block Chaining mode) is the only encryption -supported, both for ISAKMP SAs and IPSEC SAs. -<DT>*<DD> -MD5 and SHA1 hashing are supported for packet authentication in both -kinds of SAs. -<DT>*<DD> -The ESP, AH, or AH plus ESP are supported. If, and only if, AH and -ESP are combined, the ESP need not have its own authentication -component. The selection is controlled by the --encrypt and ---authenticate flags. -<DT>*<DD> -Each of these may be combined with IPCOMP Deflate compression, -but only if the potential connection specifies compression and only -if KLIPS is configured with IPCOMP support. -<DT>*<DD> -The IPSEC SAs may be tunnel or transport mode, where appropriate. -The --tunnel flag controls this when <B>pluto</B> is initiating. -<DT>*<DD> -When responding to an ISAKMP SA proposal, the maximum acceptable -lifetime is eight hours. The default is one hour. There is no -minimum. The --ikelifetime flag controls this when <B>pluto</B> -is initiating. -<DT>*<DD> -When responding to an IPSEC SA proposal, the maximum acceptable -lifetime is one day. The default is eight hours. There is no -minimum. The --ipseclifetime flag controls this when <B>pluto</B> -is initiating. -<DT>*<DD> -PFS is acceptable, and will be proposed if the --pfs flag was -specified. The DH group proposed will be the same as negotiated for -Phase 1. -</DL> -<A NAME="lbAU"> </A> -<H2>SIGNALS</H2> - -<P> - -<B>Pluto</B> responds to <B>SIGHUP</B> by issuing a suggestion that ``<B>whack</B> ---listen'' might have been intended. -<P> - -<B>Pluto</B> exits when it recieves <B>SIGTERM</B>. -<A NAME="lbAV"> </A> -<H2>EXIT STATUS</H2> - -<P> - -<B>pluto</B> normally forks a daemon process, so the exit status is -normally a very preliminary result. -<DL COMPACT> -<DT>0<DD> -means that all is OK so far. -<DT>1<DD> -means that something was wrong. -<DT>10<DD> -means that the lock file already exists. -</DL> -<P> - -If <B>whack</B> detects a problem, it will return an exit status of 1. -If it received progress messages from <B>pluto</B>, it returns as status -the value of the numeric prefix from the last such message -that was not a message sent to syslog or a comment -(but the prefix for success is treated as 0). -Otherwise, the exit status is 0. -<A NAME="lbAW"> </A> -<H2>FILES</H2> - -<I>/var/run/pluto.pid</I> -<BR> - -<I>/var/run/pluto.ctl</I> -<BR> - -<I>/etc/ipsec.secrets</I> -<BR> - -<I>$IPSEC_LIBDIR/_pluto_adns</I> -<BR> - -<I>$IPSEC_EXECDIR/lwdnsq</I> -<BR> - -<I>/dev/urandom</I> -<A NAME="lbAX"> </A> -<H2>ENVIRONMENT</H2> - -<I>IPSEC_LIBDIR</I> -<BR> - -<I>IPSEC_EXECDIR</I> -<BR> - -<I>IPSECmyid</I> -<A NAME="lbAY"> </A> -<H2>SEE ALSO</H2> - -<P> - -The rest of the FreeS/WAN distribution, in particular <I><A HREF="ipsec.8.html">ipsec</A></I>(8). -<P> - -<I><A HREF="ipsec_auto.8.html">ipsec_auto</A></I>(8) is designed to make using <B>pluto</B> more pleasant. -Use it! -<P> - -<I><A HREF="ipsec.secrets.5.html">ipsec.secrets</A></I>(5) - -describes the format of the secrets file. -<P> - -<I><A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A></I>(3), part of the FreeS/WAN distribution, describes the -forms that IP addresses may take. -<I><A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A></I>(3), part of the FreeS/WAN distribution, describes the -forms that subnet specifications. -<P> - -For more information on IPsec, the mailing list, and the relevant -documents, see: -<DL COMPACT> -<DT><DD> - -<I><A HREF="http://www.ietf.cnri.reston.va.us/html.charters/ipsec-charter.html">http://www.ietf.cnri.reston.va.us/html.charters/ipsec-charter.html</A></I> - -</DL> -<P> - -At the time of writing, the most relevant IETF RFCs are: -<DL COMPACT> -<DT><DD> -RFC2409 The Internet Key Exchange (IKE) -<DT><DD> -RFC2408 Internet Security Association and Key Management Protocol (ISAKMP) -<DT><DD> -RFC2407 The Internet IP Security Domain of Interpretation for ISAKMP -</DL> -<P> - -The FreeS/WAN web site <<A HREF="htp://www.freeswan.org">htp://www.freeswan.org</A>> -and the mailing lists described there. -<A NAME="lbAZ"> </A> -<H2>HISTORY</H2> - -This code is released under the GPL terms. -See the accompanying file COPYING-2.0 for more details. -The GPL does NOT apply to those pieces of code written by others -which are included in this distribution, except as noted by the -individual authors. -<P> - -This software was originally written -for the FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Angelos D. Keromytis -(<A HREF="mailto:angelos@dsl.cis.upenn.edu">angelos@dsl.cis.upenn.edu</A>), in May/June 1997, in Athens, Greece. -Thanks go to John Ioannidis for his help. -<P> - -It is currently (2000) -being developed and maintained by D. Hugh Redelmeier -(<A HREF="mailto:hugh@mimosa.com">hugh@mimosa.com</A>), in Canada. The regulations of Greece and Canada -allow us to make the code freely redistributable. -<P> - -Kai Martius (<A HREF="mailto:admin@imib.med.tu-dresden.de">admin@imib.med.tu-dresden.de</A>) contributed the initial -version of the code supporting PFS. -<P> - -Richard Guy Briggs <<A HREF="mailto:rgb@conscoop.ottawa.on.ca">rgb@conscoop.ottawa.on.ca</A>> and Peter Onion -<<A HREF="mailto:ponion@srd.bt.co.uk">ponion@srd.bt.co.uk</A>> added the PFKEY2 support. -<P> - -We gratefully acknowledge that we use parts of Eric Young's <I>libdes</I> -package; see <I>../libdes/COPYRIGHT</I>. -<A NAME="lbBA"> </A> -<H2>BUGS</H2> - -<B>pluto</B> - -is a work-in-progress. It currently has many limitations. -For example, it ignores notification messages that it receives, and -it generates only Delete Notifications and those only for IPSEC SAs. -<P> - -<B>pluto</B> does not support the Commit Flag. -The Commit Flag is a bad feature of the IKE protocol. -It isn't protected -- neither encrypted nor authenticated. -A man in the middle could turn it on, leading to DoS. -We just ignore it, with a warning. -This should let us interoperate with -implementations that insist on it, with minor damage. -<P> - -<B>pluto</B> does not check that the SA returned by the Responder -is actually one that was proposed. It only checks that the SA is -acceptable. The difference is not large, but can show up in attributes -such as SA lifetime. -<P> - -There is no good way for a connection to be automatically terminated. -This is a problem for Road Warrior and Opportunistic connections. -The <B>--dontrekey</B> option does prevent the SAs from -being rekeyed on expiry. -Additonally, if a Road Warrior connection has a client subnet with a fixed IP -address, a negotiation with that subnet will cause any other -connection instantiations with that same subnet to be unoriented -(deleted, in effect). -See also the --uniqueids option for an extension of this. -<P> - -When <B>pluto</B> sends a message to a peer that has disappeared, -<B>pluto</B> receives incomplete information from the kernel, so it -logs the unsatisfactory message ``some IKE message we sent has been -rejected with ECONNREFUSED (kernel supplied no details)''. John -Denker suggests that this command is useful for tracking down the -source of these problems: -<BR> - -<TT> </TT>tcpdump -i eth0 icmp[0] != 8 and icmp[0] != 0<BR> -<BR> - -Substitute your public interface for eth0 if it is different. -<P> - -The word ``authenticate'' is used for two different features. We must -authenticate each IKE peer to the other. This is an important task of -Phase 1. Each packet must be authenticated, both in IKE and in IPsec, -and the method for IPsec is negotiated as an AH SA or part of an ESP SA. -Unfortunately, the protocol has no mechanism for authenticating the Phase 2 -identities. -<P> - -Bugs should be reported to the <<A HREF="mailto:users@lists.freeswan.org">users@lists.freeswan.org</A>> mailing list. -Caution: we cannot accept -actual code from US residents, or even US citizens living outside the -US, because that would bring FreeS/WAN under US export law. Some -other countries cause similar problems. In general, we would prefer -that you send detailed problem reports rather than code: we want -FreeS/WAN to be unquestionably freely exportable, which means being -very careful about where the code comes from, and for a small bug fix, -that is often more time-consuming than just reinventing the fix -ourselves. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DL> -<DT><A HREF="#lbAE">IKE's Job</A><DD> -<DT><A HREF="#lbAF">Pluto</A><DD> -<DT><A HREF="#lbAG">Before Running Pluto</A><DD> -<DT><A HREF="#lbAH">Setting up <B>KLIPS</B> for <B>pluto</B></A><DD> -<DT><A HREF="#lbAI">ipsec.secrets file</A><DD> -<DT><A HREF="#lbAJ">Running Pluto</A><DD> -<DT><A HREF="#lbAK">Pluto's Internal State</A><DD> -<DT><A HREF="#lbAL">Using Whack</A><DD> -<DT><A HREF="#lbAM">Examples</A><DD> -<DT><A HREF="#lbAN">The updown command</A><DD> -<DT><A HREF="#lbAO">Rekeying</A><DD> -<DT><A HREF="#lbAP">Selecting a Connection When Responding: Road Warrior Support</A><DD> -<DT><A HREF="#lbAQ">Debugging</A><DD> -<DT><A HREF="#lbAR">Pluto's Behaviour When Things Go Wrong</A><DD> -<DT><A HREF="#lbAS">Notes</A><DD> -<DT><A HREF="#lbAT">Policies</A><DD> -</DL> -<DT><A HREF="#lbAU">SIGNALS</A><DD> -<DT><A HREF="#lbAV">EXIT STATUS</A><DD> -<DT><A HREF="#lbAW">FILES</A><DD> -<DT><A HREF="#lbAX">ENVIRONMENT</A><DD> -<DT><A HREF="#lbAY">SEE ALSO</A><DD> -<DT><A HREF="#lbAZ">HISTORY</A><DD> -<DT><A HREF="#lbBA">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_portof.3.html b/doc/manpage.d/ipsec_portof.3.html deleted file mode 100644 index 3965ca62d..000000000 --- a/doc/manpage.d/ipsec_portof.3.html +++ /dev/null @@ -1,143 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_PORTOF</TITLE> -</HEAD><BODY> -<H1>IPSEC_PORTOF</H1> -Section: C Library Functions (3)<BR>Updated: 8 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec portof - get port field of an ip_address -<BR> - -ipsec setportof - set port field of an ip_address -<BR> - -ipsec sockaddrof - get pointer to internal sockaddr of an ip_address -<BR> - -ipsec sockaddrlenof - get length of internal sockaddr of an ip_address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int portof(const ip_address *src);</B> - -<BR> - -<B>void setportof(int port, ip_address *dst);</B> - -<BR> - -<B>struct sockaddr *sockaddrof(ip_address *src);</B> - -<BR> - -<B>size_t sockaddrlenof(const ip_address *src);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -internal type -<I>ip_address</I> - -contains one of the -<I>sockaddr</I> - -types internally. -<I>Reliance on this feature is discouraged</I>, -but it may occasionally be necessary. -These functions provide low-level tools for this purpose. -<P> - -<I>Portof</I> - -and -<I>setportof</I> - -respectively read and write the port-number field of the internal -<I>sockaddr</I>. - -The values are in network byte order. -<P> - -<I>Sockaddrof</I> - -returns a pointer to the internal -<I>sockaddr</I>, - -for passing to other functions. -<P> - -<I>Sockaddrlenof</I> - -reports the size of the internal -<I>sockaddr</I>, - -for use in storage allocation. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_initaddr.3.html">ipsec_initaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -<I>Portof</I> - -returns -<B>-1</B>, - -<I>sockaddrof</I> - -returns -<B>NULL</B>, - -and -<I>sockaddrlenof</I> - -returns -<B>0</B> - -if an unknown address family is found within the -<I>ip_address</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -These functions all depend on low-level details of the -<I>ip_address</I> - -type, which are in principle subject to change. -Avoid using them unless really necessary. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_prng.3.html b/doc/manpage.d/ipsec_prng.3.html deleted file mode 100644 index 27763a2bb..000000000 --- a/doc/manpage.d/ipsec_prng.3.html +++ /dev/null @@ -1,204 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_PRNG</TITLE> -</HEAD><BODY> -<H1>IPSEC_PRNG</H1> -Section: C Library Functions (3)<BR>Updated: 1 April 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec prng_init - initialize IPsec pseudorandom-number generator -<BR> - -ipsec prng_bytes - get bytes from IPsec pseudorandom-number generator -<BR> - -ipsec prng_final - close down IPsec pseudorandom-number generator -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>void prng_init(struct prng *prng,</B> - -<BR> - -<B>const unsigned char *key, size_t keylen);</B> - -<BR> - -<B>void prng_bytes(struct prng *prng, char *dst,</B> - -<BR> - -<B>size_t dstlen);</B> - -<BR> - -<B>unsigned long prng_count(struct prng *prng);</B> - -<BR> - -<B>void prng_final(struct prng *prng);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Prng_init</I> - -initializes a crypto-quality pseudo-random-number generator from a key; -<I>prng_bytes</I> - -obtains pseudo-random bytes from it; -<I>prng_count</I> - -reports the number of bytes extracted from it to date; -<I>prng_final</I> - -closes it down. -It is the user's responsibility to initialize a PRNG before using it, -and not to use it again after it is closed down. -<P> - -<I>Prng_init</I> - -initializes, -or re-initializes, -the specified -<I>prng</I> - -from the -<I>key</I>, - -whose length is given by -<I>keylen</I>. - -The user must allocate the -<B>struct prng</B> - -pointed to by -<I>prng</I>. - -There is no particular constraint on the length of the key, -although a key longer than 256 bytes is unnecessary because -only the first 256 would be used. -Initialization requires on the order of 3000 integer operations, -independent of key length. -<P> - -<I>Prng_bytes</I> - -obtains -<I>dstlen</I> - -pseudo-random bytes from the PRNG and puts them in -<I>buf</I>. - -This is quite fast, -on the order of 10 integer operations per byte. -<P> - -<I>Prng_count</I> - -reports the number of bytes obtained from the PRNG -since it was (last) initialized. -<P> - -<I>Prng_final</I> - -closes down a PRNG by -zeroing its internal memory, -obliterating all trace of the state used to generate its previous output. -This requires on the order of 250 integer operations. -<P> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file supplies the definition of the -<B>prng</B> - -structure. -Examination of its innards is discouraged, as they may change. -<P> - -The PRNG algorithm -used by these functions is currently identical to that of RC4(TM). -This algorithm is cryptographically strong, -sufficiently unpredictable that even a hostile observer will -have difficulty determining the next byte of output from past history, -provided it is initialized from a reasonably large key composed of -highly random bytes (see -<I><A HREF="random.4.html">random</A></I>(4)). - -The usual run of software pseudo-random-number generators -(e.g. -<I><A HREF="random.3.html">random</A></I>(3)) - -are -<I>not</I> - -cryptographically strong. -<P> - -The well-known attacks against RC4(TM), -e.g. as found in 802.11b's WEP encryption system, -apply only if multiple PRNGs are initialized with closely-related keys -(e.g., using a counter appended to a base key). -If such keys are used, the first few hundred pseudo-random bytes -from each PRNG should be discarded, -to give the PRNGs a chance to randomize their innards properly. -No useful attacks are known if the key is well randomized to begin with. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="random.3.html">random</A>(3), <A HREF="random.4.html">random</A>(4) -<BR> - -Bruce Schneier, -<I>Applied Cryptography</I>, 2nd ed., 1996, ISBN 0-471-11709-9, -pp. 397-8. -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAG"> </A> -<H2>BUGS</H2> - -If an attempt is made to obtain more than 4e9 bytes -between initializations, -the PRNG will continue to work but -<I>prng_count</I>'s - -output will stick at -<B>4000000000</B>. - -Fixing this would require a longer integer type and does -not seem worth the trouble, -since you should probably re-initialize before then anyway... -<P> - -``RC4'' is a trademark of RSA Data Security, Inc. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -<DT><A HREF="#lbAG">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_prng_bytes.3.html b/doc/manpage.d/ipsec_prng_bytes.3.html deleted file mode 100644 index 27763a2bb..000000000 --- a/doc/manpage.d/ipsec_prng_bytes.3.html +++ /dev/null @@ -1,204 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_PRNG</TITLE> -</HEAD><BODY> -<H1>IPSEC_PRNG</H1> -Section: C Library Functions (3)<BR>Updated: 1 April 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec prng_init - initialize IPsec pseudorandom-number generator -<BR> - -ipsec prng_bytes - get bytes from IPsec pseudorandom-number generator -<BR> - -ipsec prng_final - close down IPsec pseudorandom-number generator -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>void prng_init(struct prng *prng,</B> - -<BR> - -<B>const unsigned char *key, size_t keylen);</B> - -<BR> - -<B>void prng_bytes(struct prng *prng, char *dst,</B> - -<BR> - -<B>size_t dstlen);</B> - -<BR> - -<B>unsigned long prng_count(struct prng *prng);</B> - -<BR> - -<B>void prng_final(struct prng *prng);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Prng_init</I> - -initializes a crypto-quality pseudo-random-number generator from a key; -<I>prng_bytes</I> - -obtains pseudo-random bytes from it; -<I>prng_count</I> - -reports the number of bytes extracted from it to date; -<I>prng_final</I> - -closes it down. -It is the user's responsibility to initialize a PRNG before using it, -and not to use it again after it is closed down. -<P> - -<I>Prng_init</I> - -initializes, -or re-initializes, -the specified -<I>prng</I> - -from the -<I>key</I>, - -whose length is given by -<I>keylen</I>. - -The user must allocate the -<B>struct prng</B> - -pointed to by -<I>prng</I>. - -There is no particular constraint on the length of the key, -although a key longer than 256 bytes is unnecessary because -only the first 256 would be used. -Initialization requires on the order of 3000 integer operations, -independent of key length. -<P> - -<I>Prng_bytes</I> - -obtains -<I>dstlen</I> - -pseudo-random bytes from the PRNG and puts them in -<I>buf</I>. - -This is quite fast, -on the order of 10 integer operations per byte. -<P> - -<I>Prng_count</I> - -reports the number of bytes obtained from the PRNG -since it was (last) initialized. -<P> - -<I>Prng_final</I> - -closes down a PRNG by -zeroing its internal memory, -obliterating all trace of the state used to generate its previous output. -This requires on the order of 250 integer operations. -<P> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file supplies the definition of the -<B>prng</B> - -structure. -Examination of its innards is discouraged, as they may change. -<P> - -The PRNG algorithm -used by these functions is currently identical to that of RC4(TM). -This algorithm is cryptographically strong, -sufficiently unpredictable that even a hostile observer will -have difficulty determining the next byte of output from past history, -provided it is initialized from a reasonably large key composed of -highly random bytes (see -<I><A HREF="random.4.html">random</A></I>(4)). - -The usual run of software pseudo-random-number generators -(e.g. -<I><A HREF="random.3.html">random</A></I>(3)) - -are -<I>not</I> - -cryptographically strong. -<P> - -The well-known attacks against RC4(TM), -e.g. as found in 802.11b's WEP encryption system, -apply only if multiple PRNGs are initialized with closely-related keys -(e.g., using a counter appended to a base key). -If such keys are used, the first few hundred pseudo-random bytes -from each PRNG should be discarded, -to give the PRNGs a chance to randomize their innards properly. -No useful attacks are known if the key is well randomized to begin with. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="random.3.html">random</A>(3), <A HREF="random.4.html">random</A>(4) -<BR> - -Bruce Schneier, -<I>Applied Cryptography</I>, 2nd ed., 1996, ISBN 0-471-11709-9, -pp. 397-8. -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAG"> </A> -<H2>BUGS</H2> - -If an attempt is made to obtain more than 4e9 bytes -between initializations, -the PRNG will continue to work but -<I>prng_count</I>'s - -output will stick at -<B>4000000000</B>. - -Fixing this would require a longer integer type and does -not seem worth the trouble, -since you should probably re-initialize before then anyway... -<P> - -``RC4'' is a trademark of RSA Data Security, Inc. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -<DT><A HREF="#lbAG">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_prng_final.3.html b/doc/manpage.d/ipsec_prng_final.3.html deleted file mode 100644 index 27763a2bb..000000000 --- a/doc/manpage.d/ipsec_prng_final.3.html +++ /dev/null @@ -1,204 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_PRNG</TITLE> -</HEAD><BODY> -<H1>IPSEC_PRNG</H1> -Section: C Library Functions (3)<BR>Updated: 1 April 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec prng_init - initialize IPsec pseudorandom-number generator -<BR> - -ipsec prng_bytes - get bytes from IPsec pseudorandom-number generator -<BR> - -ipsec prng_final - close down IPsec pseudorandom-number generator -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>void prng_init(struct prng *prng,</B> - -<BR> - -<B>const unsigned char *key, size_t keylen);</B> - -<BR> - -<B>void prng_bytes(struct prng *prng, char *dst,</B> - -<BR> - -<B>size_t dstlen);</B> - -<BR> - -<B>unsigned long prng_count(struct prng *prng);</B> - -<BR> - -<B>void prng_final(struct prng *prng);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Prng_init</I> - -initializes a crypto-quality pseudo-random-number generator from a key; -<I>prng_bytes</I> - -obtains pseudo-random bytes from it; -<I>prng_count</I> - -reports the number of bytes extracted from it to date; -<I>prng_final</I> - -closes it down. -It is the user's responsibility to initialize a PRNG before using it, -and not to use it again after it is closed down. -<P> - -<I>Prng_init</I> - -initializes, -or re-initializes, -the specified -<I>prng</I> - -from the -<I>key</I>, - -whose length is given by -<I>keylen</I>. - -The user must allocate the -<B>struct prng</B> - -pointed to by -<I>prng</I>. - -There is no particular constraint on the length of the key, -although a key longer than 256 bytes is unnecessary because -only the first 256 would be used. -Initialization requires on the order of 3000 integer operations, -independent of key length. -<P> - -<I>Prng_bytes</I> - -obtains -<I>dstlen</I> - -pseudo-random bytes from the PRNG and puts them in -<I>buf</I>. - -This is quite fast, -on the order of 10 integer operations per byte. -<P> - -<I>Prng_count</I> - -reports the number of bytes obtained from the PRNG -since it was (last) initialized. -<P> - -<I>Prng_final</I> - -closes down a PRNG by -zeroing its internal memory, -obliterating all trace of the state used to generate its previous output. -This requires on the order of 250 integer operations. -<P> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file supplies the definition of the -<B>prng</B> - -structure. -Examination of its innards is discouraged, as they may change. -<P> - -The PRNG algorithm -used by these functions is currently identical to that of RC4(TM). -This algorithm is cryptographically strong, -sufficiently unpredictable that even a hostile observer will -have difficulty determining the next byte of output from past history, -provided it is initialized from a reasonably large key composed of -highly random bytes (see -<I><A HREF="random.4.html">random</A></I>(4)). - -The usual run of software pseudo-random-number generators -(e.g. -<I><A HREF="random.3.html">random</A></I>(3)) - -are -<I>not</I> - -cryptographically strong. -<P> - -The well-known attacks against RC4(TM), -e.g. as found in 802.11b's WEP encryption system, -apply only if multiple PRNGs are initialized with closely-related keys -(e.g., using a counter appended to a base key). -If such keys are used, the first few hundred pseudo-random bytes -from each PRNG should be discarded, -to give the PRNGs a chance to randomize their innards properly. -No useful attacks are known if the key is well randomized to begin with. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="random.3.html">random</A>(3), <A HREF="random.4.html">random</A>(4) -<BR> - -Bruce Schneier, -<I>Applied Cryptography</I>, 2nd ed., 1996, ISBN 0-471-11709-9, -pp. 397-8. -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAG"> </A> -<H2>BUGS</H2> - -If an attempt is made to obtain more than 4e9 bytes -between initializations, -the PRNG will continue to work but -<I>prng_count</I>'s - -output will stick at -<B>4000000000</B>. - -Fixing this would require a longer integer type and does -not seem worth the trouble, -since you should probably re-initialize before then anyway... -<P> - -``RC4'' is a trademark of RSA Data Security, Inc. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -<DT><A HREF="#lbAG">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_prng_init.3.html b/doc/manpage.d/ipsec_prng_init.3.html deleted file mode 100644 index 27763a2bb..000000000 --- a/doc/manpage.d/ipsec_prng_init.3.html +++ /dev/null @@ -1,204 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_PRNG</TITLE> -</HEAD><BODY> -<H1>IPSEC_PRNG</H1> -Section: C Library Functions (3)<BR>Updated: 1 April 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec prng_init - initialize IPsec pseudorandom-number generator -<BR> - -ipsec prng_bytes - get bytes from IPsec pseudorandom-number generator -<BR> - -ipsec prng_final - close down IPsec pseudorandom-number generator -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>void prng_init(struct prng *prng,</B> - -<BR> - -<B>const unsigned char *key, size_t keylen);</B> - -<BR> - -<B>void prng_bytes(struct prng *prng, char *dst,</B> - -<BR> - -<B>size_t dstlen);</B> - -<BR> - -<B>unsigned long prng_count(struct prng *prng);</B> - -<BR> - -<B>void prng_final(struct prng *prng);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Prng_init</I> - -initializes a crypto-quality pseudo-random-number generator from a key; -<I>prng_bytes</I> - -obtains pseudo-random bytes from it; -<I>prng_count</I> - -reports the number of bytes extracted from it to date; -<I>prng_final</I> - -closes it down. -It is the user's responsibility to initialize a PRNG before using it, -and not to use it again after it is closed down. -<P> - -<I>Prng_init</I> - -initializes, -or re-initializes, -the specified -<I>prng</I> - -from the -<I>key</I>, - -whose length is given by -<I>keylen</I>. - -The user must allocate the -<B>struct prng</B> - -pointed to by -<I>prng</I>. - -There is no particular constraint on the length of the key, -although a key longer than 256 bytes is unnecessary because -only the first 256 would be used. -Initialization requires on the order of 3000 integer operations, -independent of key length. -<P> - -<I>Prng_bytes</I> - -obtains -<I>dstlen</I> - -pseudo-random bytes from the PRNG and puts them in -<I>buf</I>. - -This is quite fast, -on the order of 10 integer operations per byte. -<P> - -<I>Prng_count</I> - -reports the number of bytes obtained from the PRNG -since it was (last) initialized. -<P> - -<I>Prng_final</I> - -closes down a PRNG by -zeroing its internal memory, -obliterating all trace of the state used to generate its previous output. -This requires on the order of 250 integer operations. -<P> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file supplies the definition of the -<B>prng</B> - -structure. -Examination of its innards is discouraged, as they may change. -<P> - -The PRNG algorithm -used by these functions is currently identical to that of RC4(TM). -This algorithm is cryptographically strong, -sufficiently unpredictable that even a hostile observer will -have difficulty determining the next byte of output from past history, -provided it is initialized from a reasonably large key composed of -highly random bytes (see -<I><A HREF="random.4.html">random</A></I>(4)). - -The usual run of software pseudo-random-number generators -(e.g. -<I><A HREF="random.3.html">random</A></I>(3)) - -are -<I>not</I> - -cryptographically strong. -<P> - -The well-known attacks against RC4(TM), -e.g. as found in 802.11b's WEP encryption system, -apply only if multiple PRNGs are initialized with closely-related keys -(e.g., using a counter appended to a base key). -If such keys are used, the first few hundred pseudo-random bytes -from each PRNG should be discarded, -to give the PRNGs a chance to randomize their innards properly. -No useful attacks are known if the key is well randomized to begin with. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="random.3.html">random</A>(3), <A HREF="random.4.html">random</A>(4) -<BR> - -Bruce Schneier, -<I>Applied Cryptography</I>, 2nd ed., 1996, ISBN 0-471-11709-9, -pp. 397-8. -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAG"> </A> -<H2>BUGS</H2> - -If an attempt is made to obtain more than 4e9 bytes -between initializations, -the PRNG will continue to work but -<I>prng_count</I>'s - -output will stick at -<B>4000000000</B>. - -Fixing this would require a longer integer type and does -not seem worth the trouble, -since you should probably re-initialize before then anyway... -<P> - -``RC4'' is a trademark of RSA Data Security, Inc. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -<DT><A HREF="#lbAG">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_ranbits.8.html b/doc/manpage.d/ipsec_ranbits.8.html deleted file mode 100644 index 036b2a351..000000000 --- a/doc/manpage.d/ipsec_ranbits.8.html +++ /dev/null @@ -1,147 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_RANBITS</TITLE> -</HEAD><BODY> -<H1>IPSEC_RANBITS</H1> -Section: Maintenance Commands (8)<BR>Updated: 22 Aug 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ranbits - generate random bits in ASCII form -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>ranbits</B> - -[ -<B>--quick</B> - -] [ -<B>--continuous</B> - -] [ -<B>--bytes</B> - -] nbits -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ranbits</I> - -obtains -<I>nbits</I> - -(rounded up to the nearest byte) -high-quality random bits from -<I><A HREF="random.4.html">random</A></I>(4), - -and emits them on standard output as an ASCII string. -The default output format is -<I><A HREF="datatot.3.html">datatot</A></I>(3) - -<B>h</B> - -format: -lowercase hexadecimal with a -<B>0x</B> - -prefix and an underscore every 32 bits. -<P> - -The -<B>--quick</B> - -option produces quick-and-dirty random bits: -instead of using the high-quality random bits from -<I>/dev/random</I>, - -which may take some time to supply the necessary bits if -<I>nbits</I> - -is large, -<I>ranbits</I> - -uses -<I>/dev/urandom</I>, - -which yields prompt results but lower-quality randomness. -<P> - -The -<B>--continuous</B> - -option uses -<I><A HREF="datatot.3.html">datatot</A></I>(3) - -<B>x</B> - -output format, like -<B>h</B> - -but without the underscores. -<P> - -The -<B>--bytes</B> - -option causes -<I>nbits</I> - -to be interpreted as a byte count rather than a bit count. -<A NAME="lbAE"> </A> -<H2>FILES</H2> - -/dev/random, /dev/urandom -<A NAME="lbAF"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec_datatot.3.html">ipsec_datatot</A>(3), <A HREF="random.4.html">random</A>(4) -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -There is an internal limit on -<I>nbits</I>, - -currently 20000. -<P> - -Without -<B>--quick</B>, - -<I>ranbits</I>'s - -run time is difficult to predict. -A request for a large number of bits, -at a time when the system's entropy pool is low on randomness, -may take quite a while to satisfy. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">SEE ALSO</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_rangetoa.3.html b/doc/manpage.d/ipsec_rangetoa.3.html deleted file mode 100644 index 3bacd5943..000000000 --- a/doc/manpage.d/ipsec_rangetoa.3.html +++ /dev/null @@ -1,294 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ATOASR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ATOASR</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec atoasr - convert ASCII to Internet address, subnet, or range -<BR> - -ipsec rangetoa - convert Internet address range to ASCII -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *atoasr(const char *src, size_t srclen,</B> - -<BR> - -<B>char *type, struct in_addr *addrs);</B> - -<BR> - -<B>size_t rangetoa(struct in_addr *addrs, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; -there is no current equivalent, -because so far they have not proved useful. -<P> - -<I>Atoasr</I> - -converts an ASCII address, subnet, or address range -into a suitable combination of binary addresses -(in network byte order). -<I>Rangetoa</I> - -converts an address range back into ASCII, -using dotted-decimal form for the addresses -(the other reverse conversions are handled by -<I><A HREF="ipsec_addrtoa.3.html">ipsec_addrtoa</A></I>(3) - -and -<I><A HREF="ipsec_subnettoa.3.html">ipsec_subnettoa</A></I>(3)). - -<P> - -A single address can be any form acceptable to -<I><A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A></I>(3): - -dotted decimal, DNS name, or hexadecimal number. -A subnet -specification uses the form <I>network</I><B>/</B><I>mask</I> -interpreted by -<I><A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A></I>(3). - -<P> - -An address range is two -<I><A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A></I>(3) - -addresses separated by a -<B>...</B> - -delimiter. -If there are four dots rather than three, the first is taken as -part of the begin address, -e.g. for a complete DNS name which ends with -<B>.</B> - -to suppress completion attempts. -The begin address of a range must be -less than or equal to the end address. -<P> - -The -<I>srclen</I> - -parameter of -<I>atoasr</I> - -specifies the length of the ASCII string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>type</I> - -parameter of -<I>atoasr</I> - -must point to a -<B>char</B> - -variable used to record which form was found. -The -<I>addrs</I> - -parameter must point to a two-element array of -<B>struct in_addr</B> - -which receives the results. -The values stored into -<B>*type</B>, - -and the corresponding values in the array, are: -<P> - - - -<TT> </TT>*typeaddrs[0]addrs[1]<BR> -<P> -address<B>'a'</B>address-<BR> -<BR> - -subnet<TT> </TT><B>'s'</B>networkmask<BR> -<BR> - -range<TT> </TT><B>'r'</B>beginend<BR> -<P> - -The -<I>dstlen</I> - -parameter of -<I>rangetoa</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines a constant, -<B>RANGETOA_BUF</B>, - -which is the size of a buffer just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>rangetoa</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the ASCII character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default, -and is in fact the only format currently available. -This parameter is a hedge against future needs. -<P> - -<I>Atoasr</I> - -returns NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<I>Rangetoa</I> - -returns -<B>0</B> - -for a failure, and otherwise -always returns the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A>(3), <A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>atoasr</I> - -are: -empty input; -error in -<I><A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A></I>(3) - -or -<I><A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A></I>(3) - -during conversion; -begin address of range exceeds end address. -<P> - -Fatal errors in -<I>rangetoa</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The restriction of error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = atoasr( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_rangetosubnet.3.html b/doc/manpage.d/ipsec_rangetosubnet.3.html deleted file mode 100644 index 9e03244ea..000000000 --- a/doc/manpage.d/ipsec_rangetosubnet.3.html +++ /dev/null @@ -1,116 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_RANGETOSUBNET</TITLE> -</HEAD><BODY> -<H1>IPSEC_RANGETOSUBNET</H1> -Section: C Library Functions (3)<BR>Updated: 8 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec rangetosubnet - convert address range to subnet -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *rangetosubnet(const ip_address *start,</B> - -<BR> - -<B>const ip_address *stop, ip_subnet *dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Rangetosubnet</I> - -accepts two IP addresses which define an address range, -from -<I>start</I> - -to -<I>stop</I> - -inclusive, -and converts this to a subnet if possible. -The addresses must both be IPv4 or both be IPv6, -and the address family of the resulting subnet is the same. -<P> - -<I>Rangetosubnet</I> - -returns NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec_initsubnet.3.html">ipsec_initsubnet</A>(3), <A HREF="ipsec_ttosubnet.3.html">ipsec_ttosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>rangetosubnet</I> - -are: -mixed address families; -unknown address family; -<I>start</I> - -and -<I>stop</I> - -do not define a subnet. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The restriction of error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = rangetosubnet( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_rsasigkey.8.html b/doc/manpage.d/ipsec_rsasigkey.8.html deleted file mode 100644 index 3173a9f13..000000000 --- a/doc/manpage.d/ipsec_rsasigkey.8.html +++ /dev/null @@ -1,401 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_RSASIGKEY</TITLE> -</HEAD><BODY> -<H1>IPSEC_RSASIGKEY</H1> -Section: Maintenance Commands (8)<BR>Updated: 22 July 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec rsasigkey - generate RSA signature key -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>rsasigkey</B> - -[ -<B>--verbose</B> - -] [ -<B>--random</B> - -filename -] -<B>\</B> - -<BR> - - [ -<B>--rounds</B> - -nr -] [ -<B>--hostname</B> - -host ] [ -<B>--noopt</B> - -] nbits -<BR> - -<B>ipsec</B> - -<B>rsasigkey</B> - -[ -<B>--verbose</B> - -] [ -<B>--hostname</B> - -host ] -<B>\</B> - -<BR> - - -[ -<B>--noopt</B> - -] -<B>--oldkey</B> - -file -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Rsasigkey</I> - -generates an RSA public/private key pair, -suitable for digital signatures, -of (exactly) -<I>nbits</I> - -bits (that is, two primes each of exactly -<I>nbits</I>/2 - -bits, -and related numbers) -and emits it on standard output as ASCII (mostly hex) data. -<I>nbits</I> - -must be a multiple of 16. -<P> - -The public exponent is forced to the value -<B>3</B>, - -which has important speed advantages for signature checking. -Beware that the resulting keys have known weaknesses as encryption keys -<I>and should not be used for that purpose</I>. -<P> - -The -<B>--verbose</B> - -option makes -<I>rsasigkey</I> - -give a running commentary on standard error. -By default, it works in silence until it is ready to generate output. -<P> - -The -<B>--random</B> - -option specifies a source for random bits. -The default is -<I>/dev/random</I> - -(see -<I><A HREF="random.4.html">random</A></I>(4)). - -Normally, -<I>rsasigkey</I> - -reads exactly -<I>nbits</I> - -random bits from the source; -in extremely-rare circumstances it may need more. -<P> - -The -<B>--rounds</B> - -option specifies the number of rounds to be done by the -<I>mpz_probab_prime_p</I> - -probabilistic primality checker. -The default, 30, is fairly rigorous and should not normally -have to be overridden. -<P> - -The -<B>--hostname</B> - -option specifies what host name to use in -the first line of the output (see below); -the default is what -<I><A HREF="gethostname.2.html">gethostname</A></I>(2) - -returns. -<P> - -The -<B>--noopt</B> - -option suppresses an optimization of the private key -(to be precise, setting of the decryption exponent to -<B>lcm(p-1,q-1)</B> - -rather than -<B>(p-1)*(q-1)</B>) - -which speeds up operations on it slightly -but can cause it to flunk a validity check in old RSA implementations -(notably, obsolete versions of -<I><A HREF="ipsec_pluto.8.html">ipsec_pluto</A></I>(8)). - -<P> - -The -<B>--oldkey</B> - -option specifies that rather than generate a new key, -<I>rsasigkey</I> - -should read an old key from the -<I>file</I> - -(the name -<B>-</B> - -means ``standard input'') -and use that to generate its output. -Input lines which do not look like -<I>rsasigkey</I> - -output are silently ignored. -This permits updating old keys to the current format. -<P> - -The output format looks like this (with long numbers trimmed down -for clarity): -<P> - - -<PRE> - # RSA 2048 bits xy.example.com Sat Apr 15 13:53:22 2000 - # for signatures only, UNSAFE FOR ENCRYPTION - #pubkey=0sAQOF8tZ2NZt...Y1P+buFuFn/ - Modulus: 0xcc2a86fcf440...cf1011abb82d1 - PublicExponent: 0x03 - # everything after this point is secret - PrivateExponent: 0x881c59fdf8...ab05c8c77d23 - Prime1: 0xf49fd1f779...46504c7bf3 - Prime2: 0xd5a9108453...321d43cb2b - Exponent1: 0xa31536a4fb...536d98adda7f7 - Exponent2: 0x8e70b5ad8d...9142168d7dcc7 - Coefficient: 0xafb761d001...0c13e98d98 -</PRE> - -<P> - -The first (comment) line, -indicating the nature and date of the key, -and giving a host name, -is used by -<I><A HREF="ipsec_showhostkey.8.html">ipsec_showhostkey</A></I>(8) - -when generating some forms of key output. -<P> - -The commented-out -<B>pubkey=</B> - -line contains the public key---the public exponent and the modulus---combined -in approximately RFC 2537 format -(the one deviation is that the combined value is given with a -<B>0s</B> - -prefix, rather than in unadorned base-64), -suitable for use in the -<I>ipsec.conf</I> - -file. -<P> - -The -<B>Modulus</B>, - -<B>PublicExponent</B>, - -and -<B>PrivateExponent</B> - -lines give the basic signing and verification data. -<P> - -The -<B>Prime1</B> - -and -<B>Prime2</B> - -lines give the primes themselves (aka -<I>p</I> - -and -<I>q</I>), - -largest first. -The -<B>Exponent1</B> - -and -<B>Exponent2</B> - -lines give -the private exponent mod -<I>p-1</I> - -and -<I>q-1</I> - -respectively. -The -<B>Coefficient</B> - -line gives the Chinese Remainder Theorem coefficient, -which is the inverse of -<I>q</I>, - -mod -<I>p</I>. - -These additional numbers (which must all be kept as secret as the -private exponent) are precomputed aids to rapid signature generation. -<P> - -No attempt is made to break long lines. -<P> - -The US patent on the RSA algorithm expired 20 Sept 2000. -<A NAME="lbAE"> </A> -<H2>EXAMPLES</H2> - -<DL COMPACT> -<DT><B>ipsec rsasigkey --verbose 2192 >mykey</B> - -<DD> -generates a 2192-bit signature key and puts it in the file -<I>mykey</I>, - -with running commentary on standard error. -The file contents can be inserted verbatim into a suitable entry in the -<I>ipsec.secrets</I> - -file (see -<I><A HREF="ipsec.secrets.5.html">ipsec.secrets</A></I>(5)), - -and the public key can then be extracted and edited into the -<I>ipsec.conf</I> - -file (see -<I><A HREF="ipsec.conf.5.html">ipsec.conf</A></I>(5)). - -<DT><B>ipsec rsasigkey --verbose --oldkey oldie >latest</B> - -<DD> -takes the old signature key from file -<I>oldie</I> - -and puts a version in the current format into the file -<I>latest</I>, - -with running commentary on standard error. -</DL> -<A NAME="lbAF"> </A> -<H2>FILES</H2> - -/dev/random -<A NAME="lbAG"> </A> -<H2>SEE ALSO</H2> - -<A HREF="random.4.html">random</A>(4), <A HREF="ipsec_showhostkey.8.html">ipsec_showhostkey</A>(8) -<BR> - -<I>Applied Cryptography</I>, 2nd. ed., by Bruce Schneier, Wiley 1996. -<BR> - -RFCs 2537, 2313. -<BR> - -<I>GNU MP, the GNU multiple precision arithmetic library, edition 2.0.2</I>, -by Torbj Granlund. -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Henry Spencer. -<A NAME="lbAI"> </A> -<H2>BUGS</H2> - -There is an internal limit on -<I>nbits</I>, - -currently 20000. -<P> - -<I>Rsasigkey</I>'s - -run time is difficult to predict, -since -<I>/dev/random</I> - -output can be arbitrarily delayed if -the system's entropy pool is low on randomness, -and the time taken by the search for primes is also somewhat unpredictable. -A reasonably typical time for a 1024-bit key on a quiet 200MHz Pentium MMX -with plenty of randomness available is 20 seconds, -almost all of it in the prime searches. -Generating a 2192-bit key on the same system usually takes several minutes. -A 4096-bit key took an hour and a half of CPU time. -<P> - -The -<B>--oldkey</B> - -option does not check its input format as rigorously as it might. -Corrupted -<I>rsasigkey</I> - -output may confuse it. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">EXAMPLES</A><DD> -<DT><A HREF="#lbAF">FILES</A><DD> -<DT><A HREF="#lbAG">SEE ALSO</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -<DT><A HREF="#lbAI">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_sameaddr.3.html b/doc/manpage.d/ipsec_sameaddr.3.html deleted file mode 100644 index 414a0d513..000000000 --- a/doc/manpage.d/ipsec_sameaddr.3.html +++ /dev/null @@ -1,274 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Nov 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec sameaddr - are two addresses the same? -<BR> - -ipsec addrcmp - ordered comparison of addresses -<BR> - -ipsec samesubnet - are two subnets the same? -<BR> - -ipsec addrinsubnet - is an address within a subnet? -<BR> - -ipsec subnetinsubnet - is a subnet within another subnet? -<BR> - -ipsec subnetishost - is a subnet a single host? -<BR> - -ipsec samesaid - are two SA IDs the same? -<BR> - -ipsec sameaddrtype - are two addresses of the same address family? -<BR> - -ipsec samesubnettype - are two subnets of the same address family? -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int sameaddr(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int addrcmp(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int addrinsubnet(const ip_address *a, const ip_subnet *s);</B> - -<BR> - -<B>int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int subnetishost(const ip_subnet *s);</B> - -<BR> - -<B>int samesaid(const ip_said *a, const ip_said *b);</B> - -<BR> - -<B>int sameaddrtype(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnettype(const ip_subnet *a, const ip_subnet *b);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions do various comparisons and tests on the -<I>ip_address</I> - -type and -<I>ip_subnet</I> - -types. -<P> - -<I>Sameaddr</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Addresses of different families are never identical. -<P> - -<I>Addrcmp</I> - -returns -<B>-1</B>, - -<B>0</B>, - -or -<B>1</B> - -respectively -if address -<I>a</I> - -is less than, equal to, or greater than -<I>b</I>. - -If they are not of the same address family, -they are never equal; -the ordering reported in this case is arbitrary -(and probably not useful) but consistent. -<P> - -<I>Samesubnet</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Subnets of different address families are never identical. -<P> - -<I>Addrinsubnet</I> - -returns -non-zero -if address -<I>a</I> - -is within subnet -<I>s</I> - -and -<B>0</B> - -otherwise. -An address is never within a -subnet of a different address family. -<P> - -<I>Subnetinsubnet</I> - -returns -non-zero -if subnet -<I>a</I> - -is a subset of subnet -<I>b</I> - -and -<B>0</B> - -otherwise. -A subnet is deemed to be a subset of itself. -A subnet is never a subset of another -subnet if their address families differ. -<P> - -<I>Subnetishost</I> - -returns -non-zero -if subnet -<I>s</I> - -is in fact only a single host, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesaid</I> - -returns -non-zero -if SA IDs -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -<P> - -<I>Sameaddrtype</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesubnettype</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_initaddr.3.html">ipsec_initaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_sameaddrtype.3.html b/doc/manpage.d/ipsec_sameaddrtype.3.html deleted file mode 100644 index 414a0d513..000000000 --- a/doc/manpage.d/ipsec_sameaddrtype.3.html +++ /dev/null @@ -1,274 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Nov 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec sameaddr - are two addresses the same? -<BR> - -ipsec addrcmp - ordered comparison of addresses -<BR> - -ipsec samesubnet - are two subnets the same? -<BR> - -ipsec addrinsubnet - is an address within a subnet? -<BR> - -ipsec subnetinsubnet - is a subnet within another subnet? -<BR> - -ipsec subnetishost - is a subnet a single host? -<BR> - -ipsec samesaid - are two SA IDs the same? -<BR> - -ipsec sameaddrtype - are two addresses of the same address family? -<BR> - -ipsec samesubnettype - are two subnets of the same address family? -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int sameaddr(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int addrcmp(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int addrinsubnet(const ip_address *a, const ip_subnet *s);</B> - -<BR> - -<B>int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int subnetishost(const ip_subnet *s);</B> - -<BR> - -<B>int samesaid(const ip_said *a, const ip_said *b);</B> - -<BR> - -<B>int sameaddrtype(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnettype(const ip_subnet *a, const ip_subnet *b);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions do various comparisons and tests on the -<I>ip_address</I> - -type and -<I>ip_subnet</I> - -types. -<P> - -<I>Sameaddr</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Addresses of different families are never identical. -<P> - -<I>Addrcmp</I> - -returns -<B>-1</B>, - -<B>0</B>, - -or -<B>1</B> - -respectively -if address -<I>a</I> - -is less than, equal to, or greater than -<I>b</I>. - -If they are not of the same address family, -they are never equal; -the ordering reported in this case is arbitrary -(and probably not useful) but consistent. -<P> - -<I>Samesubnet</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Subnets of different address families are never identical. -<P> - -<I>Addrinsubnet</I> - -returns -non-zero -if address -<I>a</I> - -is within subnet -<I>s</I> - -and -<B>0</B> - -otherwise. -An address is never within a -subnet of a different address family. -<P> - -<I>Subnetinsubnet</I> - -returns -non-zero -if subnet -<I>a</I> - -is a subset of subnet -<I>b</I> - -and -<B>0</B> - -otherwise. -A subnet is deemed to be a subset of itself. -A subnet is never a subset of another -subnet if their address families differ. -<P> - -<I>Subnetishost</I> - -returns -non-zero -if subnet -<I>s</I> - -is in fact only a single host, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesaid</I> - -returns -non-zero -if SA IDs -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -<P> - -<I>Sameaddrtype</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesubnettype</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_initaddr.3.html">ipsec_initaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_samesaid.3.html b/doc/manpage.d/ipsec_samesaid.3.html deleted file mode 100644 index 414a0d513..000000000 --- a/doc/manpage.d/ipsec_samesaid.3.html +++ /dev/null @@ -1,274 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Nov 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec sameaddr - are two addresses the same? -<BR> - -ipsec addrcmp - ordered comparison of addresses -<BR> - -ipsec samesubnet - are two subnets the same? -<BR> - -ipsec addrinsubnet - is an address within a subnet? -<BR> - -ipsec subnetinsubnet - is a subnet within another subnet? -<BR> - -ipsec subnetishost - is a subnet a single host? -<BR> - -ipsec samesaid - are two SA IDs the same? -<BR> - -ipsec sameaddrtype - are two addresses of the same address family? -<BR> - -ipsec samesubnettype - are two subnets of the same address family? -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int sameaddr(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int addrcmp(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int addrinsubnet(const ip_address *a, const ip_subnet *s);</B> - -<BR> - -<B>int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int subnetishost(const ip_subnet *s);</B> - -<BR> - -<B>int samesaid(const ip_said *a, const ip_said *b);</B> - -<BR> - -<B>int sameaddrtype(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnettype(const ip_subnet *a, const ip_subnet *b);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions do various comparisons and tests on the -<I>ip_address</I> - -type and -<I>ip_subnet</I> - -types. -<P> - -<I>Sameaddr</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Addresses of different families are never identical. -<P> - -<I>Addrcmp</I> - -returns -<B>-1</B>, - -<B>0</B>, - -or -<B>1</B> - -respectively -if address -<I>a</I> - -is less than, equal to, or greater than -<I>b</I>. - -If they are not of the same address family, -they are never equal; -the ordering reported in this case is arbitrary -(and probably not useful) but consistent. -<P> - -<I>Samesubnet</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Subnets of different address families are never identical. -<P> - -<I>Addrinsubnet</I> - -returns -non-zero -if address -<I>a</I> - -is within subnet -<I>s</I> - -and -<B>0</B> - -otherwise. -An address is never within a -subnet of a different address family. -<P> - -<I>Subnetinsubnet</I> - -returns -non-zero -if subnet -<I>a</I> - -is a subset of subnet -<I>b</I> - -and -<B>0</B> - -otherwise. -A subnet is deemed to be a subset of itself. -A subnet is never a subset of another -subnet if their address families differ. -<P> - -<I>Subnetishost</I> - -returns -non-zero -if subnet -<I>s</I> - -is in fact only a single host, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesaid</I> - -returns -non-zero -if SA IDs -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -<P> - -<I>Sameaddrtype</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesubnettype</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_initaddr.3.html">ipsec_initaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_samesubnet.3.html b/doc/manpage.d/ipsec_samesubnet.3.html deleted file mode 100644 index 414a0d513..000000000 --- a/doc/manpage.d/ipsec_samesubnet.3.html +++ /dev/null @@ -1,274 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Nov 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec sameaddr - are two addresses the same? -<BR> - -ipsec addrcmp - ordered comparison of addresses -<BR> - -ipsec samesubnet - are two subnets the same? -<BR> - -ipsec addrinsubnet - is an address within a subnet? -<BR> - -ipsec subnetinsubnet - is a subnet within another subnet? -<BR> - -ipsec subnetishost - is a subnet a single host? -<BR> - -ipsec samesaid - are two SA IDs the same? -<BR> - -ipsec sameaddrtype - are two addresses of the same address family? -<BR> - -ipsec samesubnettype - are two subnets of the same address family? -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int sameaddr(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int addrcmp(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int addrinsubnet(const ip_address *a, const ip_subnet *s);</B> - -<BR> - -<B>int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int subnetishost(const ip_subnet *s);</B> - -<BR> - -<B>int samesaid(const ip_said *a, const ip_said *b);</B> - -<BR> - -<B>int sameaddrtype(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnettype(const ip_subnet *a, const ip_subnet *b);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions do various comparisons and tests on the -<I>ip_address</I> - -type and -<I>ip_subnet</I> - -types. -<P> - -<I>Sameaddr</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Addresses of different families are never identical. -<P> - -<I>Addrcmp</I> - -returns -<B>-1</B>, - -<B>0</B>, - -or -<B>1</B> - -respectively -if address -<I>a</I> - -is less than, equal to, or greater than -<I>b</I>. - -If they are not of the same address family, -they are never equal; -the ordering reported in this case is arbitrary -(and probably not useful) but consistent. -<P> - -<I>Samesubnet</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Subnets of different address families are never identical. -<P> - -<I>Addrinsubnet</I> - -returns -non-zero -if address -<I>a</I> - -is within subnet -<I>s</I> - -and -<B>0</B> - -otherwise. -An address is never within a -subnet of a different address family. -<P> - -<I>Subnetinsubnet</I> - -returns -non-zero -if subnet -<I>a</I> - -is a subset of subnet -<I>b</I> - -and -<B>0</B> - -otherwise. -A subnet is deemed to be a subset of itself. -A subnet is never a subset of another -subnet if their address families differ. -<P> - -<I>Subnetishost</I> - -returns -non-zero -if subnet -<I>s</I> - -is in fact only a single host, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesaid</I> - -returns -non-zero -if SA IDs -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -<P> - -<I>Sameaddrtype</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesubnettype</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_initaddr.3.html">ipsec_initaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_samesubnettype.3.html b/doc/manpage.d/ipsec_samesubnettype.3.html deleted file mode 100644 index 414a0d513..000000000 --- a/doc/manpage.d/ipsec_samesubnettype.3.html +++ /dev/null @@ -1,274 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Nov 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec sameaddr - are two addresses the same? -<BR> - -ipsec addrcmp - ordered comparison of addresses -<BR> - -ipsec samesubnet - are two subnets the same? -<BR> - -ipsec addrinsubnet - is an address within a subnet? -<BR> - -ipsec subnetinsubnet - is a subnet within another subnet? -<BR> - -ipsec subnetishost - is a subnet a single host? -<BR> - -ipsec samesaid - are two SA IDs the same? -<BR> - -ipsec sameaddrtype - are two addresses of the same address family? -<BR> - -ipsec samesubnettype - are two subnets of the same address family? -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int sameaddr(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int addrcmp(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int addrinsubnet(const ip_address *a, const ip_subnet *s);</B> - -<BR> - -<B>int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int subnetishost(const ip_subnet *s);</B> - -<BR> - -<B>int samesaid(const ip_said *a, const ip_said *b);</B> - -<BR> - -<B>int sameaddrtype(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnettype(const ip_subnet *a, const ip_subnet *b);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions do various comparisons and tests on the -<I>ip_address</I> - -type and -<I>ip_subnet</I> - -types. -<P> - -<I>Sameaddr</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Addresses of different families are never identical. -<P> - -<I>Addrcmp</I> - -returns -<B>-1</B>, - -<B>0</B>, - -or -<B>1</B> - -respectively -if address -<I>a</I> - -is less than, equal to, or greater than -<I>b</I>. - -If they are not of the same address family, -they are never equal; -the ordering reported in this case is arbitrary -(and probably not useful) but consistent. -<P> - -<I>Samesubnet</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Subnets of different address families are never identical. -<P> - -<I>Addrinsubnet</I> - -returns -non-zero -if address -<I>a</I> - -is within subnet -<I>s</I> - -and -<B>0</B> - -otherwise. -An address is never within a -subnet of a different address family. -<P> - -<I>Subnetinsubnet</I> - -returns -non-zero -if subnet -<I>a</I> - -is a subset of subnet -<I>b</I> - -and -<B>0</B> - -otherwise. -A subnet is deemed to be a subset of itself. -A subnet is never a subset of another -subnet if their address families differ. -<P> - -<I>Subnetishost</I> - -returns -non-zero -if subnet -<I>s</I> - -is in fact only a single host, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesaid</I> - -returns -non-zero -if SA IDs -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -<P> - -<I>Sameaddrtype</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesubnettype</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_initaddr.3.html">ipsec_initaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_satoa.3.html b/doc/manpage.d/ipsec_satoa.3.html deleted file mode 100644 index 2b2c7425c..000000000 --- a/doc/manpage.d/ipsec_satoa.3.html +++ /dev/null @@ -1,347 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ATOSA</TITLE> -</HEAD><BODY> -<H1>IPSEC_ATOSA</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec atosa, satoa - convert IPsec Security Association IDs to and from ASCII -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *atosa(const char *src, size_t srclen,</B> - -<BR> - -<B>struct sa_id *sa);</B> - -<BR> - -<B>size_t satoa(struct sa_id sa, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<P> -<B>struct sa_id {</B> - -<BR> - -<B>struct in_addr dst;</B> - -<BR> - -<B>ipsec_spi_t spi;</B> - -<BR> - -<B>int proto;</B> - -<BR> - -<B>};</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; see -<I><A HREF="ipsec_ttosa.3.html">ipsec_ttosa</A></I>(3) - -for their replacements. -<P> - -<I>Atosa</I> - -converts an ASCII Security Association (SA) specifier into an -<B>sa_id</B> - -structure (containing -a destination-host address -in network byte order, -an SPI number in network byte order, and -a protocol code). -<I>Satoa</I> - -does the reverse conversion, back to an ASCII SA specifier. -<P> - -An SA is specified in ASCII with a mail-like syntax, e.g. -<B><A HREF="mailto:esp507@1.2.3.4">esp507@1.2.3.4</A></B>. - -An SA specifier contains -a protocol prefix (currently -<B>ah</B>, - -<B>esp</B>, - -or -<B>tun</B>), - -an unsigned integer SPI number, -and an IP address. -The SPI number can be decimal or hexadecimal -(with -<B>0x</B> - -prefix), as accepted by -<I><A HREF="ipsec_atoul.3.html">ipsec_atoul</A></I>(3). - -The IP address can be any form accepted by -<I><A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A></I>(3), - -e.g. dotted-decimal address or DNS name. -<P> - -As a special case, the SA specifier -<B>%passthrough</B> - -signifies the special SA used to indicate that packets should be -passed through unaltered. -(At present, this is a synonym for -<B><A HREF="mailto:tun0x0@0.0.0.0">tun0x0@0.0.0.0</A></B>, - -but that is subject to change without notice.) -This form is known to both -<I>atosa</I> - -and -<I>satoa</I>, - -so the internal form of -<B>%passthrough</B> - -is never visible. -<P> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file supplies the -<B>sa_id</B> - -structure, as well as a data type -<B>ipsec_spi_t</B> - -which is an unsigned 32-bit integer. -(There is no consistency between kernel and user on what such a type -is called, hence the header hides the differences.) -<P> - -The protocol code uses the same numbers that IP does. -For user convenience, given the difficulty in acquiring the exact set of -protocol names used by the kernel, -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -defines the names -<B>SA_ESP</B>, - -<B>SA_AH</B>, - -and -<B>SA_IPIP</B> - -to have the same values as the kernel names -<B>IPPROTO_ESP</B>, - -<B>IPPROTO_AH</B>, - -and -<B>IPPROTO_IPIP</B>. - -<P> - -The -<I>srclen</I> - -parameter of -<I>atosa</I> - -specifies the length of the ASCII string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>satoa</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines a constant, -<B>SATOA_BUF</B>, - -which is the size of a buffer just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>satoa</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the ASCII character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default -(currently -lowercase protocol prefix, lowercase hexadecimal SPI, dotted-decimal address). -The value -<B>d</B> - -causes the SPI to be generated in decimal instead. -<P> - -<I>Atosa</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<I>Satoa</I> - -returns -<B>0</B> - -for a failure, and otherwise -always returns the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec_atoul.3.html">ipsec_atoul</A>(3), <A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A>(3), <A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>atosa</I> - -are: -empty input; -input too small to be a legal SA specifier; -no -<B>@</B> - -in input; -unknown protocol prefix; -conversion error in -<I>atoul</I> - -or -<I>atoaddr</I>. - -<P> - -Fatal errors in -<I>satoa</I> - -are: -unknown format; unknown protocol code. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The -<B>tun</B> - -protocol code is a FreeS/WANism which may eventually disappear. -<P> - -The restriction of ASCII-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The ASCII-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = atoaddr( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_satot.3.html b/doc/manpage.d/ipsec_satot.3.html deleted file mode 100644 index 1e457fc24..000000000 --- a/doc/manpage.d/ipsec_satot.3.html +++ /dev/null @@ -1,453 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TTOSA</TITLE> -</HEAD><BODY> -<H1>IPSEC_TTOSA</H1> -Section: C Library Functions (3)<BR>Updated: 26 Nov 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ttosa, satot - convert IPsec Security Association IDs to and from text -<BR> - -ipsec initsaid - initialize an SA ID -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>typedef struct {</B> - -<BR> - -<B>ip_address dst;</B> - -<BR> - -<B>ipsec_spi_t spi;</B> - -<BR> - -<B>int proto;</B> - -<BR> - -<B>} ip_said;</B> - -<P> -<B>const char *ttosa(const char *src, size_t srclen,</B> - -<BR> - -<B>ip_said *sa);</B> - -<BR> - -<B>size_t satot(const ip_said *sa, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<BR> - -<B>void initsaid(const ip_address *addr, ipsec_spi_t spi,</B> - -<BR> - -<B>int proto, ip_said *dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ttosa</I> - -converts an ASCII Security Association (SA) specifier into an -<B>ip_said</B> - -structure (containing -a destination-host address -in network byte order, -an SPI number in network byte order, and -a protocol code). -<I>Satot</I> - -does the reverse conversion, back to a text SA specifier. -<I>Initsaid</I> - -initializes an -<B>ip_said</B> - -from separate items of information. -<P> - -An SA is specified in text with a mail-like syntax, e.g. -<B><A HREF="mailto:esp.5a7@1.2.3.4">esp.5a7@1.2.3.4</A></B>. - -An SA specifier contains -a protocol prefix (currently -<B>ah</B>, - -<B>esp</B>, - -<B>tun</B>, - -<B>comp</B>, - -or -<B>int</B>), - -a single character indicating the address family -(<B>.</B> - -for IPv4, -<B>:</B> - -for IPv6), -an unsigned integer SPI number in hexadecimal (with no -<B>0x</B> - -prefix), -and an IP address. -The IP address can be any form accepted by -<I><A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A></I>(3), - -e.g. dotted-decimal IPv4 address, -colon-hex IPv6 address, -or DNS name. -<P> - -As a special case, the SA specifier -<B>%passthrough4</B> - -or -<B>%passthrough6</B> - -signifies the special SA used to indicate that packets should be -passed through unaltered. -(At present, these are synonyms for -<B><A HREF="mailto:tun.0@0.0.0.0">tun.0@0.0.0.0</A></B> - -and -<B>tun:0@::</B> - -respectively, -but that is subject to change without notice.) -<B>%passthrough</B> - -is a historical synonym for -<B>%passthrough4</B>. - -These forms are known to both -<I>ttosa</I> - -and -<I>satot</I>, - -so the internal representation is never visible. -<P> - -Similarly, the SA specifiers -<B>%pass</B>, - -<B>%drop</B>, - -<B>%reject</B>, - -<B>%hold</B>, - -<B>%trap</B>, - -and -<B>%trapsubnet</B> - -signify special ``magic'' SAs used to indicate that packets should be -passed, dropped, rejected (dropped with ICMP notification), -held, -and trapped (sent up to -<I><A HREF="ipsec_pluto.8.html">ipsec_pluto</A></I>(8), - -with either of two forms of -<B>%hold</B> - -automatically installed) -respectively. -These forms too are known to both routines, -so the internal representation of the magic SAs should never be visible. -<P> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file supplies the -<B>ip_said</B> - -structure, as well as a data type -<B>ipsec_spi_t</B> - -which is an unsigned 32-bit integer. -(There is no consistency between kernel and user on what such a type -is called, hence the header hides the differences.) -<P> - -The protocol code uses the same numbers that IP does. -For user convenience, given the difficulty in acquiring the exact set of -protocol names used by the kernel, -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -defines the names -<B>SA_ESP</B>, - -<B>SA_AH</B>, - -<B>SA_IPIP</B>, - -and -<B>SA_COMP</B> - -to have the same values as the kernel names -<B>IPPROTO_ESP</B>, - -<B>IPPROTO_AH</B>, - -<B>IPPROTO_IPIP</B>, - -and -<B>IPPROTO_COMP</B>. - -<P> - -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -also defines -<B>SA_INT</B> - -to have the value -<B>61</B> - -(reserved by IANA for ``any host internal protocol'') -and -<B>SPI_PASS</B>, - -<B>SPI_DROP</B>, - -<B>SPI_REJECT</B>, - -<B>SPI_HOLD</B>, - -and -<B>SPI_TRAP</B> - -to have the values 256-260 (in <I>host</I> byte order) respectively. -These are used in constructing the magic SAs -(which always have address -<B>0.0.0.0</B>). - -<P> - -If -<I>satot</I> - -encounters an unknown protocol code, e.g. 77, -it yields output using a prefix -showing the code numerically, e.g. ``unk77''. -This form is -<I>not</I> - -recognized by -<I>ttosa</I>. - -<P> - -The -<I>srclen</I> - -parameter of -<I>ttosa</I> - -specifies the length of the string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>satot</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file defines a constant, -<B>SATOT_BUF</B>, - -which is the size of a buffer just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>satot</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the ASCII character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default -(currently -lowercase protocol prefix, lowercase hexadecimal SPI, -dotted-decimal or colon-hex address). -The value -<B>'f'</B> - -is similar except that the SPI is padded with -<B>0</B>s - -to a fixed 32-bit width, to ease aligning displayed tables. -<P> - -<I>Ttosa</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<I>Satot</I> - -returns -<B>0</B> - -for a failure, and otherwise -always returns the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<P> - -There is also, temporarily, support for some obsolete -forms of SA specifier which lack the address-family indicator. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec_ttoul.3.html">ipsec_ttoul</A>(3), <A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A>(3), <A HREF="ipsec_samesaid.3.html">ipsec_samesaid</A>(3), <A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>ttosa</I> - -are: -empty input; -input too small to be a legal SA specifier; -no -<B>@</B> - -in input; -unknown protocol prefix; -conversion error in -<I>ttoul</I> - -or -<I>ttoaddr</I>. - -<P> - -Fatal errors in -<I>satot</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The restriction of text-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The text-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = ttosa( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_send-pr.8.html b/doc/manpage.d/ipsec_send-pr.8.html deleted file mode 100644 index 19026543a..000000000 --- a/doc/manpage.d/ipsec_send-pr.8.html +++ /dev/null @@ -1,427 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of SEND-PR</TITLE> -</HEAD><BODY> -<H1>SEND-PR</H1> -Section: User Commands (1)<BR>Updated: xVERSIONx<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec send-pr - send problem report (PR) to a central support site -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec send-pr</B> - -[ -<I>site</I> - -] -[ -<B>-f</B> - -<I>problem-report</I> - -] -[ -<B>-t</B> - -<I>mail-address</I> - -] -<BR> - - -[ -<B>-P</B> - -] -[ -<B>-L</B> - -] -[ -<B>-s</B> - -<I>severity</I> - -] -[ -<B>-c</B> - -<I>address</I> - -] -<BR> - -[ -<B>--request-id</B> - -] -[ -<B>-V</B> - -] -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<B>ipsec send-pr</B> - -is a tool used to submit -<I>problem reports </I> - - -(PRs) to a central support site. In most cases the correct -<I>site</I> - -will be the default. This argument indicates the support site which -is responsible for the category of problem involved. Some sites may -use a local address as a default. -<I>site</I> - -values are defined by using the -<B><A HREF="aliases.5.html">aliases</A></B>(5). - -<P> - -<B>ipsec send-pr</B> - -invokes an editor on a problem report template (after trying to fill -in some fields with reasonable default values). When you exit the -editor, -<B>ipsec send-pr </B> - -sends the completed form to the -<I>Problem Report Management System</I> - -(<B>GNATS</B>) at a central support site. At the support site, the PR -is assigned a unique number and is stored in the <B>GNATS</B> database -according to its category and submitter-id. <B>GNATS</B> automatically -replies with an acknowledgement, citing the category and the PR -number. -<P> - -To ensure that a PR is handled promptly, it should contain your (unique) -<I>submitter-id</I> and one of the available <I>categories</I> to identify the -problem area. (Use -<B>`ipsec send-pr -L'</B> - -to see a list of categories.) -<P> - -The -<B>ipsec send-pr</B> - -template at your site should already be customized with your -submitter-id (running `<B>install-sid</B> <I>submitter-id</I>' to -accomplish this is part of the installation procedures for -<B>ipsec</B>send-pr<B>).</B> - -If this hasn't been done, see your system administrator for your -submitter-id, or request one from your support site by invoking -<B>`ipsec send-pr --request-id'.</B> - -If your site does not distinguish between different user sites, or if -you are not affiliated with the support site, use -<B>`net'</B> - -for this field. -<P> - -The more precise your problem description and the more complete your -information, the faster your support team can solve your problems. -<A NAME="lbAE"> </A> -<H2>OPTIONS</H2> - -<DL COMPACT> -<DT><B>-f</B><I> problem-report</I> - -<DD> -specify a file (<I>problem-report</I>) which already contains a -complete problem report. -<B>ipsec send-pr</B> - -sends the contents of the file without invoking the editor. If -the value for -<I>problem-report</I> - -is -<B>`-'</B>, - -then -<B>ipsec send-pr</B> - -reads from standard input. -<DT><B>-s</B><I> severity</I> - -<DD> -Give the problem report the severity -<I>severity</I>. - -<DT><B>-t</B><I> mail-address</I> - -<DD> -Change mail address at the support site for problem reports. The -default -<I>mail-address</I> - -is the address used for the default -<I>site</I>. - -Use the -<I>site</I> - -argument rather than this option in nearly all cases. -<DT><B>-c</B><I> address</I> - -<DD> -Put -<I>address</I> - -in the -<B>Cc:</B> - -header of the message. -<DT><B>-P</B> - -<DD> -print the form specified by the environment variable -<B>PR_FORM </B> - -on standard output. If -<B>PR_FORM</B> - -is not set, print the standard blank PR template. No mail is sent. -<DT><B>-L</B> - -<DD> -print the list of available categories. No mail is sent. -<DT><B>--request-id</B> - -<DD> -sends mail to the default support site, or -<I>site</I> - -if specified, with a request for your -<I>submitter-id</I>. - -If you are -not affiliated with -<I>site</I>, - -use a -<I>submitter-id</I> - -of -<B>net</B>'. - -<DT><B>-V</B> - -<DD> -Display the -<B>ipsec send-pr</B> - -version number. -</DL> -<P> - -Note: use -<B>ipsec send-pr</B> - -to submit problem reports rather than mailing them directly. Using -both the template and -<B>ipsec send-pr</B> - -itself will help ensure all necessary information will reach the -support site. -<A NAME="lbAF"> </A> -<H2>ENVIRONMENT</H2> - -The environment variable -<B>EDITOR</B> - -specifies the editor to invoke on the template. -<BR> - -default: -<B>vi</B> - -<P> -If the environment variable -<B>PR_FORM</B> - -is set, then its value is used as the file name of the template for -your problem-report editing session. You can use this to start with a -partially completed form (for example, a form with the identification -fields already completed). -<A NAME="lbAG"> </A> -<H2>HOW TO FILL OUT A PROBLEM REPORT</H2> - -Problem reports have to be in a particular form so that a program can -easily manage them. Please remember the following guidelines: -<DL COMPACT> -<DT>*<DD> -describe only -<B>one problem</B> - -with each problem report. -<DT>*<DD> -For follow-up mail, use the same subject line as the one in the automatic -acknowledgent. It consists of category, PR number and the original synopsis -line. This allows the support site to relate several mail messages to a -particular PR and to record them automatically. -<DT>*<DD> -Please try to be as accurate as possible in the subject and/or synopsis line. -<DT>*<DD> -The subject and the synopsis line are not confidential. This is -because open-bugs lists are compiled from them. Avoid confidential -information there. -</DL> -<P> - -See the GNU -<B>Info </B> - -file -<B>send-pr.info</B> - -or the document <I>Reporting Problems With send-pr</I> for detailed -information on reporting problems -<A NAME="lbAH"> </A> -<H2>HOW TO SUBMIT TEST CASES, CODE, ETC.</H2> - -Submit small code samples with the PR. Contact the support site for -instructions on submitting larger test cases and problematic source -code. -<A NAME="lbAI"> </A> -<H2>FILES</H2> - - - -/tmp/p$$<TT> </TT>copy of PR used in editing session<BR> -<BR> - -/tmp/pf$$<TT> </TT>copy of empty PR form, for testing purposes<BR> -<BR> - -/tmp/pbad$$<TT> </TT>file for rejected PRs<BR> -<BR> - -@IPSEC_DIR@/send-pr.confscript to customize send-pr.<BR> -<A NAME="lbAJ"> </A> -<H2>EMACS USER INTERFACE</H2> - -An Emacs user interface for -<B>send-pr</B> - -with completion of field values is part of the -<B>send-pr</B> - -distribution (invoked with -<B>M-x send-pr</B>). - -See the file -<B>send-pr.info</B> - -or the ASCII file -<B>INSTALL</B> - -in the top level directory of the distribution for configuration and -installation information. The Emacs LISP template file is -<B>send-pr-el.in</B> - -and is installed as -<B>send-pr.el</B>. - -<A NAME="lbAK"> </A> -<H2>INSTALLATION AND CONFIGURATION</H2> - -See -<B>send-pr.info</B> - -or -<B>INSTALL</B> - -for installation instructions. -<A NAME="lbAL"> </A> -<H2>SEE ALSO</H2> - -<I>Reporting Problems Using send-pr</I> - -(also installed as the GNU Info file -<B>send-pr.info</B>). - -<P> - -<B><A HREF="http://localhost/cgi-bin/man/man2html?l+gnats">gnats</A></B>(l), - -<B><A HREF="query-pr.1.html">query-pr</A></B>(1), - -<B><A HREF="edit-pr.1.html">edit-pr</A></B>(1), - -<B><A HREF="gnats.8.html">gnats</A></B>(8), - -<B><A HREF="queue-pr.8.html">queue-pr</A></B>(8), - -<B><A HREF="at-pr.8.html">at-pr</A></B>(8), - -<B><A HREF="mkcat.8.html">mkcat</A></B>(8), - -<B><A HREF="mkdist.8.html">mkdist</A></B>(8). - -<A NAME="lbAM"> </A> -<H2>AUTHORS</H2> - -Jeffrey Osier, Brendan Kehoe, Jason Merrill, Heinz G. Seidl (Cygnus -Support) -<A NAME="lbAN"> </A> -<H2>COPYING</H2> - -Copyright (c) 1992, 1993 Free Software Foundation, Inc. -<P> - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. -<P> - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. -<P> - -Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be included in -translations approved by the Free Software Foundation instead of in -the original English. -<P> -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">OPTIONS</A><DD> -<DT><A HREF="#lbAF">ENVIRONMENT</A><DD> -<DT><A HREF="#lbAG">HOW TO FILL OUT A PROBLEM REPORT</A><DD> -<DT><A HREF="#lbAH">HOW TO SUBMIT TEST CASES, CODE, ETC.</A><DD> -<DT><A HREF="#lbAI">FILES</A><DD> -<DT><A HREF="#lbAJ">EMACS USER INTERFACE</A><DD> -<DT><A HREF="#lbAK">INSTALLATION AND CONFIGURATION</A><DD> -<DT><A HREF="#lbAL">SEE ALSO</A><DD> -<DT><A HREF="#lbAM">AUTHORS</A><DD> -<DT><A HREF="#lbAN">COPYING</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_setportof.3.html b/doc/manpage.d/ipsec_setportof.3.html deleted file mode 100644 index 3965ca62d..000000000 --- a/doc/manpage.d/ipsec_setportof.3.html +++ /dev/null @@ -1,143 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_PORTOF</TITLE> -</HEAD><BODY> -<H1>IPSEC_PORTOF</H1> -Section: C Library Functions (3)<BR>Updated: 8 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec portof - get port field of an ip_address -<BR> - -ipsec setportof - set port field of an ip_address -<BR> - -ipsec sockaddrof - get pointer to internal sockaddr of an ip_address -<BR> - -ipsec sockaddrlenof - get length of internal sockaddr of an ip_address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int portof(const ip_address *src);</B> - -<BR> - -<B>void setportof(int port, ip_address *dst);</B> - -<BR> - -<B>struct sockaddr *sockaddrof(ip_address *src);</B> - -<BR> - -<B>size_t sockaddrlenof(const ip_address *src);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -internal type -<I>ip_address</I> - -contains one of the -<I>sockaddr</I> - -types internally. -<I>Reliance on this feature is discouraged</I>, -but it may occasionally be necessary. -These functions provide low-level tools for this purpose. -<P> - -<I>Portof</I> - -and -<I>setportof</I> - -respectively read and write the port-number field of the internal -<I>sockaddr</I>. - -The values are in network byte order. -<P> - -<I>Sockaddrof</I> - -returns a pointer to the internal -<I>sockaddr</I>, - -for passing to other functions. -<P> - -<I>Sockaddrlenof</I> - -reports the size of the internal -<I>sockaddr</I>, - -for use in storage allocation. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_initaddr.3.html">ipsec_initaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -<I>Portof</I> - -returns -<B>-1</B>, - -<I>sockaddrof</I> - -returns -<B>NULL</B>, - -and -<I>sockaddrlenof</I> - -returns -<B>0</B> - -if an unknown address family is found within the -<I>ip_address</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -These functions all depend on low-level details of the -<I>ip_address</I> - -type, which are in principle subject to change. -Avoid using them unless really necessary. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_setup.8.html b/doc/manpage.d/ipsec_setup.8.html deleted file mode 100644 index 7197e2b18..000000000 --- a/doc/manpage.d/ipsec_setup.8.html +++ /dev/null @@ -1,237 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_SETUP</TITLE> -</HEAD><BODY> -<H1>IPSEC_SETUP</H1> -Section: Maintenance Commands (8)<BR>Updated: 23 July 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec setup - control IPsec subsystem -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>setup</B> - -[ -<B>--show</B> - -| -<B>--showonly</B> - -] -command -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Setup</I> - -controls the FreeS/WAN IPsec subsystem, -including both the Klips kernel code and the Pluto key-negotiation daemon. -(It is a synonym for the ``rc'' script for the subsystem; -the system runs the equivalent of -<B>ipsec setup start</B> - -at boot time, -and -<B>ipsec setup stop</B> - -at shutdown time, more or less.) -<P> - -The action taken depends on the specific -<I>command</I>, - -and on the contents of the -<B>config</B> - -<B>setup</B> - -section of the -IPsec configuration file (<I>/etc/ipsec.conf</I>, - -see -<I><A HREF="ipsec.conf.5.html">ipsec.conf</A></I>(5)). - -Current -<I>command</I>s - -are: -<DL COMPACT> -<DT><B>start</B> - -<DD> -start Klips and Pluto, -including setting up Klips to do crypto operations on the -interface(s) specified in the configuration file, -and (if the configuration file so specifies) -setting up manually-keyed connections and/or -asking Pluto to negotiate automatically-keyed connections -to other security gateways -<DT><B>stop</B> - -<DD> -shut down Klips and Pluto, -including tearing down all existing crypto connections -<DT><B>restart</B> - -<DD> -equivalent to -<B>stop</B> - -followed by -<B>start</B> - -<DT><B>status</B> - -<DD> -report the status of the subsystem; -normally just reports -<B>IPsec running</B> - -and -<B>pluto pid </B><I>nnn</I>, - -or -<B>IPsec stopped</B>, - -and exits with status 0, -but will go into more detail (and exit with status 1) -if something strange is found. -(An ``illicit'' Pluto is one that does not match the process ID in -Pluto's lock file; -an ``orphaned'' Pluto is one with no lock file.) -</DL> -<P> - -The -<B>stop</B> - -operation tries to clean up properly even if assorted accidents -have occurred, -e.g. Pluto having died without removing its lock file. -If -<B>stop</B> - -discovers that the subsystem is (supposedly) not running, -it will complain, -but will do its cleanup anyway before exiting with status 1. -<P> - -Although a number of configuration-file parameters influence -<I>setup</I>'s - -operations, the key one is the -<B>interfaces</B> - -parameter, which must be right or chaos will ensue. -<P> - -The -<B>--show</B> - -and -<B>--showonly</B> - -options cause -<I>setup</I> - -to display the shell commands that it would execute. -<B>--showonly</B> - -suppresses their execution. -Only -<B>start</B>, - -<B>stop</B>, - -and -<B>restart</B> - -commands recognize these flags. -<A NAME="lbAE"> </A> -<H2>FILES</H2> - - - -/etc/rc.d/init.d/ipsec<TT> </TT>the script itself<BR> -<BR> - -/etc/init.d/ipsec<TT> </TT>alternate location for the script<BR> -<BR> - -/etc/ipsec.conf<TT> </TT>IPsec configuration file<BR> -<BR> - -/proc/sys/net/ipv4/ip_forward<TT> </TT>forwarding control<BR> -<BR> - -/var/run/ipsec.info<TT> </TT>saved information<BR> -<BR> - -/var/run/pluto.pid<TT> </TT>Pluto lock file<BR> -<BR> - -/var/run/ipsec_setup.pid<TT> </TT>IPsec lock file<BR> -<A NAME="lbAF"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.conf.5.html">ipsec.conf</A>(5), <A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_auto.8.html">ipsec_auto</A>(8), <A HREF="route.8.html">route</A>(8) -<A NAME="lbAG"> </A> -<H2>DIAGNOSTICS</H2> - -All output from the commands -<B>start</B> - -and -<B>stop</B> - -goes both to standard -output and to -<I><A HREF="syslogd.8.html">syslogd</A></I>(8), - -via -<I><A HREF="logger.1.html">logger</A></I>(1). - -Selected additional information is logged only to -<I><A HREF="syslogd.8.html">syslogd</A></I>(8). - -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Henry Spencer. -<A NAME="lbAI"> </A> -<H2>BUGS</H2> - -Old versions of -<I><A HREF="logger.1.html">logger</A></I>(1) - -inject spurious extra newlines onto standard output. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">SEE ALSO</A><DD> -<DT><A HREF="#lbAG">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -<DT><A HREF="#lbAI">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_showdefaults.8.html b/doc/manpage.d/ipsec_showdefaults.8.html deleted file mode 100644 index e1786dc0a..000000000 --- a/doc/manpage.d/ipsec_showdefaults.8.html +++ /dev/null @@ -1,82 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_SHOWDEFAULTS</TITLE> -</HEAD><BODY> -<H1>IPSEC_SHOWDEFAULTS</H1> -Section: Maintenance Commands (8)<BR>Updated: 23 Jan 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec showdefaults - show %defaultroute defaults -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>showdefaults</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Showdefaults</I> - -outputs (on standard output) a terse description of the defaults -used by the -<B>%defaultroute</B> - -facilities in -<I><A HREF="ipsec_auto.8.html">ipsec_auto</A></I>(8) - -and -<I><A HREF="ipsec_manual.8.html">ipsec_manual</A></I>(8). - -<P> - -Beware that the exact output format is subject to change. -<A NAME="lbAE"> </A> -<H2>DIAGNOSTICS</H2> - -Normal exit status is 0. -If no defaults are available, -i.e. the -<B>interfaces</B> - -parameter in -<B>config setup</B> - -is not -<B>%defaultroute</B>, - -produces a message on standard error and exits with status 1. -<A NAME="lbAF"> </A> -<H2>FILES</H2> - -/var/run/ipsec.info -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAF">FILES</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_showhostkey.8.html b/doc/manpage.d/ipsec_showhostkey.8.html deleted file mode 100644 index 90a16d5ee..000000000 --- a/doc/manpage.d/ipsec_showhostkey.8.html +++ /dev/null @@ -1,269 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_SHOWHOSTKEY</TITLE> -</HEAD><BODY> -<H1>IPSEC_SHOWHOSTKEY</H1> -Section: Maintenance Commands (8)<BR>Updated: 5 March 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec showhostkey - show host's authentication key -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>showhostkey</B> - -[ -<B>--key</B> - -] [ -<B>--left</B> - -] [ -<B>--right</B> - -] [ -<B>--txt</B> - -gateway -] [ -<B>--dhclient</B> - -] [ -<B>--file</B> - -secretfile -] [ -<B>--id</B> - -identity -] -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Showhostkey</I> - -outputs (on standard output) a public key suitable for this host, -in the format specified, -using the host key information stored in -<I>/etc/ipsec.secrets</I>. - -In general only the super-user can run this command, -since only he can read -<I>ipsec.secrets</I>. - -<P> - -The -<B>--txt</B> - -option causes the output to be in opportunistic-encryption DNS TXT record -format, -with the specified -<I>gateway</I> - -value. -If information about how the key was generated is available, -that is provided as a DNS-file comment. -For example, -<B>--txt 10.11.12.13</B> - -might give (with the key data trimmed for clarity): -<P> - -<PRE> - ; RSA 2048 bits xy.example.com Sat Apr 15 13:53:22 2000 - IN TXT "X-IPsec-Server(10)=10.11.12.13 AQOF8tZ2...+buFuFn/" -</PRE> - -<P> - -No name is supplied in the TXT record -because there are too many possibilities, -depending on how it will be used. -If the text string is longer than 255 bytes, -it is split up into multiple strings (matching the restrictions of -the DNS TXT binary format). -If any split is needed, the first split will be at the start of the key: -this increases the chances that later hand editing will work. -<P> - -The -<B>--left</B> - -and -<B>--right</B> - -options cause the output to be in -<I><A HREF="ipsec.conf.5.html">ipsec.conf</A></I>(5) - -format, as a -<B>leftrsasigkey</B> - -or -<B>rightrsasigkey</B> - -parameter respectively. -Again, generation information is included if available. -For example, -<B>--left</B> - -might give (with the key data trimmed down for clarity): -<P> - -<PRE> - # RSA 2048 bits xy.example.com Sat Apr 15 13:53:22 2000 - leftrsasigkey=0sAQOF8tZ2...+buFuFn/ -</PRE> - -<P> - -The -<B>--dhclient</B> - -option cause the output to be suitable for inclusion in -<I><A HREF="dhclient.conf.5.html">dhclient.conf</A></I>(5) - -as part of configuring WAVEsec. -See <<A HREF="http://www.wavesec.org">http://www.wavesec.org</A>>. -<P> - -If -<B>--key</B> - -is specified, -the output format is the text form of a DNS KEY record; -the host name is the one included in the key information -(or, if that is not available, -the output of -<B>hostname --fqdn</B>), - -with a -<B>.</B> - -appended. -Again, generation information is included if available. -For example (with the key data trimmed down for clarity): -<P> - -<PRE> - ; RSA 2048 bits xy.example.com Sat Apr 15 13:53:22 2000 - xy.example.com. IN KEY 0x4200 4 1 AQOF8tZ2...+buFuFn/ -</PRE> - -<P> - -Normally, the default key for this host -(the one with no host identities specified for it) is the one extracted. -The -<B>--id</B> - -option overrides this, -causing extraction of the key labeled with the specified -<I>identity</I>, - -if any. -The specified -<I>identity</I> - -must -<I>exactly</I> - -match the identity in the file; -in particular, the comparison is case-sensitive. -<P> - -The -<B>--file</B> - -option overrides the default for where the key information should be -found, and takes it from the specified -<I>secretfile</I>. - -<A NAME="lbAE"> </A> -<H2>DIAGNOSTICS</H2> - -A complaint about ``no pubkey line found'' indicates that the -host has a key but it was generated with an old version of FreeS/WAN -and does not contain the information that -<I>showhostkey</I> - -needs. -<A NAME="lbAF"> </A> -<H2>FILES</H2> - -/etc/ipsec.secrets -<A NAME="lbAG"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.secrets.5.html">ipsec.secrets</A>(5), <A HREF="ipsec.conf.5.html">ipsec.conf</A>(5), <A HREF="ipsec_rsasigkey.8.html">ipsec_rsasigkey</A>(8) -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Henry Spencer. -<A NAME="lbAI"> </A> -<H2>BUGS</H2> - -Arguably, -rather than just reporting the no-IN-KEY-line-found problem, -<I>showhostkey</I> - -should be smart enough to run the existing key through -<I>rsasigkey</I> - -with the -<B>--oldkey</B> - -option, to generate a suitable output line. -<P> - -The need to specify the gateway address (etc.) for -<B>--txt</B> - -is annoying, but there is no good way to determine it automatically. -<P> - -There should be a way to specify the priority value for TXT records; -currently it is hardwired to -<B>10</B>. - -<P> - -The -<B>--id</B> - -option assumes that the -<I>identity</I> - -appears on the same line as the -<B>: RSA {</B> - -that begins the key proper. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAF">FILES</A><DD> -<DT><A HREF="#lbAG">SEE ALSO</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -<DT><A HREF="#lbAI">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_showpolicy.8.html b/doc/manpage.d/ipsec_showpolicy.8.html deleted file mode 100644 index 470c40879..000000000 --- a/doc/manpage.d/ipsec_showpolicy.8.html +++ /dev/null @@ -1,88 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_SHOWPOLICY</TITLE> -</HEAD><BODY> -<H1>IPSEC_SHOWPOLICY</H1> -Section: Maintenance Commands (8)<BR>Updated: 7 May 2003<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec showpolicy - dump policy of socket found as stdin -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<P> - -<B>ipsec</B> - -<B>showpolicy</B> - -<P> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>showpolicy</I> - -calls the -<I><A HREF="ipsec_policy_lookup.3.html">ipsec_policy_lookup</A></I>(3) - -function on the file description which is its stdin. -<P> - -It then dumps the resulting query in a human readable form. -<P> - -This is a test program. One might run it from inetd, via: -<DL COMPACT> -<DT>discard stream tcp nowait nobody /usr/local/libexec/ipsec/showpolicy showpolicy<DD> -</DL> -<A NAME="lbAE"> </A> -<H2>FILES</H2> - -/var/run/ipsecpolicy.ctl -<A NAME="lbAF"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_policy_query.3.html">ipsec_policy_query</A>(3), <A HREF="ipsec_pluto.8.html">ipsec_pluto</A>(8) -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael Richardson -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">SEE ALSO</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_sockaddrlenof.3.html b/doc/manpage.d/ipsec_sockaddrlenof.3.html deleted file mode 100644 index 3965ca62d..000000000 --- a/doc/manpage.d/ipsec_sockaddrlenof.3.html +++ /dev/null @@ -1,143 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_PORTOF</TITLE> -</HEAD><BODY> -<H1>IPSEC_PORTOF</H1> -Section: C Library Functions (3)<BR>Updated: 8 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec portof - get port field of an ip_address -<BR> - -ipsec setportof - set port field of an ip_address -<BR> - -ipsec sockaddrof - get pointer to internal sockaddr of an ip_address -<BR> - -ipsec sockaddrlenof - get length of internal sockaddr of an ip_address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int portof(const ip_address *src);</B> - -<BR> - -<B>void setportof(int port, ip_address *dst);</B> - -<BR> - -<B>struct sockaddr *sockaddrof(ip_address *src);</B> - -<BR> - -<B>size_t sockaddrlenof(const ip_address *src);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -internal type -<I>ip_address</I> - -contains one of the -<I>sockaddr</I> - -types internally. -<I>Reliance on this feature is discouraged</I>, -but it may occasionally be necessary. -These functions provide low-level tools for this purpose. -<P> - -<I>Portof</I> - -and -<I>setportof</I> - -respectively read and write the port-number field of the internal -<I>sockaddr</I>. - -The values are in network byte order. -<P> - -<I>Sockaddrof</I> - -returns a pointer to the internal -<I>sockaddr</I>, - -for passing to other functions. -<P> - -<I>Sockaddrlenof</I> - -reports the size of the internal -<I>sockaddr</I>, - -for use in storage allocation. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_initaddr.3.html">ipsec_initaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -<I>Portof</I> - -returns -<B>-1</B>, - -<I>sockaddrof</I> - -returns -<B>NULL</B>, - -and -<I>sockaddrlenof</I> - -returns -<B>0</B> - -if an unknown address family is found within the -<I>ip_address</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -These functions all depend on low-level details of the -<I>ip_address</I> - -type, which are in principle subject to change. -Avoid using them unless really necessary. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_sockaddrof.3.html b/doc/manpage.d/ipsec_sockaddrof.3.html deleted file mode 100644 index 3965ca62d..000000000 --- a/doc/manpage.d/ipsec_sockaddrof.3.html +++ /dev/null @@ -1,143 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_PORTOF</TITLE> -</HEAD><BODY> -<H1>IPSEC_PORTOF</H1> -Section: C Library Functions (3)<BR>Updated: 8 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec portof - get port field of an ip_address -<BR> - -ipsec setportof - set port field of an ip_address -<BR> - -ipsec sockaddrof - get pointer to internal sockaddr of an ip_address -<BR> - -ipsec sockaddrlenof - get length of internal sockaddr of an ip_address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int portof(const ip_address *src);</B> - -<BR> - -<B>void setportof(int port, ip_address *dst);</B> - -<BR> - -<B>struct sockaddr *sockaddrof(ip_address *src);</B> - -<BR> - -<B>size_t sockaddrlenof(const ip_address *src);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -internal type -<I>ip_address</I> - -contains one of the -<I>sockaddr</I> - -types internally. -<I>Reliance on this feature is discouraged</I>, -but it may occasionally be necessary. -These functions provide low-level tools for this purpose. -<P> - -<I>Portof</I> - -and -<I>setportof</I> - -respectively read and write the port-number field of the internal -<I>sockaddr</I>. - -The values are in network byte order. -<P> - -<I>Sockaddrof</I> - -returns a pointer to the internal -<I>sockaddr</I>, - -for passing to other functions. -<P> - -<I>Sockaddrlenof</I> - -reports the size of the internal -<I>sockaddr</I>, - -for use in storage allocation. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_initaddr.3.html">ipsec_initaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -<I>Portof</I> - -returns -<B>-1</B>, - -<I>sockaddrof</I> - -returns -<B>NULL</B>, - -and -<I>sockaddrlenof</I> - -returns -<B>0</B> - -if an unknown address family is found within the -<I>ip_address</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -These functions all depend on low-level details of the -<I>ip_address</I> - -type, which are in principle subject to change. -Avoid using them unless really necessary. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_spi.5.html b/doc/manpage.d/ipsec_spi.5.html deleted file mode 100644 index b1cf89033..000000000 --- a/doc/manpage.d/ipsec_spi.5.html +++ /dev/null @@ -1,305 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_SPI</TITLE> -</HEAD><BODY> -<H1>IPSEC_SPI</H1> -Section: File Formats (5)<BR>Updated: 26 Jun 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec_spi - list IPSEC Security Associations -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>spi</B> - -<P> - -<B>cat</B> - -<B>/proc/net/ipsec_spi</B> - -<P> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>/proc/net/ipsec_spi</I> - -is a read-only file that lists the current IPSEC Security Associations. -A Security Association (SA) is a transform through which packet contents -are to be processed before being forwarded. A transform can be an -IPv4-in-IPv4 or IPv6-in-IPv6 encapsulation, an IPSEC Authentication Header (authentication -with no encryption), or an IPSEC Encapsulation Security Payload -(encryption, possibly including authentication). -<P> - -When a packet is passed from a higher networking layer through an IPSEC -virtual interface, a search in the extended routing table (see -<I><A HREF="ipsec_eroute.5.html">ipsec_eroute</A></I>(5)) - -yields -a IP protocol number -, -a Security Parameters Index (SPI) -and -an effective destination address -When an IPSEC packet arrives from the network, -its ostensible destination, an SPI and an IP protocol -specified by its outermost IPSEC header are used. -The destination/SPI/protocol combination is used to select a relevant SA. -(See -<I><A HREF="ipsec_spigrp.5.html">ipsec_spigrp</A></I>(5) - -for discussion of how multiple transforms are combined.) -<P> - -An -<I>spi ,</I> - -<I>proto, </I> - -<I>daddr</I> - -and -<I>address_family</I> - -arguments specify an SAID. -<I>Proto</I> - -is an ASCII string, "ah", "esp", "comp" or "tun", specifying the IP protocol. -<I>Spi</I> - -is a number, preceded by '.' indicating hexadecimal and IPv4 or by ':' indicating hexadecimal and IPv6, -where each hexadecimal digit represents 4 bits, -between -<B>0x100</B> - -and -<B>0xffffffff</B>; - -values from -<B>0x0</B> - -to -<B>0xff</B> - -are reserved. -<I>Daddr</I> - -is a dotted-decimal IPv4 destination address or a coloned hex IPv6 destination address. -<P> - -An -<I>SAID</I> - -combines the three parameters above, such as: "<A HREF="mailto:tun.101@1.2.3.4">tun.101@1.2.3.4</A>" for IPv4 or "tun:<A HREF="mailto:101@3049">101@3049</A>:1::1" for IPv6 -<P> - -A table entry consists of: -<DL COMPACT> -<DT>+<DD> -<B>SAID</B> - -<DT>+<DD> -<transform name (proto,encalg,authalg)>: -<DT>+<DD> -direction (dir=) -<DT>+<DD> -source address (src=) -<DT>+<DD> -source and destination addresses and masks for inner header policy check -addresses (policy=), as dotted-quads or coloned hex, separated by '->', -for IPv4-in-IPv4 or IPv6-in-IPv6 SAs only -<DT>+<DD> -initialisation vector length and value (iv_bits=, iv=) if non-zero -<DT>+<DD> -out-of-order window size, number of out-of-order errors, sequence -number, recently received packet bitmask, maximum difference between -sequence numbers (ooowin=, ooo_errs=, seq=, bit=, max_seq_diff=) if SA -is AH or ESP and if individual items are non-zero -<DT>+<DD> -extra flags (flags=) if any are set -<DT>+<DD> -authenticator length in bits (alen=) if non-zero -<DT>+<DD> -authentication key length in bits (aklen=) if non-zero -<DT>+<DD> -authentication errors (auth_errs=) if non-zero -<DT>+<DD> -encryption key length in bits (eklen=) if non-zero -<DT>+<DD> -encryption size errors (encr_size_errs=) if non-zero -<DT>+<DD> -encryption padding error warnings (encr_pad_errs=) if non-zero -<DT>+<DD> -lifetimes legend, c=Current status, s=Soft limit when exceeded will -initiate rekeying, h=Hard limit will cause termination of SA (life(c,s,h)=) -<DT>+<DD> -number of connections to which the SA is allocated (c), that will cause a -rekey (s), that will cause an expiry (h) (alloc=), if any value is non-zero -<DT>+<DD> -number of bytes processesd by this SA (c), that will cause a rekey (s), that -will cause an expiry (h) (bytes=), if any value is non-zero -<DT>+<DD> -time since the SA was added (c), until rekey (s), until expiry (h), in seconds (add=) -<DT>+<DD> -time since the SA was first used (c), until rekey (s), until expiry (h), in seconds (used=), -if any value is non-zero -<DT>+<DD> -number of packets processesd by this SA (c), that will cause a rekey (s), that -will cause an expiry (h) (packets=), if any value is non-zero -<DT>+<DD> -time since the last packet was processed, in seconds (idle=), if SA has -been used -<DT><DD> -average compression ratio (ratio=) -</DL> -<A NAME="lbAE"> </A> -<H2>EXAMPLES</H2> - -<B><A HREF="mailto:tun.12a@192.168.43.1">tun.12a@192.168.43.1</A> IPIP: dir=out src=192.168.43.2</B> - -<BR> - -<B> life(c,s,h)=bytes(14073,0,0)add(269,0,0)</B> - -<BR> - -<B> use(149,0,0)packets(14,0,0)</B> - -<BR> - -<B> idle=23</B> - -<P> - -is an outbound IPv4-in-IPv4 (protocol 4) tunnel-mode SA set up between machines -192.168.43.2 and 192.168.43.1 with an SPI of 12a in hexadecimal that has -passed about 14 kilobytes of traffic in 14 packets since it was created, -269 seconds ago, first used 149 seconds ago and has been idle for 23 -seconds. -<P> - -<B>esp:<A HREF="mailto:9a35fc02@3049">9a35fc02@3049</A>:1::1 ESP_3DES_HMAC_MD5:</B> - -<BR> - -<B> dir=in src=<A HREF="mailto:9a35fc02@3049">9a35fc02@3049</A>:1::2</B> - -<BR> - -<B> ooowin=32 seq=7149 bit=0xffffffff</B> - -<BR> - -<B> alen=128 aklen=128 eklen=192</B> - -<BR> - -<B> life(c,s,h)=bytes(1222304,0,0)add(4593,0,0)</B> - -<BR> - -<B> use(3858,0,0)packets(7149,0,0)</B> - -<BR> - -<B> idle=23</B> - -<P> - -is an inbound Encapsulating Security Payload (protocol 50) SA on machine -3049:1::1 with an SPI of 9a35fc02 that uses 3DES as the encryption -cipher, HMAC MD5 as the authentication algorithm, an out-of-order -window of 32 packets, a present sequence number of 7149, every one of -the last 32 sequence numbers was received, the authenticator length and -keys is 128 bits, the encryption key is 192 bits (actually 168 for 3DES -since 1 of 8 bits is a parity bit), has passed 1.2 Mbytes of data in -7149 packets, was added 4593 seconds ago, first used -3858 seconds ago and has been idle for 23 seconds. -<P> - -<A NAME="lbAF"> </A> -<H2>FILES</H2> - -/proc/net/ipsec_spi, /usr/local/bin/ipsec -<A NAME="lbAG"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_tncfg.5.html">ipsec_tncfg</A>(5), <A HREF="ipsec_eroute.5.html">ipsec_eroute</A>(5), -<A HREF="ipsec_spigrp.5.html">ipsec_spigrp</A>(5), <A HREF="ipsec_klipsdebug.5.html">ipsec_klipsdebug</A>(5), <A HREF="ipsec_spi.8.html">ipsec_spi</A>(8), <A HREF="ipsec_version.5.html">ipsec_version</A>(5), -<A HREF="ipsec_pf_key.5.html">ipsec_pf_key</A>(5) -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Richard Guy Briggs. -<A NAME="lbAI"> </A> -<H2>BUGS</H2> - -The add and use times are awkward, displayed in seconds since machine -start. It would be better to display them in seconds before now for -human readability. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">EXAMPLES</A><DD> -<DT><A HREF="#lbAF">FILES</A><DD> -<DT><A HREF="#lbAG">SEE ALSO</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -<DT><A HREF="#lbAI">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_spi.8.html b/doc/manpage.d/ipsec_spi.8.html deleted file mode 100644 index a40d06d9b..000000000 --- a/doc/manpage.d/ipsec_spi.8.html +++ /dev/null @@ -1,790 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_SPI</TITLE> -</HEAD><BODY> -<H1>IPSEC_SPI</H1> -Section: Maintenance Commands (8)<BR>Updated: 23 Oct 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec spi - manage IPSEC Security Associations -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<BR> - -Note: In the following, -<BR> - -<B><SA></B> - -means: -<B>--af</B> - -(inet | inet6) -<B>--edst</B> - -daddr -<B>--spi</B> - -spi -<B>--proto</B> - -proto OR -<B>--said</B> - -said, -<BR> - -<B><life></B> - -means: -<B>--life</B> - -(soft | hard)-(allocations | bytes | addtime | usetime | packets)=value[,...] -<P> - -<B>ipsec</B> - -<B>spi</B> - -<P> - -<B>ipsec</B> - -<B>spi</B> - -<B><SA></B> - -<B>--src</B> - -src -<B>--ah</B> - -<B>hmac-md5-96</B>|<B>hmac-sha1-96</B> - -[ -<B>--replay_window</B> - -replayw ] -[ -<B><life></B> - -] -<B>--authkey</B> - -akey -<P> - -<B>ipsec</B> - -<B>spi</B> - -<B><SA></B> - -<B>--src</B> - -src -<B>--esp</B> - -<B>3des</B> - -[ -<B>--replay_window</B> - -replayw ] -[ -<B><life></B> - -] -<B>--enckey</B> - -ekey -<P> - -<B>ipsec</B> - -<B>spi</B> - -<B><SA></B> - -<B>--src</B> - -src -<B>--esp</B> - -<B>3des-md5-96</B>|<B>3des-sha1-96</B> - -[ -<B>--replay_window</B> - -replayw ] -[ -<B><life></B> - -] -<B>--enckey</B> - -ekey -<B>--authkey</B> - -akey -<P> - -<B>ipsec</B> - -<B>spi</B> - -<B><SA></B> - -<B>--src</B> - -src -<B>--comp</B> - -<B>deflate</B> - -<P> - -<B>ipsec</B> - -<B>spi</B> - -<B><SA></B> - -<B>--ip4</B> - -<B>--src</B> - -encap-src -<B>--dst</B> - -encap-dst -<P> - -<B>ipsec</B> - -<B>spi</B> - -<B><SA></B> - -<B>--ip6</B> - -<B>--src</B> - -encap-src -<B>--dst</B> - -encap-dst -<P> - -<B>ipsec</B> - -<B>spi</B> - -<B><SA></B> - -<B>--del</B> - -<P> - -<B>ipsec</B> - -<B>spi</B> - -<B>--help</B> - -<P> - -<B>ipsec</B> - -<B>spi</B> - -<B>--version</B> - -<P> - -<B>ipsec</B> - -<B>spi</B> - -<B>--clear</B> - -<P> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Spi</I> - -creates and deletes IPSEC Security Associations. -A Security Association (SA) is a transform through which packet -contents are to be processed before being forwarded. -A transform can be an IPv4-in-IPv4 or an IPv6-in-IPv6 encapsulation, -an IPSEC Authentication Header (authentication with no encryption), -or an IPSEC Encapsulation Security Payload (encryption, possibly -including authentication). -<P> - -When a packet is passed from a higher networking layer -through an IPSEC virtual interface, -a search in the extended routing table (see -<I><A HREF="ipsec_eroute.8.html">ipsec_eroute</A></I>(8)) - -yields an effective destination address, a -Security Parameters Index (SPI) and a IP protocol number. -When an IPSEC packet arrives from the network, -its ostensible destination, an SPI and an IP protocol -specified by its outermost IPSEC header are used. -The destination/SPI/protocol combination is used to select a relevant SA. -(See -<I><A HREF="ipsec_spigrp.8.html">ipsec_spigrp</A></I>(8) - -for discussion of how multiple transforms are combined.) -<P> - -The -<I>af</I>, - -<I>daddr</I>, - -<I>spi</I> - -and -<I>proto</I> - -arguments specify the SA to be created or deleted. -<I>af</I> - -is the address family (inet for IPv4, inet6 for IPv6). -<I>Daddr</I> - -is a destination address -in dotted-decimal notation for IPv4 -or in a coloned hex notation for IPv6. -<I>Spi</I> - -is a number, preceded by '0x' for hexadecimal, -between -<B>0x100</B> - -and -<B>0xffffffff</B>; - -values from -<B>0x0</B> - -to -<B>0xff</B> - -are reserved. -<I>Proto</I> - -is an ASCII string, "ah", "esp", "comp" or "tun", specifying the IP protocol. -The protocol must agree with the algorithm selected. -<P> - -Alternatively, the -<I>said</I> - -argument can also specify an SA to be created or deleted. -<I>Said</I> - -combines the three parameters above, such as: "<A HREF="mailto:tun.101@1.2.3.4">tun.101@1.2.3.4</A>" or "tun:101@1:2::3:4", -where the address family is specified by "." for IPv4 and ":" for IPv6. The address -family indicators substitute the "0x" for hexadecimal. -<P> - -The source address, -<I>src</I>, - -must also be provided for the inbound policy check to -function. The source address does not need to be included if inbound -policy checking has been disabled. -<P> - -Keys vectors must be entered as hexadecimal or base64 numbers. -They should be cryptographically strong random numbers. -<P> - -All hexadecimal numbers are entered as strings of hexadecimal digits -(0-9 and a-f), without spaces, preceded by '0x', where each hexadecimal -digit represents 4 bits. -All base64 numbers are entered as strings of base64 digits -<BR> (0-9, A-Z, a-z, '+' and '/'), without spaces, preceded by '0s', -where each hexadecimal digit represents 6 bits and '=' is used for padding. -<P> - -The deletion of an SA which has been grouped will result in the entire chain -being deleted. -<P> - -The form with no additional arguments lists the contents of -/proc/net/ipsec_spi. The format of /proc/net/ipsec_spi is discussed in -<A HREF="ipsec_spi.5.html">ipsec_spi</A>(5). -<P> - -The lifetime severity of -<B>soft</B> - -sets a limit when the key management daemons are asked to rekey the SA. -The lifetime severity of -<B>hard</B> - -sets a limit when the SA must expire. -The lifetime type -<B>allocations</B> - -tells the system when to expire the SA because it is being shared by too many -eroutes (not currently used). The lifetime type of -<B>bytes</B> - -tells the system to expire the SA after a certain number of bytes have been -processed with that SA. The lifetime type of -<B>addtime</B> - -tells the system to expire the SA a certain number of seconds after the SA was -installed. The lifetime type of -<B>usetime</B> - -tells the system to expire the SA a certain number of seconds after that SA has -processed its first packet. The lifetime type of -<B>packets</B> - -tells the system to expire the SA after a certain number of packets have been -processed with that SA. -<A NAME="lbAE"> </A> -<H2>OPTIONS</H2> - -<DL COMPACT> -<DT><B>--af</B> - -<DD> -specifies the address family (inet for IPv4, inet6 for IPv6) -<DT><B>--edst</B> - -<DD> -specifies the effective destination -<I>daddr</I> - -of the Security Association -<DT><B>--spi</B> - -<DD> -specifies the Security Parameters Index -<I>spi</I> - -of the Security Association -<DT><B>--proto</B> - -<DD> -specifies the IP protocol -<I>proto</I> - -of the Security Association -<DT><B>--said</B> - -<DD> -specifies the Security Association in monolithic format -<DT><B>--ah</B> - -<DD> -add an SA for an IPSEC Authentication Header, -specified by the following transform identifier -(<B>hmac-md5-96</B> - -or -<B>hmac-sha1-96</B>) - -(RFC2402, obsoletes RFC1826) -<DT><B>hmac-md5-96</B> - -<DD> -transform following the HMAC and MD5 standards, -using a 128-bit -<I>key</I> - -to produce a 96-bit authenticator (RFC2403) -<DT><B>hmac-sha1-96</B> - -<DD> -transform following the HMAC and SHA1 standards, -using a 160-bit -<I>key</I> - -to produce a 96-bit authenticator (RFC2404) -<DT><B>--esp</B> - -<DD> -add an SA for an IPSEC Encapsulation Security Payload, -specified by the following -transform identifier (<B>3des</B>, - -or -<B>3des-md5-96</B>) - -(RFC2406, obsoletes RFC1827) -<DT><B>3des</B> - -<DD> -encryption transform following the Triple-DES standard in -Cipher-Block-Chaining mode using a 64-bit -<I>iv</I> - -(internally generated) and a 192-bit 3DES -<I>ekey</I> - -(RFC2451) -<DT><B>3des-md5-96</B> - -<DD> -encryption transform following the Triple-DES standard in -Cipher-Block-Chaining mode with authentication provided by -HMAC and MD5 -(96-bit authenticator), -using a 64-bit -<I>iv</I> - -(internally generated), a 192-bit 3DES -<I>ekey</I> - -and a 128-bit HMAC-MD5 -<I>akey</I> - -(RFC2451, RFC2403) -<DT><B>3des-sha1-96</B> - -<DD> -encryption transform following the Triple-DES standard in -Cipher-Block-Chaining mode with authentication provided by -HMAC and SHA1 -(96-bit authenticator), -using a 64-bit -<I>iv</I> - -(internally generated), a 192-bit 3DES -<I>ekey</I> - -and a 160-bit HMAC-SHA1 -<I>akey</I> - -(RFC2451, RFC2404) -<DT><B>--replay_window</B> replayw - -<DD> -sets the replay window size; valid values are decimal, 1 to 64 -<DT><B>--life</B> life_param[,life_param] - -<DD> -sets the lifetime expiry; the format of -<B>life_param</B> - -consists of a comma-separated list of lifetime specifications without spaces; -a lifetime specification is comprised of a severity of -<B>soft</B> or <B>hard</B> - -followed by a '-', followed by a lifetime type of -<B>allocations</B>, <B>bytes</B>, <B>addtime</B>, <B>usetime</B> or <B>packets</B> - -followed by an '=' and finally by a value -<DT><B>--comp</B> - -<DD> -add an SA for IPSEC IP Compression, -specified by the following -transform identifier (<B>deflate</B>) - -(RFC2393) -<DT><B>deflate</B> - -<DD> -compression transform following the patent-free Deflate compression algorithm -(RFC2394) -<DT><B>--ip4</B> - -<DD> -add an SA for an IPv4-in-IPv4 -tunnel from -<I>encap-src</I> - -to -<I>encap-dst</I> - -<DT><B>--ip6</B> - -<DD> -add an SA for an IPv6-in-IPv6 -tunnel from -<I>encap-src</I> - -to -<I>encap-dst</I> - -<DT><B>--src</B> - -<DD> -specify the source end of an IP-in-IP tunnel from -<I>encap-src</I> - -to -<I>encap-dst</I> - -and also specifies the source address of the Security Association to be -used in inbound policy checking and must be the same address -family as -<I>af</I> - -and -<I>edst</I> - -<DT><B>--dst</B> - -<DD> -specify the destination end of an IP-in-IP tunnel from -<I>encap-src</I> - -to -<I>encap-dst</I> - -<DT><B>--del</B> - -<DD> -delete the specified SA -<DT><B>--clear</B> - -<DD> -clears the table of -<B>SA</B>s - -<DT><B>--help</B> - -<DD> -display synopsis -<DT><B>--version</B> - -<DD> -display version information -</DL> -<A NAME="lbAF"> </A> -<H2>EXAMPLES</H2> - -To keep line lengths down and reduce clutter, -some of the long keys in these examples have been abbreviated -by replacing part of their text with -``<I>...</I>''. - -Keys used when the programs are actually run must, -of course, be the full length required for the particular algorithm. -<P> - -<B>ipsec spi --af inet --edst gw2 --spi 0x125 --proto esp \</B> - -<BR> - -<B> --src gw1 \</B> - -<BR> - -<B> --esp 3des-md5-96 \</B> - -<BR> - -<B> --enckey 0x6630</B><I>...</I><B>97ce \</B> - -<BR> - -<B> --authkey 0x9941</B><I>...</I><B>71df</B> - -<P> - -sets up an SA from -<B>gw1</B> - -to -<B>gw2</B> - -with an SPI of -<B>0x125</B> - -and protocol -<B>ESP</B> - -(50) using -<B>3DES</B> - -encryption with integral -<B>MD5-96</B> - -authentication transform, using an encryption key of -<B>0x6630</B><I>...</I><B>97ce</B> - -and an authentication key of -<B>0x9941</B><I>...</I><B>71df</B> - -(see note above about abbreviated keys). -<P> - -<B>ipsec spi --af inet6 --edst 3049:9::9000:3100 --spi 0x150 --proto ah \</B> - -<BR> - -<B> --src 3049:9::9000:3101 \</B> - -<BR> - -<B> --ah hmac-md5-96 \</B> - -<BR> - -<B> --authkey 0x1234</B><I>...</I><B>2eda \</B> - -<P> - -sets up an SA from -<B>3049:9::9000:3101</B> - -to -<B>3049:9::9000:3100</B> - -with an SPI of -<B>0x150</B> - -and protocol -<B>AH</B> - -(50) using -<B>MD5-96</B> - -authentication transform, using an authentication key of -<B>0x1234</B><I>...</I><B>2eda</B> - -(see note above about abbreviated keys). -<P> - -<B>ipsec spi --said <A HREF="mailto:tun.987@192.168.100.100">tun.987@192.168.100.100</A> --del </B> - -<P> - -deletes an SA to -<B>192.168.100.100</B> - -with an SPI of -<B>0x987</B> - -and protocol -<B>IPv4-in-IPv4</B> - -(4). -<P> - -<B>ipsec spi --said tun:<A HREF="mailto:500@3049">500@3049</A>:9::1000:1 --del </B> - -<P> - -deletes an SA to -<B>3049:9::1000:1</B> - -with an SPI of -<B>0x500</B> - -and protocol -<B>IPv6-in-IPv6</B> - -(4). -<P> - -<A NAME="lbAG"> </A> -<H2>FILES</H2> - -/proc/net/ipsec_spi, /usr/local/bin/ipsec -<A NAME="lbAH"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A>(8), <A HREF="ipsec_eroute.8.html">ipsec_eroute</A>(8), -<A HREF="ipsec_spigrp.8.html">ipsec_spigrp</A>(8), <A HREF="ipsec_klipsdebug.8.html">ipsec_klipsdebug</A>(8), <A HREF="ipsec_spi.5.html">ipsec_spi</A>(5) -<A NAME="lbAI"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Richard Guy Briggs. -<A NAME="lbAJ"> </A> -<H2>BUGS</H2> - -The syntax is messy and the transform naming needs work. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">OPTIONS</A><DD> -<DT><A HREF="#lbAF">EXAMPLES</A><DD> -<DT><A HREF="#lbAG">FILES</A><DD> -<DT><A HREF="#lbAH">SEE ALSO</A><DD> -<DT><A HREF="#lbAI">HISTORY</A><DD> -<DT><A HREF="#lbAJ">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_spigrp.5.html b/doc/manpage.d/ipsec_spigrp.5.html deleted file mode 100644 index e0efcb73e..000000000 --- a/doc/manpage.d/ipsec_spigrp.5.html +++ /dev/null @@ -1,193 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_SPIGRP</TITLE> -</HEAD><BODY> -<H1>IPSEC_SPIGRP</H1> -Section: File Formats (5)<BR>Updated: 27 Jun 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec_spigrp - list IPSEC Security Association groupings -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>spigrp</B> - -<P> - -<B>cat</B> - -<B>/proc/net/ipsec_spigrp</B> - -<P> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>/proc/net/ipsec_spigrp</I> - -is a read-only file that lists groups of IPSEC Security Associations -(SAs). -<P> - -An entry in the IPSEC extended routing table can only point (via an -SAID) to one SA. If more than one transform must be applied to a given -type of packet, this can be accomplished by setting up several SAs with -the same destination address but potentially different SPIs and -protocols, and grouping them with -<I><A HREF="ipsec_spigrp.8.html">ipsec_spigrp</A>(8)</I>. - -<P> - -The SA groups are listed, one line per connection/group, as a sequence -of SAs to be applied (or that should have been applied, in the case of -an incoming packet) from inside to outside the packet. An SA is -identified by its SAID, which consists of protocol ("ah", "esp", "comp" or -"tun"), SPI (with '.' for IPv4 or ':' for IPv6 prefixed hexadecimal number ) and destination address -(IPv4 dotted quad or IPv6 coloned hex) prefixed by '@', in the format <proto><af><spi>@<dest>. -<A NAME="lbAE"> </A> -<H2>EXAMPLES</H2> - -<DL COMPACT> -<DT><B><A HREF="mailto:tun.3d0@192.168.2.110">tun.3d0@192.168.2.110</A></B> - -<DD> -<B><A HREF="mailto:comp.3d0@192.168.2.110">comp.3d0@192.168.2.110</A></B> - -<B><A HREF="mailto:esp.187a101b@192.168.2.110">esp.187a101b@192.168.2.110</A></B> - -<B><A HREF="mailto:ah.187a101a@192.168.2.110">ah.187a101a@192.168.2.110</A> </B> - -</DL> -<P> - -is a group of 3 SAs, destined for -<B>192.168.2.110</B> - -with an IPv4-in-IPv4 tunnel SA applied first with an SPI of -<B>3d0</B> - -in hexadecimal, followed by a Deflate compression header to compress -the packet with CPI of -<B>3d0</B> - -in hexadecimal, followed by an Encapsulating Security Payload header to -encrypt the packet with SPI -<B>187a101b</B> - -in hexadecimal, followed by an Authentication Header to authenticate the -packet with SPI -<B>187a101a</B> - -in hexadecimal, applied from inside to outside the packet. This could -be an incoming or outgoing group, depending on the address of the local -machine. -<P> - -<DL COMPACT> -<DT><B>tun:<A HREF="mailto:3d0@3049">3d0@3049</A>:1::2</B> - -<DD> -<B>comp:<A HREF="mailto:3d0@3049">3d0@3049</A>:1::2</B> - -<B>esp:<A HREF="mailto:187a101b@3049">187a101b@3049</A>:1::2</B> - -<B>ah:<A HREF="mailto:187a101a@3049">187a101a@3049</A>:1::2 </B> - -</DL> -<P> - -is a group of 3 SAs, destined for -<B>3049:1::2</B> - -with an IPv6-in-IPv6 tunnel SA applied first with an SPI of -<B>3d0</B> - -in hexadecimal, followed by a Deflate compression header to compress -the packet with CPI of -<B>3d0</B> - -in hexadecimal, followed by an Encapsulating Security Payload header to -encrypt the packet with SPI -<B>187a101b</B> - -in hexadecimal, followed by an Authentication Header to authenticate the -packet with SPI -<B>187a101a</B> - -in hexadecimal, applied from inside to outside the packet. This could -be an incoming or outgoing group, depending on the address of the local -machine. -<P> - -<A NAME="lbAF"> </A> -<H2>FILES</H2> - -/proc/net/ipsec_spigrp, /usr/local/bin/ipsec -<A NAME="lbAG"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_tncfg.5.html">ipsec_tncfg</A>(5), <A HREF="ipsec_eroute.5.html">ipsec_eroute</A>(5), -<A HREF="ipsec_spi.5.html">ipsec_spi</A>(5), <A HREF="ipsec_klipsdebug.5.html">ipsec_klipsdebug</A>(5), <A HREF="ipsec_spigrp.8.html">ipsec_spigrp</A>(8), <A HREF="ipsec_version.5.html">ipsec_version</A>(5), -<A HREF="ipsec_pf_key.5.html">ipsec_pf_key</A>(5) -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Richard Guy Briggs. -<A NAME="lbAI"> </A> -<H2>BUGS</H2> - -:-) - - - - - - - - - - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">EXAMPLES</A><DD> -<DT><A HREF="#lbAF">FILES</A><DD> -<DT><A HREF="#lbAG">SEE ALSO</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -<DT><A HREF="#lbAI">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_spigrp.8.html b/doc/manpage.d/ipsec_spigrp.8.html deleted file mode 100644 index 2e96c0574..000000000 --- a/doc/manpage.d/ipsec_spigrp.8.html +++ /dev/null @@ -1,280 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_SPIGRP</TITLE> -</HEAD><BODY> -<H1>IPSEC_SPIGRP</H1> -Section: Maintenance Commands (8)<BR>Updated: 21 Jun 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec spigrp - group/ungroup IPSEC Security Associations -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>spigrp</B> - -<P> - -<B>ipsec</B> - -<B>spigrp</B> - -[ -<B>--label</B> - -label ] -af1 dst1 spi1 proto1 [ af2 dst2 spi2 proto2 [ af3 dst3 spi3 proto3 [ af4 dst4 spi4 proto4 ] ] ] -<P> - -<B>ipsec</B> - -<B>spigrp</B> - -[ -<B>--label</B> - -label ] -<B>--said</B> - -SA1 [ SA2 [ SA3 [ SA4 ] ] ] -<P> - -<B>ipsec</B> - -<B>spigrp</B> - -<B>--help</B> - -<P> - -<B>ipsec</B> - -<B>spigrp</B> - -<B>--version</B> - -<P> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Spigrp</I> - -groups IPSEC Security Associations (SAs) together or ungroups -previously grouped SAs. -An entry in the IPSEC extended -routing table can only point -(via a destination address, a Security Parameters Index (SPI) and -a protocol identifier) to one SA. -If more than one transform must be applied to a given type of packet, -this can be accomplished by setting up several SAs -with the same destination address but potentially different SPIs and protocols, -and grouping them with -<I>spigrp</I>. - -<P> - -The SAs to be grouped, -specified by destination address (DNS name lookup, IPv4 dotted quad or IPv6 coloned hex), SPI -('0x'-prefixed hexadecimal number) and protocol ("ah", "esp", "comp" or "tun"), -are listed from the inside transform to the -outside; -in other words, the transforms are applied in -the order of the command line and removed in the reverse -order. -The resulting SA group is referred to by its first SA (by -<I>af1</I>, - -<I>dst1</I>, - -<I>spi1</I> - -and -<I>proto1</I>). - -<P> - -The --said option indicates that the SA IDs are to be specified as -one argument each, in the format <proto><af><spi>@<dest>. The SA IDs must -all be specified as separate parameters without the --said option or -all as monolithic parameters after the --said option. -<P> - -The SAs must already exist and must not already -be part of a group. -<P> - -If -<I>spigrp</I> - -is invoked with only one SA specification, -it ungroups the previously-grouped set of SAs containing -the SA specified. -<P> - -The --label option identifies all responses from that command -invocation with a user-supplied label, provided as an argument to the -label option. This can be helpful for debugging one invocation of the -command out of a large number. -<P> - -The command form with no additional arguments lists the contents of -/proc/net/ipsec_spigrp. The format of /proc/net/ipsec_spigrp is -discussed in <A HREF="ipsec_spigrp.5.html">ipsec_spigrp</A>(5). -<A NAME="lbAE"> </A> -<H2>EXAMPLES</H2> - -<DL COMPACT> -<DT><B>ipsec spigrp inet gw2 0x113 tun inet gw2 0x115 esp inet gw2 0x116 ah</B> - -<DD> -groups 3 SAs together, all destined for -<B>gw2</B>, - -but with an IPv4-in-IPv4 tunnel SA applied first with SPI -<B>0x113</B>, - -then an ESP header to encrypt the packet with SPI -<B>0x115</B>, - -and finally an AH header to authenticate the packet with SPI -<B>0x116</B>. - -</DL> -<P> - -<DL COMPACT> -<DT><B>ipsec spigrp --said tun.113@gw2 esp.115@gw2 ah.116@gw2 </B> - -<DD> -groups 3 SAs together, all destined for -<B>gw2</B>, - -but with an IPv4-in-IPv4 tunnel SA applied first with SPI -<B>0x113</B>, - -then an ESP header to encrypt the packet with SPI -<B>0x115</B>, - -and finally an AH header to authenticate the packet with SPI -<B>0x116</B>. - -</DL> -<P> - -<DL COMPACT> -<DT><B>ipsec spigrp --said tun:<A HREF="mailto:233@3049">233@3049</A>:1::1 esp:<A HREF="mailto:235@3049">235@3049</A>:1::1 ah:<A HREF="mailto:236@3049">236@3049</A>:1::1 </B> - -<DD> -groups 3 SAs together, all destined for -<B>3049:1::1,</B> - -but with an IPv6-in-IPv6 tunnel SA applied first with SPI -<B>0x233</B>, - -then an ESP header to encrypt the packet with SPI -<B>0x235</B>, - -and finally an AH header to authenticate the packet with SPI -<B>0x236</B>. - -</DL> -<P> - -<DL COMPACT> -<DT><B>ipsec spigrp inet6 3049:1::1 0x233 tun inet6 3049:1::1 0x235 esp inet6 3049:1::1 0x236 ah</B> - -<DD> -groups 3 SAs together, all destined for -<B>3049:1::1,</B> - -but with an IPv6-in-IPv6 tunnel SA applied first with SPI -<B>0x233</B>, - -then an ESP header to encrypt the packet with SPI -<B>0x235</B>, - -and finally an AH header to authenticate the packet with SPI -<B>0x236</B>. - -</DL> -<P> - -<A NAME="lbAF"> </A> -<H2>FILES</H2> - -/proc/net/ipsec_spigrp, /usr/local/bin/ipsec -<A NAME="lbAG"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A>(8), <A HREF="ipsec_eroute.8.html">ipsec_eroute</A>(8), -<A HREF="ipsec_spi.8.html">ipsec_spi</A>(8), <A HREF="ipsec_klipsdebug.8.html">ipsec_klipsdebug</A>(8), <A HREF="ipsec_spigrp.5.html">ipsec_spigrp</A>(5) -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Richard Guy Briggs. -<A NAME="lbAI"> </A> -<H2>BUGS</H2> - -Yes, it really is limited to a maximum of four SAs, -although admittedly it's hard to see why you would need more. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">EXAMPLES</A><DD> -<DT><A HREF="#lbAF">FILES</A><DD> -<DT><A HREF="#lbAG">SEE ALSO</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -<DT><A HREF="#lbAI">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_splitkeytoid.3.html b/doc/manpage.d/ipsec_splitkeytoid.3.html deleted file mode 100644 index 109cfafa7..000000000 --- a/doc/manpage.d/ipsec_splitkeytoid.3.html +++ /dev/null @@ -1,174 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_KEYBLOBTOID</TITLE> -</HEAD><BODY> -<H1>IPSEC_KEYBLOBTOID</H1> -Section: C Library Functions (3)<BR>Updated: 25 March 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec keyblobtoid, splitkeytoid - generate key IDs from RSA keys -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>size_t keyblobtoid(const unsigned char *blob,</B> - -<BR> - -<B>size_t bloblen, char *dst, size_t dstlen);</B> - -<BR> - -<B>size_t splitkeytoid(const unsigned char *e, size_t elen,</B> - -<BR> - -<B>const unsigned char *m, size_t mlen, char *dst,</B> - -<BR> - -<B>size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Keyblobtoid</I> - -and -<I>splitkeytoid</I> - -generate -key IDs -from RSA keys, -for use in messages and reporting, -writing the result to -<I>dst</I>. - -A -<I>key ID</I> - -is a short ASCII string identifying a key; -currently it is just the first nine characters of the base64 -encoding of the RFC 2537/3110 ``byte blob'' representation of the key. -(Beware that no finite key ID can be collision-proof: -there is always some small chance of two random keys having the -same ID.) -<P> - -<I>Keyblobtoid</I> - -generates a key ID from a key which is already in the form of an -RFC 2537/3110 binary key -<I>blob</I> - -(encoded exponent length, exponent, modulus). -<P> - -<I>Splitkeytoid</I> - -generates a key ID from a key given in the form of a separate -(binary) exponent -<I>e</I> - -and modulus -<I>m</I>. - -<P> - -The -<I>dstlen</I> - -parameter of either -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines a constant -<B>KEYID_BUF</B> - -which is the size of a buffer large enough for worst-case results. -<P> - -Both functions return -<B>0</B> - -for a failure, and otherwise -always return the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. - -With keys generated by -<I><A HREF="ipsec_rsasigkey.3.html">ipsec_rsasigkey</A></I>(3), - -the first two base64 digits are always the same, -and the third carries only about one bit of information. -It's worse with keys using longer fixed exponents, -e.g. the 24-bit exponent that's common in X.509 certificates. -However, being able to relate key IDs to the full -base64 text form of keys by eye is sufficiently useful that this -waste of space seems justifiable. -The choice of nine digits is a compromise between bulk and -probability of collision. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -RFC 3110, -<I>RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)</I>, -Eastlake, 2001 -(superseding the older but better-known RFC 2537). -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors are: -key too short to supply enough bits to construct a complete key ID -(almost certainly indicating a garbage key); -exponent too long for its length to be representable. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_subnetinsubnet.3.html b/doc/manpage.d/ipsec_subnetinsubnet.3.html deleted file mode 100644 index 414a0d513..000000000 --- a/doc/manpage.d/ipsec_subnetinsubnet.3.html +++ /dev/null @@ -1,274 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Nov 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec sameaddr - are two addresses the same? -<BR> - -ipsec addrcmp - ordered comparison of addresses -<BR> - -ipsec samesubnet - are two subnets the same? -<BR> - -ipsec addrinsubnet - is an address within a subnet? -<BR> - -ipsec subnetinsubnet - is a subnet within another subnet? -<BR> - -ipsec subnetishost - is a subnet a single host? -<BR> - -ipsec samesaid - are two SA IDs the same? -<BR> - -ipsec sameaddrtype - are two addresses of the same address family? -<BR> - -ipsec samesubnettype - are two subnets of the same address family? -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int sameaddr(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int addrcmp(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int addrinsubnet(const ip_address *a, const ip_subnet *s);</B> - -<BR> - -<B>int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int subnetishost(const ip_subnet *s);</B> - -<BR> - -<B>int samesaid(const ip_said *a, const ip_said *b);</B> - -<BR> - -<B>int sameaddrtype(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnettype(const ip_subnet *a, const ip_subnet *b);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions do various comparisons and tests on the -<I>ip_address</I> - -type and -<I>ip_subnet</I> - -types. -<P> - -<I>Sameaddr</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Addresses of different families are never identical. -<P> - -<I>Addrcmp</I> - -returns -<B>-1</B>, - -<B>0</B>, - -or -<B>1</B> - -respectively -if address -<I>a</I> - -is less than, equal to, or greater than -<I>b</I>. - -If they are not of the same address family, -they are never equal; -the ordering reported in this case is arbitrary -(and probably not useful) but consistent. -<P> - -<I>Samesubnet</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Subnets of different address families are never identical. -<P> - -<I>Addrinsubnet</I> - -returns -non-zero -if address -<I>a</I> - -is within subnet -<I>s</I> - -and -<B>0</B> - -otherwise. -An address is never within a -subnet of a different address family. -<P> - -<I>Subnetinsubnet</I> - -returns -non-zero -if subnet -<I>a</I> - -is a subset of subnet -<I>b</I> - -and -<B>0</B> - -otherwise. -A subnet is deemed to be a subset of itself. -A subnet is never a subset of another -subnet if their address families differ. -<P> - -<I>Subnetishost</I> - -returns -non-zero -if subnet -<I>s</I> - -is in fact only a single host, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesaid</I> - -returns -non-zero -if SA IDs -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -<P> - -<I>Sameaddrtype</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesubnettype</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_initaddr.3.html">ipsec_initaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_subnetishost.3.html b/doc/manpage.d/ipsec_subnetishost.3.html deleted file mode 100644 index 414a0d513..000000000 --- a/doc/manpage.d/ipsec_subnetishost.3.html +++ /dev/null @@ -1,274 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Nov 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec sameaddr - are two addresses the same? -<BR> - -ipsec addrcmp - ordered comparison of addresses -<BR> - -ipsec samesubnet - are two subnets the same? -<BR> - -ipsec addrinsubnet - is an address within a subnet? -<BR> - -ipsec subnetinsubnet - is a subnet within another subnet? -<BR> - -ipsec subnetishost - is a subnet a single host? -<BR> - -ipsec samesaid - are two SA IDs the same? -<BR> - -ipsec sameaddrtype - are two addresses of the same address family? -<BR> - -ipsec samesubnettype - are two subnets of the same address family? -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>int sameaddr(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int addrcmp(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int addrinsubnet(const ip_address *a, const ip_subnet *s);</B> - -<BR> - -<B>int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);</B> - -<BR> - -<B>int subnetishost(const ip_subnet *s);</B> - -<BR> - -<B>int samesaid(const ip_said *a, const ip_said *b);</B> - -<BR> - -<B>int sameaddrtype(const ip_address *a, const ip_address *b);</B> - -<BR> - -<B>int samesubnettype(const ip_subnet *a, const ip_subnet *b);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions do various comparisons and tests on the -<I>ip_address</I> - -type and -<I>ip_subnet</I> - -types. -<P> - -<I>Sameaddr</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Addresses of different families are never identical. -<P> - -<I>Addrcmp</I> - -returns -<B>-1</B>, - -<B>0</B>, - -or -<B>1</B> - -respectively -if address -<I>a</I> - -is less than, equal to, or greater than -<I>b</I>. - -If they are not of the same address family, -they are never equal; -the ordering reported in this case is arbitrary -(and probably not useful) but consistent. -<P> - -<I>Samesubnet</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -Subnets of different address families are never identical. -<P> - -<I>Addrinsubnet</I> - -returns -non-zero -if address -<I>a</I> - -is within subnet -<I>s</I> - -and -<B>0</B> - -otherwise. -An address is never within a -subnet of a different address family. -<P> - -<I>Subnetinsubnet</I> - -returns -non-zero -if subnet -<I>a</I> - -is a subset of subnet -<I>b</I> - -and -<B>0</B> - -otherwise. -A subnet is deemed to be a subset of itself. -A subnet is never a subset of another -subnet if their address families differ. -<P> - -<I>Subnetishost</I> - -returns -non-zero -if subnet -<I>s</I> - -is in fact only a single host, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesaid</I> - -returns -non-zero -if SA IDs -<I>a</I> - -and -<I>b</I> - -are identical, -and -<B>0</B> - -otherwise. -<P> - -<I>Sameaddrtype</I> - -returns -non-zero -if addresses -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<P> - -<I>Samesubnettype</I> - -returns -non-zero -if subnets -<I>a</I> - -and -<I>b</I> - -are of the same address family, -and -<B>0</B> - -otherwise. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_initaddr.3.html">ipsec_initaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_subnetof.3.html b/doc/manpage.d/ipsec_subnetof.3.html deleted file mode 100644 index a185d716b..000000000 --- a/doc/manpage.d/ipsec_subnetof.3.html +++ /dev/null @@ -1,107 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_SUBNETOF</TITLE> -</HEAD><BODY> -<H1>IPSEC_SUBNETOF</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec subnetof - given Internet address and subnet mask, return subnet number -<BR> - -ipsec hostof - given Internet address and subnet mask, return host part -<BR> - -ipsec broadcastof - given Internet address and subnet mask, return broadcast address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>struct in_addr subnetof(struct in_addr addr,</B> - -<BR> - -<B>struct in_addr mask);</B> - -<BR> - -<B>struct in_addr hostof(struct in_addr addr,</B> - -<BR> - -<B>struct in_addr mask);</B> - -<BR> - -<B>struct in_addr broadcastof(struct in_addr addr,</B> - -<BR> - -<B>struct in_addr mask);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; see -<I><A HREF="ipsec_networkof.3.html">ipsec_networkof</A></I>(3) - -for their replacements. -<P> - -<I>Subnetof</I> - -takes an Internet -<I>address</I> - -and a subnet -<I>mask</I> - -and returns the network part of the address -(all in network byte order). -<I>Hostof</I> - -similarly returns the host part, and -<I>broadcastof</I> - -returns the broadcast address (all-1s convention) for the network. -<P> - -These functions are provided to hide the Internet bit-munging inside -an API, in hopes of easing the eventual transition to IPv6. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAG"> </A> -<H2>BUGS</H2> - -Calling functions for this is more costly than doing it yourself. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -<DT><A HREF="#lbAG">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_subnettoa.3.html b/doc/manpage.d/ipsec_subnettoa.3.html deleted file mode 100644 index 718fa935a..000000000 --- a/doc/manpage.d/ipsec_subnettoa.3.html +++ /dev/null @@ -1,448 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ATOADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ATOADDR</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec atoaddr, addrtoa - convert Internet addresses to and from ASCII -<BR> - -ipsec atosubnet, subnettoa - convert subnet/mask ASCII form to and from addresses -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *atoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>struct in_addr *addr);</B> - -<BR> - -<B>size_t addrtoa(struct in_addr addr, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<P> -<B>const char *atosubnet(const char *src, size_t srclen,</B> - -<BR> - -<B>struct in_addr *addr, struct in_addr *mask);</B> - -<BR> - -<B>size_t subnettoa(struct in_addr addr, struct in_addr mask,</B> - -<BR> - -<B>int format, char *dst, size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; see -<I><A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A></I>(3) - -for their replacements. -<P> - -<I>Atoaddr</I> - -converts an ASCII name or dotted-decimal address into a binary address -(in network byte order). -<I>Addrtoa</I> - -does the reverse conversion, back to an ASCII dotted-decimal address. -<I>Atosubnet</I> - -and -<I>subnettoa</I> - -do likewise for the ``address/mask'' ASCII form used to write a -specification of a subnet. -<P> - -An address is specified in ASCII as a -dotted-decimal address (e.g. -<B>1.2.3.4</B>), - -an eight-digit network-order hexadecimal number with the usual C prefix (e.g. -<B>0x01020304</B>, - -which is synonymous with -<B>1.2.3.4</B>), - -an eight-digit host-order hexadecimal number with a -<B>0h</B> - -prefix (e.g. -<B>0h01020304</B>, - -which is synonymous with -<B>1.2.3.4</B> - -on a big-endian host and -<B>4.3.2.1</B> - -on a little-endian host), -a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3), - -or an old-style network name to be looked up via -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3). - -<P> - -A dotted-decimal address may be incomplete, in which case -ASCII-to-binary conversion implicitly appends -as many instances of -<B>.0</B> - -as necessary to bring it up to four components. -The components of a dotted-decimal address are always taken as -decimal, and leading zeros are ignored. -For example, -<B>10</B> - -is synonymous with -<B>10.0.0.0</B>, - -and -<B>128.009.000.032</B> - -is synonymous with -<B>128.9.0.32</B> - -(the latter example is verbatim from RFC 1166). -The result of -<I>addrtoa</I> - -is always complete and does not contain leading zeros. -<P> - -The letters in -a hexadecimal address may be uppercase or lowercase or any mixture thereof. -Use of hexadecimal addresses is -<B>strongly</B> - -<B>discouraged</B>; - -they are included only to save hassles when dealing with -the handful of perverted programs which already print -network addresses in hexadecimal. -<P> - -DNS names may be complete (optionally terminated with a ``.'') -or incomplete, and are looked up as specified by local system configuration -(see -<I><A HREF="resolver.5.html">resolver</A></I>(5)). - -The -<I>h_addr</I> - -value returned by -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3) - -is used, -so with current DNS implementations, -the result when the name corresponds to more than one address is -difficult to predict. -Name lookup resorts to -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3) - -only if -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3) - -fails. -<P> - -A subnet specification is of the form <I>network</I><B>/</B><I>mask</I>. -The -<I>network</I> - -and -<I>mask</I> - -can be any form acceptable to -<I>atoaddr</I>. - -In addition, the -<I>mask</I> - -can be a decimal integer (leading zeros ignored) giving a bit count, -in which case -it stands for a mask with that number of high bits on and all others off -(e.g., -<B>24</B> - -means -<B>255.255.255.0</B>). - -In any case, the mask must be contiguous -(a sequence of high bits on and all remaining low bits off). -As a special case, the subnet specification -<B>%default</B> - -is a synonym for -<B>0.0.0.0/0</B>. - -<P> - -<I>Atosubnet</I> - -ANDs the mask with the address before returning, -so that any non-network bits in the address are turned off -(e.g., -<B>10.1.2.3/24</B> - -is synonymous with -<B>10.1.2.0/24</B>). - -<I>Subnettoa</I> - -generates the decimal-integer-bit-count -form of the mask, -with no leading zeros, -unless the mask is non-contiguous. -<P> - -The -<I>srclen</I> - -parameter of -<I>atoaddr</I> - -and -<I>atosubnet</I> - -specifies the length of the ASCII string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>addrtoa</I> - -and -<I>subnettoa</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines constants, -<B>ADDRTOA_BUF</B> - -and -<B>SUBNETTOA_BUF</B>, - -which are the sizes of buffers just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>addrtoa</I> - -and -<I>subnettoa</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the ASCII character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default, -and is in fact the only format currently available. -This parameter is a hedge against future needs. -<P> - -The ASCII-to-binary functions return NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -The binary-to-ASCII functions return -<B>0</B> - -for a failure, and otherwise -always return the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>atoaddr</I> - -are: -empty input; -attempt to allocate temporary storage for a very long name failed; -name lookup failed; -syntax error in dotted-decimal form; -dotted-decimal component too large to fit in 8 bits. -<P> - -Fatal errors in -<I>atosubnet</I> - -are: -no -<B>/</B> - -in -<I>src</I>; - -<I>atoaddr</I> - -error in conversion of -<I>network</I> - -or -<I>mask</I>; - -bit-count mask too big; -mask non-contiguous. -<P> - -Fatal errors in -<I>addrtoa</I> - -and -<I>subnettoa</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The interpretation of incomplete dotted-decimal addresses -(e.g. -<B>10/24</B> - -means -<B>10.0.0.0/24</B>) - -differs from that of some older conversion -functions, e.g. those of -<I><A HREF="inet.3.html">inet</A></I>(3). - -The behavior of the older functions has never been -particularly consistent or particularly useful. -<P> - -Ignoring leading zeros in dotted-decimal components and bit counts -is arguably the most useful behavior in this application, -but it might occasionally cause confusion with the historical use of leading -zeros to denote octal numbers. -<P> - -It is barely possible that somebody, somewhere, -might have a legitimate use for non-contiguous subnet masks. -<P> - -<I><A HREF="Getnetbyname.3.html">Getnetbyname</A></I>(3) - -is a historical dreg. -<P> - -The restriction of ASCII-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The ASCII-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = atoaddr( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_subnettot.3.html b/doc/manpage.d/ipsec_subnettot.3.html deleted file mode 100644 index 199937a35..000000000 --- a/doc/manpage.d/ipsec_subnettot.3.html +++ /dev/null @@ -1,569 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TTOADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_TTOADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Sept 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ttoaddr, tnatoaddr, addrtot - convert Internet addresses to and from text -<BR> - -ipsec ttosubnet, subnettot - convert subnet/mask text form to and from addresses -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *ttoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *addr);</B> - -<BR> - -<B>const char *tnatoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *addr);</B> - -<BR> - -<B>size_t addrtot(const ip_address *addr, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<P> -<B>const char *ttosubnet(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_subnet *dst);</B> - -<BR> - -<B>size_t subnettot(const ip_subnet *sub, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ttoaddr</I> - -converts a text-string name or numeric address into a binary address -(in network byte order). -<I>Tnatoaddr</I> - -does the same conversion, -but the only text forms it accepts are -the ``official'' forms of -numeric address (dotted-decimal for IPv4, colon-hex for IPv6). -<I>Addrtot</I> - -does the reverse conversion, from binary address back to a text form. -<I>Ttosubnet</I> - -and -<I>subnettot</I> - -do likewise for the ``address/mask'' form used to write a -specification of a subnet. -<P> - -An IPv4 address is specified in text as a -dotted-decimal address (e.g. -<B>1.2.3.4</B>), - -an eight-digit network-order hexadecimal number with the usual C prefix (e.g. -<B>0x01020304</B>, - -which is synonymous with -<B>1.2.3.4</B>), - -an eight-digit host-order hexadecimal number with a -<B>0h</B> - -prefix (e.g. -<B>0h01020304</B>, - -which is synonymous with -<B>1.2.3.4</B> - -on a big-endian host and -<B>4.3.2.1</B> - -on a little-endian host), -a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3), - -or an old-style network name to be looked up via -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3). - -<P> - -A dotted-decimal address may be incomplete, in which case -text-to-binary conversion implicitly appends -as many instances of -<B>.0</B> - -as necessary to bring it up to four components. -The components of a dotted-decimal address are always taken as -decimal, and leading zeros are ignored. -For example, -<B>10</B> - -is synonymous with -<B>10.0.0.0</B>, - -and -<B>128.009.000.032</B> - -is synonymous with -<B>128.9.0.32</B> - -(the latter example is verbatim from RFC 1166). -The result of applying -<I>addrtot</I> - -to an IPv4 address is always complete and does not contain leading zeros. -<P> - -Use of hexadecimal addresses is -<B>strongly</B> - -<B>discouraged</B>; - -they are included only to save hassles when dealing with -the handful of perverted programs which already print -network addresses in hexadecimal. -<P> - -An IPv6 address is specified in text with -colon-hex notation (e.g. -<B>0:56:78ab:22:33:44:55:66</B>), - -colon-hex with -<B>::</B> - -abbreviating at most one subsequence of multiple zeros (e.g. -<B>99:ab::54:068</B>, - -which is synonymous with -<B>99:ab:0:0:0:0:54:68</B>), - -or a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3). - -The result of applying -<I>addrtot</I> - -to an IPv6 address will use -<B>::</B> - -abbreviation if possible, -and will not contain leading zeros. -<P> - -The letters in hexadecimal -may be uppercase or lowercase or any mixture thereof. -<P> - -DNS names may be complete (optionally terminated with a ``.'') -or incomplete, and are looked up as specified by local system configuration -(see -<I><A HREF="resolver.5.html">resolver</A></I>(5)). - -The -<I>h_addr</I> - -value returned by -<I><A HREF="gethostbyname2.3.html">gethostbyname2</A></I>(3) - -is used, -so with current DNS implementations, -the result when the name corresponds to more than one address is -difficult to predict. -IPv4 name lookup resorts to -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3) - -only if -<I><A HREF="gethostbyname2.3.html">gethostbyname2</A></I>(3) - -fails. -<P> - -A subnet specification is of the form <I>network</I><B>/</B><I>mask</I>. -The -<I>network</I> - -and -<I>mask</I> - -can be any form acceptable to -<I>ttoaddr</I>. - -In addition, and preferably, the -<I>mask</I> - -can be a decimal integer (leading zeros ignored) giving a bit count, -in which case -it stands for a mask with that number of high bits on and all others off -(e.g., -<B>24</B> - -in IPv4 means -<B>255.255.255.0</B>). - -In any case, the mask must be contiguous -(a sequence of high bits on and all remaining low bits off). -As a special case, the subnet specification -<B>%default</B> - -is a synonym for -<B>0.0.0.0/0</B> - -or -<B>::/0</B> - -in IPv4 or IPv6 respectively. -<P> - -<I>Ttosubnet</I> - -ANDs the mask with the address before returning, -so that any non-network bits in the address are turned off -(e.g., -<B>10.1.2.3/24</B> - -is synonymous with -<B>10.1.2.0/24</B>). - -<I>Subnettot</I> - -always generates the decimal-integer-bit-count -form of the mask, -with no leading zeros. -<P> - -The -<I>srclen</I> - -parameter of -<I>ttoaddr</I> - -and -<I>ttosubnet</I> - -specifies the length of the text string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>af</I> - -parameter of -<I>ttoaddr</I> - -and -<I>ttosubnet</I> - -specifies the address family of interest. -It should be either -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>addrtot</I> - -and -<I>subnettot</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines constants, -<B>ADDRTOT_BUF</B> - -and -<B>SUBNETTOT_BUF</B>, - -which are the sizes of buffers just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>addrtot</I> - -and -<I>subnettot</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default, -and is in fact the only format currently available in -<I>subnettot</I>. - -<I>Addrtot</I> - -also accepts format values -<B>'r'</B> - -(signifying a text form suitable for DNS reverse lookups, -e.g. -<B>4.3.2.1.IN-ADDR.ARPA.</B> - -for IPv4 and -RFC 2874 format for IPv6), -and -<B>'R'</B> - -(signifying an alternate reverse-lookup form, -an error for IPv4 and RFC 1886 format for IPv6). -Reverse-lookup names always end with a ``.''. -<P> - -The text-to-binary functions return NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -The binary-to-text functions return -<B>0</B> - -for a failure, and otherwise -always return the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>ttoaddr</I> - -are: -empty input; -unknown address family; -attempt to allocate temporary storage for a very long name failed; -name lookup failed; -syntax error in dotted-decimal or colon-hex form; -dotted-decimal or colon-hex component too large. -<P> - -Fatal errors in -<I>ttosubnet</I> - -are: -no -<B>/</B> - -in -<I>src</I>; - -<I>ttoaddr</I> - -error in conversion of -<I>network</I> - -or -<I>mask</I>; - -bit-count mask too big; -mask non-contiguous. -<P> - -Fatal errors in -<I>addrtot</I> - -and -<I>subnettot</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The interpretation of incomplete dotted-decimal addresses -(e.g. -<B>10/24</B> - -means -<B>10.0.0.0/24</B>) - -differs from that of some older conversion -functions, e.g. those of -<I><A HREF="inet.3.html">inet</A></I>(3). - -The behavior of the older functions has never been -particularly consistent or particularly useful. -<P> - -Ignoring leading zeros in dotted-decimal components and bit counts -is arguably the most useful behavior in this application, -but it might occasionally cause confusion with the historical use of leading -zeros to denote octal numbers. -<P> - -<I>Ttoaddr</I> - -does not support the mixed colon-hex-dotted-decimal -convention used to embed an IPv4 address in an IPv6 address. -<P> - -<I>Addrtot</I> - -always uses the -<B>::</B> - -abbreviation (which can appear only once in an address) for the -<I>first</I> - -sequence of multiple zeros in an IPv6 address. -One can construct addresses (unlikely ones) in which this is suboptimal. -<P> - -<I>Addrtot</I> - -<B>'r'</B> - -conversion of an IPv6 address uses lowercase hexadecimal, -not the uppercase used in RFC 2874's examples. -It takes careful reading of RFCs 2874, 2673, and 2234 to realize -that lowercase is technically legitimate here, -and there may be software which botches this -and hence would have trouble with lowercase hex. -<P> - -Possibly -<I>subnettot</I> - -ought to recognize the -<B>%default</B> - -case and generate that string as its output. -Currently it doesn't. -<P> - -It is barely possible that somebody, somewhere, -might have a legitimate use for non-contiguous subnet masks. -<P> - -<I><A HREF="Getnetbyname.3.html">Getnetbyname</A></I>(3) - -is a historical dreg. -<P> - -<I>Tnatoaddr</I> - -probably should enforce completeness of dotted-decimal addresses. -<P> - -The restriction of text-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The text-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = ttoaddr( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_subnettypeof.3.html b/doc/manpage.d/ipsec_subnettypeof.3.html deleted file mode 100644 index ea0f83f82..000000000 --- a/doc/manpage.d/ipsec_subnettypeof.3.html +++ /dev/null @@ -1,238 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_INITSUBNET</TITLE> -</HEAD><BODY> -<H1>IPSEC_INITSUBNET</H1> -Section: C Library Functions (3)<BR>Updated: 12 March 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec initsubnet - initialize an ip_subnet -<BR> - -ipsec addrtosubnet - initialize a singleton ip_subnet -<BR> - -ipsec subnettypeof - get address type of an ip_subnet -<BR> - -ipsec masktocount - convert subnet mask to bit count -<BR> - -ipsec networkof - get base address of an ip_subnet -<BR> - -ipsec maskof - get subnet mask of an ip_subnet -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *initsubnet(const ip_address *addr,</B> - -<BR> - -<B>int maskbits, int clash, ip_subnet *dst);</B> - -<BR> - -<B>const char *addrtosubnet(const ip_address *addr,</B> - -<BR> - -<B>ip_subnet *dst);</B> - -<P> -<B>int subnettypeof(const ip_subnet *src);</B> - -<BR> - -<B>int masktocount(const ip_address *src);</B> - -<BR> - -<B>void networkof(const ip_subnet *src, ip_address *dst);</B> - -<BR> - -<B>void maskof(const ip_subnet *src, ip_address *dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -library uses an internal type -<I>ip_subnet</I> - -to contain a description of an IP subnet -(base address plus mask). -These functions provide basic tools for creating and examining this type. -<P> - -<I>Initsubnet</I> - -initializes a variable -<I>*dst</I> - -of type -<I>ip_subnet</I> - -from a base address and -a count of mask bits. -The -<I>clash</I> - -parameter specifies what to do if the base address includes -<B>1</B> - -bits outside the prefix specified by the mask -(that is, in the ``host number'' part of the address): -<DL COMPACT><DT><DD> -<DL COMPACT> -<DT>'0'<DD> -zero out host-number bits -<DT>'x'<DD> -non-zero host-number bits are an error -</DL> -</DL> - -<P> - -<I>Initsubnet</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<P> - -<I>Addrtosubnet</I> - -initializes an -<I>ip_subnet</I> - -variable -<I>*dst</I> - -to a ``singleton subnet'' containing the single address -<I>*addr</I>. - -It returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure. -<P> - -<I>Subnettypeof</I> - -returns the address type of a subnet, -normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -(The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file arranges to include the necessary headers for these -names to be known.) -<P> - -<I>Masktocount</I> - -converts a subnet mask, expressed as an address, to a bit count -suitable for use with -<I>initsubnet</I>. - -It returns -<B>-1</B> - -for error; see DIAGNOSTICS. -<P> - -<I>Networkof</I> - -fills in -<I>*dst</I> - -with the base address of subnet -<I>src</I>. - -<P> - -<I>Maskof</I> - -fills in -<I>*dst</I> - -with the subnet mask of subnet -<I>src</I>, - -expressed as an address. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_ttosubnet.3.html">ipsec_ttosubnet</A>(3), <A HREF="ipsec_rangetosubnet.3.html">ipsec_rangetosubnet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>initsubnet</I> - -are: -unknown address family; -unknown -<I>clash</I> - -value; -impossible mask bit count; -non-zero host-number bits and -<I>clash</I> - -is -<B>'x'</B>. - -Fatal errors in -<I>addrtosubnet</I> - -are: -unknown address family. -Fatal errors in -<I>masktocount</I> - -are: -unknown address family; -mask bits not contiguous. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_tnatoaddr.3.html b/doc/manpage.d/ipsec_tnatoaddr.3.html deleted file mode 100644 index 199937a35..000000000 --- a/doc/manpage.d/ipsec_tnatoaddr.3.html +++ /dev/null @@ -1,569 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TTOADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_TTOADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Sept 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ttoaddr, tnatoaddr, addrtot - convert Internet addresses to and from text -<BR> - -ipsec ttosubnet, subnettot - convert subnet/mask text form to and from addresses -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *ttoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *addr);</B> - -<BR> - -<B>const char *tnatoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *addr);</B> - -<BR> - -<B>size_t addrtot(const ip_address *addr, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<P> -<B>const char *ttosubnet(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_subnet *dst);</B> - -<BR> - -<B>size_t subnettot(const ip_subnet *sub, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ttoaddr</I> - -converts a text-string name or numeric address into a binary address -(in network byte order). -<I>Tnatoaddr</I> - -does the same conversion, -but the only text forms it accepts are -the ``official'' forms of -numeric address (dotted-decimal for IPv4, colon-hex for IPv6). -<I>Addrtot</I> - -does the reverse conversion, from binary address back to a text form. -<I>Ttosubnet</I> - -and -<I>subnettot</I> - -do likewise for the ``address/mask'' form used to write a -specification of a subnet. -<P> - -An IPv4 address is specified in text as a -dotted-decimal address (e.g. -<B>1.2.3.4</B>), - -an eight-digit network-order hexadecimal number with the usual C prefix (e.g. -<B>0x01020304</B>, - -which is synonymous with -<B>1.2.3.4</B>), - -an eight-digit host-order hexadecimal number with a -<B>0h</B> - -prefix (e.g. -<B>0h01020304</B>, - -which is synonymous with -<B>1.2.3.4</B> - -on a big-endian host and -<B>4.3.2.1</B> - -on a little-endian host), -a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3), - -or an old-style network name to be looked up via -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3). - -<P> - -A dotted-decimal address may be incomplete, in which case -text-to-binary conversion implicitly appends -as many instances of -<B>.0</B> - -as necessary to bring it up to four components. -The components of a dotted-decimal address are always taken as -decimal, and leading zeros are ignored. -For example, -<B>10</B> - -is synonymous with -<B>10.0.0.0</B>, - -and -<B>128.009.000.032</B> - -is synonymous with -<B>128.9.0.32</B> - -(the latter example is verbatim from RFC 1166). -The result of applying -<I>addrtot</I> - -to an IPv4 address is always complete and does not contain leading zeros. -<P> - -Use of hexadecimal addresses is -<B>strongly</B> - -<B>discouraged</B>; - -they are included only to save hassles when dealing with -the handful of perverted programs which already print -network addresses in hexadecimal. -<P> - -An IPv6 address is specified in text with -colon-hex notation (e.g. -<B>0:56:78ab:22:33:44:55:66</B>), - -colon-hex with -<B>::</B> - -abbreviating at most one subsequence of multiple zeros (e.g. -<B>99:ab::54:068</B>, - -which is synonymous with -<B>99:ab:0:0:0:0:54:68</B>), - -or a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3). - -The result of applying -<I>addrtot</I> - -to an IPv6 address will use -<B>::</B> - -abbreviation if possible, -and will not contain leading zeros. -<P> - -The letters in hexadecimal -may be uppercase or lowercase or any mixture thereof. -<P> - -DNS names may be complete (optionally terminated with a ``.'') -or incomplete, and are looked up as specified by local system configuration -(see -<I><A HREF="resolver.5.html">resolver</A></I>(5)). - -The -<I>h_addr</I> - -value returned by -<I><A HREF="gethostbyname2.3.html">gethostbyname2</A></I>(3) - -is used, -so with current DNS implementations, -the result when the name corresponds to more than one address is -difficult to predict. -IPv4 name lookup resorts to -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3) - -only if -<I><A HREF="gethostbyname2.3.html">gethostbyname2</A></I>(3) - -fails. -<P> - -A subnet specification is of the form <I>network</I><B>/</B><I>mask</I>. -The -<I>network</I> - -and -<I>mask</I> - -can be any form acceptable to -<I>ttoaddr</I>. - -In addition, and preferably, the -<I>mask</I> - -can be a decimal integer (leading zeros ignored) giving a bit count, -in which case -it stands for a mask with that number of high bits on and all others off -(e.g., -<B>24</B> - -in IPv4 means -<B>255.255.255.0</B>). - -In any case, the mask must be contiguous -(a sequence of high bits on and all remaining low bits off). -As a special case, the subnet specification -<B>%default</B> - -is a synonym for -<B>0.0.0.0/0</B> - -or -<B>::/0</B> - -in IPv4 or IPv6 respectively. -<P> - -<I>Ttosubnet</I> - -ANDs the mask with the address before returning, -so that any non-network bits in the address are turned off -(e.g., -<B>10.1.2.3/24</B> - -is synonymous with -<B>10.1.2.0/24</B>). - -<I>Subnettot</I> - -always generates the decimal-integer-bit-count -form of the mask, -with no leading zeros. -<P> - -The -<I>srclen</I> - -parameter of -<I>ttoaddr</I> - -and -<I>ttosubnet</I> - -specifies the length of the text string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>af</I> - -parameter of -<I>ttoaddr</I> - -and -<I>ttosubnet</I> - -specifies the address family of interest. -It should be either -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>addrtot</I> - -and -<I>subnettot</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines constants, -<B>ADDRTOT_BUF</B> - -and -<B>SUBNETTOT_BUF</B>, - -which are the sizes of buffers just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>addrtot</I> - -and -<I>subnettot</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default, -and is in fact the only format currently available in -<I>subnettot</I>. - -<I>Addrtot</I> - -also accepts format values -<B>'r'</B> - -(signifying a text form suitable for DNS reverse lookups, -e.g. -<B>4.3.2.1.IN-ADDR.ARPA.</B> - -for IPv4 and -RFC 2874 format for IPv6), -and -<B>'R'</B> - -(signifying an alternate reverse-lookup form, -an error for IPv4 and RFC 1886 format for IPv6). -Reverse-lookup names always end with a ``.''. -<P> - -The text-to-binary functions return NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -The binary-to-text functions return -<B>0</B> - -for a failure, and otherwise -always return the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>ttoaddr</I> - -are: -empty input; -unknown address family; -attempt to allocate temporary storage for a very long name failed; -name lookup failed; -syntax error in dotted-decimal or colon-hex form; -dotted-decimal or colon-hex component too large. -<P> - -Fatal errors in -<I>ttosubnet</I> - -are: -no -<B>/</B> - -in -<I>src</I>; - -<I>ttoaddr</I> - -error in conversion of -<I>network</I> - -or -<I>mask</I>; - -bit-count mask too big; -mask non-contiguous. -<P> - -Fatal errors in -<I>addrtot</I> - -and -<I>subnettot</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The interpretation of incomplete dotted-decimal addresses -(e.g. -<B>10/24</B> - -means -<B>10.0.0.0/24</B>) - -differs from that of some older conversion -functions, e.g. those of -<I><A HREF="inet.3.html">inet</A></I>(3). - -The behavior of the older functions has never been -particularly consistent or particularly useful. -<P> - -Ignoring leading zeros in dotted-decimal components and bit counts -is arguably the most useful behavior in this application, -but it might occasionally cause confusion with the historical use of leading -zeros to denote octal numbers. -<P> - -<I>Ttoaddr</I> - -does not support the mixed colon-hex-dotted-decimal -convention used to embed an IPv4 address in an IPv6 address. -<P> - -<I>Addrtot</I> - -always uses the -<B>::</B> - -abbreviation (which can appear only once in an address) for the -<I>first</I> - -sequence of multiple zeros in an IPv6 address. -One can construct addresses (unlikely ones) in which this is suboptimal. -<P> - -<I>Addrtot</I> - -<B>'r'</B> - -conversion of an IPv6 address uses lowercase hexadecimal, -not the uppercase used in RFC 2874's examples. -It takes careful reading of RFCs 2874, 2673, and 2234 to realize -that lowercase is technically legitimate here, -and there may be software which botches this -and hence would have trouble with lowercase hex. -<P> - -Possibly -<I>subnettot</I> - -ought to recognize the -<B>%default</B> - -case and generate that string as its output. -Currently it doesn't. -<P> - -It is barely possible that somebody, somewhere, -might have a legitimate use for non-contiguous subnet masks. -<P> - -<I><A HREF="Getnetbyname.3.html">Getnetbyname</A></I>(3) - -is a historical dreg. -<P> - -<I>Tnatoaddr</I> - -probably should enforce completeness of dotted-decimal addresses. -<P> - -The restriction of text-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The text-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = ttoaddr( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_tncfg.5.html b/doc/manpage.d/ipsec_tncfg.5.html deleted file mode 100644 index e4082a28f..000000000 --- a/doc/manpage.d/ipsec_tncfg.5.html +++ /dev/null @@ -1,175 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TNCFG</TITLE> -</HEAD><BODY> -<H1>IPSEC_TNCFG</H1> -Section: File Formats (5)<BR>Updated: 27 Jun 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec_tncfg - lists IPSEC virtual interfaces attached to real interfaces -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>tncfg</B> - -<P> - -<B>cat</B> - -<B>/proc/net/ipsec_tncfg</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>/proc/net/ipsec_tncfg</I> - -is a read-only file which lists which IPSEC virtual interfaces are -attached to which real interfaces, through which packets will be -forwarded once processed by IPSEC. -<P> - -Each line lists one ipsec I/F. -A table entry consists of: -<DL COMPACT> -<DT>+<DD> -an ipsec virtual I/F name -<DT>+<DD> -a visual and machine parsable separator '->', separating the virtual I/F -and the physical I/F, -<DT>+<DD> -a physical I/F name, to which the ipsec virtual I/F is attached or NULL -if it is not attached, -<DT>+<DD> -the keyword -<B>mtu=</B>, - -<DT>+<DD> -the MTU of the ipsec virtual I/F, -<DT>+<DD> -the automatically adjusted effective MTU for PMTU discovery, in brackets, -<DT>+<DD> -a visual and machine parsable separator '->', separating the virtual I/F -MTU and the physical I/F MTU, -<DT>+<DD> -the MTU of the attached physical I/F. -<B>.SH</B>EXAMPLES - -<DT><B>ipsec2 -> eth3 mtu=16260(1443) -> 1500</B> - -<DD> -</DL> -<P> - -shows that virtual device -<B>ipsec2</B> - -with an MTU of -<B>16260</B> - -is connected to physical device -<B>eth3</B> - -with an MTU of -<B>1500</B> - -and that the effective MTU as a result of PMTU discovery has been -automatically set to -<B>1443.</B> - -<DL COMPACT> -<DT><B>ipsec0 -> wvlan0 mtu=1400(16260) -> 1500</B> - -<DD> -</DL> -<P> - -shows that virtual device -<B>ipsec0</B> - -with an MTU of -<B>1400</B> - -is connected to physical device -<B>wvlan0</B> - -with an MTU of -<B>1500</B> - -and no PMTU packets have gotten far enough to bump down the effective MTU -from its default of 16260. -<DL COMPACT> -<DT><B>ipsec3 -> NULL mtu=0(0) -> 0</B> - -<DD> -</DL> -<P> - -shows that virtual device -<B>ipsec3</B> - -is not connected to any physical device. -<P> - -<A NAME="lbAE"> </A> -<H2>FILES</H2> - -/proc/net/ipsec_tncfg, /usr/local/bin/ipsec -<A NAME="lbAF"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_eroute.5.html">ipsec_eroute</A>(5), <A HREF="ipsec_spi.5.html">ipsec_spi</A>(5), -<A HREF="ipsec_spigrp.5.html">ipsec_spigrp</A>(5), <A HREF="ipsec_klipsdebug.5.html">ipsec_klipsdebug</A>(5), <A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A>(8), <A HREF="ipsec_version.5.html">ipsec_version</A>(5), -<A HREF="ipsec_pf_key.5.html">ipsec_pf_key</A>(5) -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Richard Guy Briggs. - - - - - - - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">SEE ALSO</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_tncfg.8.html b/doc/manpage.d/ipsec_tncfg.8.html deleted file mode 100644 index e5965267c..000000000 --- a/doc/manpage.d/ipsec_tncfg.8.html +++ /dev/null @@ -1,195 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TNCFG</TITLE> -</HEAD><BODY> -<H1>IPSEC_TNCFG</H1> -Section: Maintenance Commands (8)<BR>Updated: 21 Jun 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec tncfg - associate IPSEC virtual interface with physical interface -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>tncfg</B> - -<P> - -<B>ipsec</B> - -<B>tncfg</B> - -<B>--attach</B> - -<B>--virtual</B> - -virtual -<B>--physical</B> - -physical -<P> - -<B>ipsec</B> - -<B>tncfg</B> - -<B>--detach</B> - -<B>--virtual</B> - -virtual -<P> - -<B>ipsec</B> - -<B>tncfg</B> - -<B>--clear</B> - -<P> - -<B>ipsec</B> - -<B>tncfg</B> - -<B>--version</B> - -<P> - -<B>ipsec</B> - -<B>tncfg</B> - -<B>--help</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Tncfg</I> - -attaches/detaches IPSEC virtual interfaces to/from -physical interfaces, -through which packets will be forwarded once processed by IPSEC. -<P> - -The form with no additional arguments lists the contents of -/proc/net/ipsec_tncfg. The format of /proc/net/ipsec_tncfg is discussed -in <A HREF="ipsec_tncfg.5.html">ipsec_tncfg</A>(5). -The -<B>--attach</B> - -form attaches the -<I>virtual</I> - -interface to the -<I>physical</I> - -one. -The -<B>--detach</B> - -form detaches the -<I>virtual</I> - -interface from whichever physical interface it is attached to. -The -<B>--clear</B> - -form clears all the -<I>virtual</I> - -interfaces from whichever physical interfaces they were attached to. -<P> - -Virtual interfaces typically have names like -<B>ipsec0</B>, - -while physical interfaces typically have names like -<B>eth0</B> - -or -<B>ppp0</B>. - -<A NAME="lbAE"> </A> -<H2>EXAMPLES</H2> - -<DL COMPACT> -<DT><B>ipsec tncfg --attach --virtual ipsec0 --physical eth0</B> - -<DD> -attaches the -<B>ipsec0</B> - -virtual device to the -<B>eth0</B> - -physical device. -</DL> -<P> - -<A NAME="lbAF"> </A> -<H2>FILES</H2> - -/proc/net/ipsec_tncfg, /usr/local/bin/ipsec -<A NAME="lbAG"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_eroute.8.html">ipsec_eroute</A>(8), <A HREF="ipsec_spi.8.html">ipsec_spi</A>(8), -<A HREF="ipsec_spigrp.8.html">ipsec_spigrp</A>(8), <A HREF="ipsec_klipsdebug.8.html">ipsec_klipsdebug</A>(8), <A HREF="ipsec_tncfg.5.html">ipsec_tncfg</A>(5) -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Richard Guy Briggs. - - - - - - - - - - - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">EXAMPLES</A><DD> -<DT><A HREF="#lbAF">FILES</A><DD> -<DT><A HREF="#lbAG">SEE ALSO</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_trap_count.5.html b/doc/manpage.d/ipsec_trap_count.5.html deleted file mode 100644 index 8da655f77..000000000 --- a/doc/manpage.d/ipsec_trap_count.5.html +++ /dev/null @@ -1,74 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TRAP_COUNT</TITLE> -</HEAD><BODY> -<H1>IPSEC_TRAP_COUNT</H1> -Section: File Formats (5)<BR>Updated: 19 Jun 2003<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -trap_count - KLIPS statistic on number of ACQUIREs -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>cat</B> - -<B>/proc/net/ipsec/stats/trap_count</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>/proc/net/ipsec/stats/trap_count</I> - -is a read-only file. It contains a hexadecimal number which records the -number of attempts to send PF_ACQUIRE messages. Only those recorded by -trap_sendcount were actually successfully passed to userland. Note that the -userland may still have lost them on its own. -<P> - -<A NAME="lbAE"> </A> -<H2>FILES</H2> - -/proc/net/ipsec/stats/trap_sendcount -<A NAME="lbAF"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_pf_key.5.html">ipsec_pf_key</A>(5), <A HREF="trap_sendcount.5.html">trap_sendcount</A>(5), <A HREF="pluto.8.html">pluto</A>(8) -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael C. Richardson <<A HREF="mailto:mcr@freeswan.org">mcr@freeswan.org</A>> - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">SEE ALSO</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_trap_sendcount.5.html b/doc/manpage.d/ipsec_trap_sendcount.5.html deleted file mode 100644 index 94f56b3a7..000000000 --- a/doc/manpage.d/ipsec_trap_sendcount.5.html +++ /dev/null @@ -1,72 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TRAP_SENDCOUNT</TITLE> -</HEAD><BODY> -<H1>IPSEC_TRAP_SENDCOUNT</H1> -Section: File Formats (5)<BR>Updated: 19 Jun 2003<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -trap_sendcount - KLIPS statistic on number of successful ACQUIREs -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>cat</B> - -<B>/proc/net/ipsec/stats/trap_sendcount</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>/proc/net/ipsec/stats/trap_sendcount</I> - -is a read-only file. It contains a hexadecimal number which records the -number of successful PF_ACQUIRE messages that were sent. -<P> - -<A NAME="lbAE"> </A> -<H2>FILES</H2> - -/proc/net/ipsec/stats/trap_sendcount -<A NAME="lbAF"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_pf_key.5.html">ipsec_pf_key</A>(5), <A HREF="trap_count.5.html">trap_count</A>(5), <A HREF="pluto.8.html">pluto</A>(8) -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Michael C. Richardson <<A HREF="mailto:mcr@freeswan.org">mcr@freeswan.org</A>> - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">SEE ALSO</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_ttoaddr.3.html b/doc/manpage.d/ipsec_ttoaddr.3.html deleted file mode 100644 index 199937a35..000000000 --- a/doc/manpage.d/ipsec_ttoaddr.3.html +++ /dev/null @@ -1,569 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TTOADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_TTOADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Sept 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ttoaddr, tnatoaddr, addrtot - convert Internet addresses to and from text -<BR> - -ipsec ttosubnet, subnettot - convert subnet/mask text form to and from addresses -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *ttoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *addr);</B> - -<BR> - -<B>const char *tnatoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *addr);</B> - -<BR> - -<B>size_t addrtot(const ip_address *addr, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<P> -<B>const char *ttosubnet(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_subnet *dst);</B> - -<BR> - -<B>size_t subnettot(const ip_subnet *sub, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ttoaddr</I> - -converts a text-string name or numeric address into a binary address -(in network byte order). -<I>Tnatoaddr</I> - -does the same conversion, -but the only text forms it accepts are -the ``official'' forms of -numeric address (dotted-decimal for IPv4, colon-hex for IPv6). -<I>Addrtot</I> - -does the reverse conversion, from binary address back to a text form. -<I>Ttosubnet</I> - -and -<I>subnettot</I> - -do likewise for the ``address/mask'' form used to write a -specification of a subnet. -<P> - -An IPv4 address is specified in text as a -dotted-decimal address (e.g. -<B>1.2.3.4</B>), - -an eight-digit network-order hexadecimal number with the usual C prefix (e.g. -<B>0x01020304</B>, - -which is synonymous with -<B>1.2.3.4</B>), - -an eight-digit host-order hexadecimal number with a -<B>0h</B> - -prefix (e.g. -<B>0h01020304</B>, - -which is synonymous with -<B>1.2.3.4</B> - -on a big-endian host and -<B>4.3.2.1</B> - -on a little-endian host), -a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3), - -or an old-style network name to be looked up via -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3). - -<P> - -A dotted-decimal address may be incomplete, in which case -text-to-binary conversion implicitly appends -as many instances of -<B>.0</B> - -as necessary to bring it up to four components. -The components of a dotted-decimal address are always taken as -decimal, and leading zeros are ignored. -For example, -<B>10</B> - -is synonymous with -<B>10.0.0.0</B>, - -and -<B>128.009.000.032</B> - -is synonymous with -<B>128.9.0.32</B> - -(the latter example is verbatim from RFC 1166). -The result of applying -<I>addrtot</I> - -to an IPv4 address is always complete and does not contain leading zeros. -<P> - -Use of hexadecimal addresses is -<B>strongly</B> - -<B>discouraged</B>; - -they are included only to save hassles when dealing with -the handful of perverted programs which already print -network addresses in hexadecimal. -<P> - -An IPv6 address is specified in text with -colon-hex notation (e.g. -<B>0:56:78ab:22:33:44:55:66</B>), - -colon-hex with -<B>::</B> - -abbreviating at most one subsequence of multiple zeros (e.g. -<B>99:ab::54:068</B>, - -which is synonymous with -<B>99:ab:0:0:0:0:54:68</B>), - -or a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3). - -The result of applying -<I>addrtot</I> - -to an IPv6 address will use -<B>::</B> - -abbreviation if possible, -and will not contain leading zeros. -<P> - -The letters in hexadecimal -may be uppercase or lowercase or any mixture thereof. -<P> - -DNS names may be complete (optionally terminated with a ``.'') -or incomplete, and are looked up as specified by local system configuration -(see -<I><A HREF="resolver.5.html">resolver</A></I>(5)). - -The -<I>h_addr</I> - -value returned by -<I><A HREF="gethostbyname2.3.html">gethostbyname2</A></I>(3) - -is used, -so with current DNS implementations, -the result when the name corresponds to more than one address is -difficult to predict. -IPv4 name lookup resorts to -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3) - -only if -<I><A HREF="gethostbyname2.3.html">gethostbyname2</A></I>(3) - -fails. -<P> - -A subnet specification is of the form <I>network</I><B>/</B><I>mask</I>. -The -<I>network</I> - -and -<I>mask</I> - -can be any form acceptable to -<I>ttoaddr</I>. - -In addition, and preferably, the -<I>mask</I> - -can be a decimal integer (leading zeros ignored) giving a bit count, -in which case -it stands for a mask with that number of high bits on and all others off -(e.g., -<B>24</B> - -in IPv4 means -<B>255.255.255.0</B>). - -In any case, the mask must be contiguous -(a sequence of high bits on and all remaining low bits off). -As a special case, the subnet specification -<B>%default</B> - -is a synonym for -<B>0.0.0.0/0</B> - -or -<B>::/0</B> - -in IPv4 or IPv6 respectively. -<P> - -<I>Ttosubnet</I> - -ANDs the mask with the address before returning, -so that any non-network bits in the address are turned off -(e.g., -<B>10.1.2.3/24</B> - -is synonymous with -<B>10.1.2.0/24</B>). - -<I>Subnettot</I> - -always generates the decimal-integer-bit-count -form of the mask, -with no leading zeros. -<P> - -The -<I>srclen</I> - -parameter of -<I>ttoaddr</I> - -and -<I>ttosubnet</I> - -specifies the length of the text string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>af</I> - -parameter of -<I>ttoaddr</I> - -and -<I>ttosubnet</I> - -specifies the address family of interest. -It should be either -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>addrtot</I> - -and -<I>subnettot</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines constants, -<B>ADDRTOT_BUF</B> - -and -<B>SUBNETTOT_BUF</B>, - -which are the sizes of buffers just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>addrtot</I> - -and -<I>subnettot</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default, -and is in fact the only format currently available in -<I>subnettot</I>. - -<I>Addrtot</I> - -also accepts format values -<B>'r'</B> - -(signifying a text form suitable for DNS reverse lookups, -e.g. -<B>4.3.2.1.IN-ADDR.ARPA.</B> - -for IPv4 and -RFC 2874 format for IPv6), -and -<B>'R'</B> - -(signifying an alternate reverse-lookup form, -an error for IPv4 and RFC 1886 format for IPv6). -Reverse-lookup names always end with a ``.''. -<P> - -The text-to-binary functions return NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -The binary-to-text functions return -<B>0</B> - -for a failure, and otherwise -always return the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>ttoaddr</I> - -are: -empty input; -unknown address family; -attempt to allocate temporary storage for a very long name failed; -name lookup failed; -syntax error in dotted-decimal or colon-hex form; -dotted-decimal or colon-hex component too large. -<P> - -Fatal errors in -<I>ttosubnet</I> - -are: -no -<B>/</B> - -in -<I>src</I>; - -<I>ttoaddr</I> - -error in conversion of -<I>network</I> - -or -<I>mask</I>; - -bit-count mask too big; -mask non-contiguous. -<P> - -Fatal errors in -<I>addrtot</I> - -and -<I>subnettot</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The interpretation of incomplete dotted-decimal addresses -(e.g. -<B>10/24</B> - -means -<B>10.0.0.0/24</B>) - -differs from that of some older conversion -functions, e.g. those of -<I><A HREF="inet.3.html">inet</A></I>(3). - -The behavior of the older functions has never been -particularly consistent or particularly useful. -<P> - -Ignoring leading zeros in dotted-decimal components and bit counts -is arguably the most useful behavior in this application, -but it might occasionally cause confusion with the historical use of leading -zeros to denote octal numbers. -<P> - -<I>Ttoaddr</I> - -does not support the mixed colon-hex-dotted-decimal -convention used to embed an IPv4 address in an IPv6 address. -<P> - -<I>Addrtot</I> - -always uses the -<B>::</B> - -abbreviation (which can appear only once in an address) for the -<I>first</I> - -sequence of multiple zeros in an IPv6 address. -One can construct addresses (unlikely ones) in which this is suboptimal. -<P> - -<I>Addrtot</I> - -<B>'r'</B> - -conversion of an IPv6 address uses lowercase hexadecimal, -not the uppercase used in RFC 2874's examples. -It takes careful reading of RFCs 2874, 2673, and 2234 to realize -that lowercase is technically legitimate here, -and there may be software which botches this -and hence would have trouble with lowercase hex. -<P> - -Possibly -<I>subnettot</I> - -ought to recognize the -<B>%default</B> - -case and generate that string as its output. -Currently it doesn't. -<P> - -It is barely possible that somebody, somewhere, -might have a legitimate use for non-contiguous subnet masks. -<P> - -<I><A HREF="Getnetbyname.3.html">Getnetbyname</A></I>(3) - -is a historical dreg. -<P> - -<I>Tnatoaddr</I> - -probably should enforce completeness of dotted-decimal addresses. -<P> - -The restriction of text-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The text-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = ttoaddr( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_ttodata.3.html b/doc/manpage.d/ipsec_ttodata.3.html deleted file mode 100644 index 960392fe0..000000000 --- a/doc/manpage.d/ipsec_ttodata.3.html +++ /dev/null @@ -1,439 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TTODATA</TITLE> -</HEAD><BODY> -<H1>IPSEC_TTODATA</H1> -Section: C Library Functions (3)<BR>Updated: 16 August 2003<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ttodata, datatot - convert binary data bytes from and to text formats -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *ttodata(const char *src, size_t srclen,</B> - -<BR> - -<B>int base, char *dst, size_t dstlen, size_t *lenp);</B> - -<BR> - -<B>const char *ttodatav(const char *src, size_t srclen,</B> - -<BR> - -<B>int base, char *dst, size_t dstlen, size_t *lenp,</B> - -<BR> - -<B>char *errp, size_t errlen, int flags);</B> - -<BR> - -<B>size_t datatot(const char *src, size_t srclen,</B> - -<BR> - -<B>int format, char *dst, size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ttodata</I>, - -<I>ttodatav</I>, - -and -<I>datatot</I> - -convert arbitrary binary data (e.g. encryption or authentication keys) -from and to more-or-less human-readable text formats. -<P> - -Currently supported formats are hexadecimal, base64, and characters. -<P> - -A hexadecimal text value begins with a -<B>0x</B> - -(or -<B>0X</B>) - -prefix and continues with two-digit groups -of hexadecimal digits (0-9, and a-f or A-F), -each group encoding the value of one binary byte, high-order digit first. -A single -<B>_</B> - -(underscore) -between consecutive groups is ignored, permitting punctuation to improve -readability; doing this every eight digits seems about right. -<P> - -A base64 text value begins with a -<B>0s</B> - -(or -<B>0S</B>) - -prefix -and continues with four-digit groups of base64 digits (A-Z, a-z, 0-9, +, and /), -each group encoding the value of three binary bytes as described in -section 6.8 of RFC 2045. -If -<B>flags</B> - -has the -<B>TTODATAV_IGNORESPACE</B> - -bit on, blanks are ignore (after the prefix). -Note that the last one or two digits of a base64 group can be -<B>=</B> - -to indicate that fewer than three binary bytes are encoded. -<P> - -A character text value begins with a -<B>0t</B> - -(or -<B>0T</B>) - -prefix -and continues with text characters, each being the value of one binary byte. -<P> - -All these functions basically copy data from -<I>src</I> - -(whose size is specified by -<I>srclen</I>) - -to -<I>dst</I> - -(whose size is specified by -<I>dstlen</I>), - -doing the conversion en route. -If the result will not fit in -<I>dst</I>, - -it is truncated; -under no circumstances are more than -<I>dstlen</I> - -bytes of result written to -<I>dst</I>. - -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result bytes are written at all. -<P> - -The -<I>base</I> - -parameter of -<I>ttodata</I> - -and -<I>ttodatav</I> - -specifies what format the input is in; -normally it should be -<B>0</B> - -to signify that this gets figured out from the prefix. -Values of -<B>16</B>, - -<B>64</B>, - -and -<B>256</B> - -respectively signify hexadecimal, base64, and character-text formats -without prefixes. -<P> - -The -<I>format</I> - -parameter of -<I>datatot</I>, - -a single character used as a type code, -specifies which text format is wanted. -The value -<B>0</B> - -(not ASCII -<B>'0'</B>, - -but a zero value) specifies a reasonable default. -Other currently-supported values are: -<DL COMPACT><DT><DD> -<DL COMPACT> -<DT><B>'x'</B> - -<DD> -continuous lower-case hexadecimal with a -<B>0x</B> - -prefix -<DT><B>'h'</B> - -<DD> -lower-case hexadecimal with a -<B>0x</B> - -prefix and a -<B>_</B> - -every eight digits -<DT><B>':'</B> - -<DD> -lower-case hexadecimal with no prefix and a -<B>:</B> - -(colon) every two digits -<DT><B>16</B> - -<DD> -lower-case hexadecimal with no prefix or -<B>_</B> - -<DT><B>'s'</B> - -<DD> -continuous base64 with a -<B>0s</B> - -prefix -<DT><B>64</B> - -<DD> -continuous base64 with no prefix -</DL> -</DL> - -<P> - -The default format is currently -<B>'h'</B>. - -<P> - -<I>Ttodata</I> - -returns NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -On success, -if and only if -<I>lenp</I> - -is non-NULL, -<B>*lenp</B> - -is set to the number of bytes required to contain the full untruncated result. -It is the caller's responsibility to check this against -<I>dstlen</I> - -to determine whether he has obtained a complete result. -The -<B>*lenp</B> - -value is correct even if -<I>dstlen</I> - -is zero, which offers a way to determine how much space would be needed -before having to allocate any. -<P> - -<I>Ttodatav</I> - -is just like -<I>ttodata</I> - -except that in certain cases, -if -<I>errp</I> - -is non-NULL, -the buffer pointed to by -<I>errp</I> - -(whose length is given by -<I>errlen</I>) - -is used to hold a more detailed error message. -The return value is NULL for success, -and is either -<I>errp</I> - -or a pointer to a string literal for failure. -If the size of the error-message buffer is -inadequate for the desired message, -<I>ttodatav</I> - -will fall back on returning a pointer to a literal string instead. -The -<I>freeswan.h</I> - -header file defines a constant -<B>TTODATAV_BUF</B> - -which is the size of a buffer large enough for worst-case results. -<P> - -The normal return value of -<I>datatot</I> - -is the number of bytes required -to contain the full untruncated result. -It is the caller's responsibility to check this against -<I>dstlen</I> - -to determine whether he has obtained a complete result. -The return value is correct even if -<I>dstlen</I> - -is zero, which offers a way to determine how much space would be needed -before having to allocate any. -A return value of -<B>0</B> - -signals a fatal error of some kind -(see DIAGNOSTICS). -<P> - -A zero value for -<I>srclen</I> - -in -<I>ttodata</I> - -(but not -<I>datatot</I>!) - -is synonymous with -<B>strlen(src)</B>. - -A non-zero -<I>srclen</I> - -in -<I>ttodata</I> - -must not include the terminating NUL. -<P> - -Unless -<I>dstlen</I> - -is zero, -the result supplied by -<I>datatot</I> - -is always NUL-terminated, -and its needed-size return value includes space for the terminating NUL. -<P> - -Several obsolete variants of these functions -(<I>atodata</I>, - -<I>datatoa</I>, - -<I>atobytes</I>, - -and -<I>bytestoa</I>) - -are temporarily also supported. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="sprintf.3.html">sprintf</A>(3), <A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>ttodata</I> - -and -<I>ttodatav</I> - -are: -unknown characters in the input; -unknown or missing prefix; -unknown base; -incomplete digit group; -non-zero padding in a base64 less-than-three-bytes digit group; -zero-length input. -<P> - -Fatal errors in -<I>datatot</I> - -are: -unknown format code; -zero-length input. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -<I>Datatot</I> - -should have a format code to produce character-text output. -<P> - -The -<B>0s</B> - -and -<B>0t</B> - -prefixes are the author's inventions and are not a standard -of any kind. -They have been chosen to avoid collisions with existing practice -(some C implementations use -<B>0b</B> - -for binary) -and possible confusion with unprefixed hexadecimal. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_ttosa.3.html b/doc/manpage.d/ipsec_ttosa.3.html deleted file mode 100644 index 1e457fc24..000000000 --- a/doc/manpage.d/ipsec_ttosa.3.html +++ /dev/null @@ -1,453 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TTOSA</TITLE> -</HEAD><BODY> -<H1>IPSEC_TTOSA</H1> -Section: C Library Functions (3)<BR>Updated: 26 Nov 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ttosa, satot - convert IPsec Security Association IDs to and from text -<BR> - -ipsec initsaid - initialize an SA ID -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>typedef struct {</B> - -<BR> - -<B>ip_address dst;</B> - -<BR> - -<B>ipsec_spi_t spi;</B> - -<BR> - -<B>int proto;</B> - -<BR> - -<B>} ip_said;</B> - -<P> -<B>const char *ttosa(const char *src, size_t srclen,</B> - -<BR> - -<B>ip_said *sa);</B> - -<BR> - -<B>size_t satot(const ip_said *sa, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<BR> - -<B>void initsaid(const ip_address *addr, ipsec_spi_t spi,</B> - -<BR> - -<B>int proto, ip_said *dst);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ttosa</I> - -converts an ASCII Security Association (SA) specifier into an -<B>ip_said</B> - -structure (containing -a destination-host address -in network byte order, -an SPI number in network byte order, and -a protocol code). -<I>Satot</I> - -does the reverse conversion, back to a text SA specifier. -<I>Initsaid</I> - -initializes an -<B>ip_said</B> - -from separate items of information. -<P> - -An SA is specified in text with a mail-like syntax, e.g. -<B><A HREF="mailto:esp.5a7@1.2.3.4">esp.5a7@1.2.3.4</A></B>. - -An SA specifier contains -a protocol prefix (currently -<B>ah</B>, - -<B>esp</B>, - -<B>tun</B>, - -<B>comp</B>, - -or -<B>int</B>), - -a single character indicating the address family -(<B>.</B> - -for IPv4, -<B>:</B> - -for IPv6), -an unsigned integer SPI number in hexadecimal (with no -<B>0x</B> - -prefix), -and an IP address. -The IP address can be any form accepted by -<I><A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A></I>(3), - -e.g. dotted-decimal IPv4 address, -colon-hex IPv6 address, -or DNS name. -<P> - -As a special case, the SA specifier -<B>%passthrough4</B> - -or -<B>%passthrough6</B> - -signifies the special SA used to indicate that packets should be -passed through unaltered. -(At present, these are synonyms for -<B><A HREF="mailto:tun.0@0.0.0.0">tun.0@0.0.0.0</A></B> - -and -<B>tun:0@::</B> - -respectively, -but that is subject to change without notice.) -<B>%passthrough</B> - -is a historical synonym for -<B>%passthrough4</B>. - -These forms are known to both -<I>ttosa</I> - -and -<I>satot</I>, - -so the internal representation is never visible. -<P> - -Similarly, the SA specifiers -<B>%pass</B>, - -<B>%drop</B>, - -<B>%reject</B>, - -<B>%hold</B>, - -<B>%trap</B>, - -and -<B>%trapsubnet</B> - -signify special ``magic'' SAs used to indicate that packets should be -passed, dropped, rejected (dropped with ICMP notification), -held, -and trapped (sent up to -<I><A HREF="ipsec_pluto.8.html">ipsec_pluto</A></I>(8), - -with either of two forms of -<B>%hold</B> - -automatically installed) -respectively. -These forms too are known to both routines, -so the internal representation of the magic SAs should never be visible. -<P> - -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file supplies the -<B>ip_said</B> - -structure, as well as a data type -<B>ipsec_spi_t</B> - -which is an unsigned 32-bit integer. -(There is no consistency between kernel and user on what such a type -is called, hence the header hides the differences.) -<P> - -The protocol code uses the same numbers that IP does. -For user convenience, given the difficulty in acquiring the exact set of -protocol names used by the kernel, -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -defines the names -<B>SA_ESP</B>, - -<B>SA_AH</B>, - -<B>SA_IPIP</B>, - -and -<B>SA_COMP</B> - -to have the same values as the kernel names -<B>IPPROTO_ESP</B>, - -<B>IPPROTO_AH</B>, - -<B>IPPROTO_IPIP</B>, - -and -<B>IPPROTO_COMP</B>. - -<P> - -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -also defines -<B>SA_INT</B> - -to have the value -<B>61</B> - -(reserved by IANA for ``any host internal protocol'') -and -<B>SPI_PASS</B>, - -<B>SPI_DROP</B>, - -<B>SPI_REJECT</B>, - -<B>SPI_HOLD</B>, - -and -<B>SPI_TRAP</B> - -to have the values 256-260 (in <I>host</I> byte order) respectively. -These are used in constructing the magic SAs -(which always have address -<B>0.0.0.0</B>). - -<P> - -If -<I>satot</I> - -encounters an unknown protocol code, e.g. 77, -it yields output using a prefix -showing the code numerically, e.g. ``unk77''. -This form is -<I>not</I> - -recognized by -<I>ttosa</I>. - -<P> - -The -<I>srclen</I> - -parameter of -<I>ttosa</I> - -specifies the length of the string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>satot</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<B><<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -header file defines a constant, -<B>SATOT_BUF</B>, - -which is the size of a buffer just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>satot</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the ASCII character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default -(currently -lowercase protocol prefix, lowercase hexadecimal SPI, -dotted-decimal or colon-hex address). -The value -<B>'f'</B> - -is similar except that the SPI is padded with -<B>0</B>s - -to a fixed 32-bit width, to ease aligning displayed tables. -<P> - -<I>Ttosa</I> - -returns -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<I>Satot</I> - -returns -<B>0</B> - -for a failure, and otherwise -always returns the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<P> - -There is also, temporarily, support for some obsolete -forms of SA specifier which lack the address-family indicator. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec_ttoul.3.html">ipsec_ttoul</A>(3), <A HREF="ipsec_ttoaddr.3.html">ipsec_ttoaddr</A>(3), <A HREF="ipsec_samesaid.3.html">ipsec_samesaid</A>(3), <A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>ttosa</I> - -are: -empty input; -input too small to be a legal SA specifier; -no -<B>@</B> - -in input; -unknown protocol prefix; -conversion error in -<I>ttoul</I> - -or -<I>ttoaddr</I>. - -<P> - -Fatal errors in -<I>satot</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The restriction of text-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The text-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = ttosa( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_ttosubnet.3.html b/doc/manpage.d/ipsec_ttosubnet.3.html deleted file mode 100644 index 199937a35..000000000 --- a/doc/manpage.d/ipsec_ttosubnet.3.html +++ /dev/null @@ -1,569 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TTOADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_TTOADDR</H1> -Section: C Library Functions (3)<BR>Updated: 28 Sept 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ttoaddr, tnatoaddr, addrtot - convert Internet addresses to and from text -<BR> - -ipsec ttosubnet, subnettot - convert subnet/mask text form to and from addresses -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *ttoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *addr);</B> - -<BR> - -<B>const char *tnatoaddr(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_address *addr);</B> - -<BR> - -<B>size_t addrtot(const ip_address *addr, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<P> -<B>const char *ttosubnet(const char *src, size_t srclen,</B> - -<BR> - -<B>int af, ip_subnet *dst);</B> - -<BR> - -<B>size_t subnettot(const ip_subnet *sub, int format,</B> - -<BR> - -<B>char *dst, size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ttoaddr</I> - -converts a text-string name or numeric address into a binary address -(in network byte order). -<I>Tnatoaddr</I> - -does the same conversion, -but the only text forms it accepts are -the ``official'' forms of -numeric address (dotted-decimal for IPv4, colon-hex for IPv6). -<I>Addrtot</I> - -does the reverse conversion, from binary address back to a text form. -<I>Ttosubnet</I> - -and -<I>subnettot</I> - -do likewise for the ``address/mask'' form used to write a -specification of a subnet. -<P> - -An IPv4 address is specified in text as a -dotted-decimal address (e.g. -<B>1.2.3.4</B>), - -an eight-digit network-order hexadecimal number with the usual C prefix (e.g. -<B>0x01020304</B>, - -which is synonymous with -<B>1.2.3.4</B>), - -an eight-digit host-order hexadecimal number with a -<B>0h</B> - -prefix (e.g. -<B>0h01020304</B>, - -which is synonymous with -<B>1.2.3.4</B> - -on a big-endian host and -<B>4.3.2.1</B> - -on a little-endian host), -a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3), - -or an old-style network name to be looked up via -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3). - -<P> - -A dotted-decimal address may be incomplete, in which case -text-to-binary conversion implicitly appends -as many instances of -<B>.0</B> - -as necessary to bring it up to four components. -The components of a dotted-decimal address are always taken as -decimal, and leading zeros are ignored. -For example, -<B>10</B> - -is synonymous with -<B>10.0.0.0</B>, - -and -<B>128.009.000.032</B> - -is synonymous with -<B>128.9.0.32</B> - -(the latter example is verbatim from RFC 1166). -The result of applying -<I>addrtot</I> - -to an IPv4 address is always complete and does not contain leading zeros. -<P> - -Use of hexadecimal addresses is -<B>strongly</B> - -<B>discouraged</B>; - -they are included only to save hassles when dealing with -the handful of perverted programs which already print -network addresses in hexadecimal. -<P> - -An IPv6 address is specified in text with -colon-hex notation (e.g. -<B>0:56:78ab:22:33:44:55:66</B>), - -colon-hex with -<B>::</B> - -abbreviating at most one subsequence of multiple zeros (e.g. -<B>99:ab::54:068</B>, - -which is synonymous with -<B>99:ab:0:0:0:0:54:68</B>), - -or a DNS name to be looked up via -<I><A HREF="gethostbyname.3.html">gethostbyname</A></I>(3). - -The result of applying -<I>addrtot</I> - -to an IPv6 address will use -<B>::</B> - -abbreviation if possible, -and will not contain leading zeros. -<P> - -The letters in hexadecimal -may be uppercase or lowercase or any mixture thereof. -<P> - -DNS names may be complete (optionally terminated with a ``.'') -or incomplete, and are looked up as specified by local system configuration -(see -<I><A HREF="resolver.5.html">resolver</A></I>(5)). - -The -<I>h_addr</I> - -value returned by -<I><A HREF="gethostbyname2.3.html">gethostbyname2</A></I>(3) - -is used, -so with current DNS implementations, -the result when the name corresponds to more than one address is -difficult to predict. -IPv4 name lookup resorts to -<I><A HREF="getnetbyname.3.html">getnetbyname</A></I>(3) - -only if -<I><A HREF="gethostbyname2.3.html">gethostbyname2</A></I>(3) - -fails. -<P> - -A subnet specification is of the form <I>network</I><B>/</B><I>mask</I>. -The -<I>network</I> - -and -<I>mask</I> - -can be any form acceptable to -<I>ttoaddr</I>. - -In addition, and preferably, the -<I>mask</I> - -can be a decimal integer (leading zeros ignored) giving a bit count, -in which case -it stands for a mask with that number of high bits on and all others off -(e.g., -<B>24</B> - -in IPv4 means -<B>255.255.255.0</B>). - -In any case, the mask must be contiguous -(a sequence of high bits on and all remaining low bits off). -As a special case, the subnet specification -<B>%default</B> - -is a synonym for -<B>0.0.0.0/0</B> - -or -<B>::/0</B> - -in IPv4 or IPv6 respectively. -<P> - -<I>Ttosubnet</I> - -ANDs the mask with the address before returning, -so that any non-network bits in the address are turned off -(e.g., -<B>10.1.2.3/24</B> - -is synonymous with -<B>10.1.2.0/24</B>). - -<I>Subnettot</I> - -always generates the decimal-integer-bit-count -form of the mask, -with no leading zeros. -<P> - -The -<I>srclen</I> - -parameter of -<I>ttoaddr</I> - -and -<I>ttosubnet</I> - -specifies the length of the text string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>af</I> - -parameter of -<I>ttoaddr</I> - -and -<I>ttosubnet</I> - -specifies the address family of interest. -It should be either -<B>AF_INET</B> - -or -<B>AF_INET6</B>. - -<P> - -The -<I>dstlen</I> - -parameter of -<I>addrtot</I> - -and -<I>subnettot</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines constants, -<B>ADDRTOT_BUF</B> - -and -<B>SUBNETTOT_BUF</B>, - -which are the sizes of buffers just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>addrtot</I> - -and -<I>subnettot</I> - -specifies what format is to be used for the conversion. -The value -<B>0</B> - -(not the character -<B>'0'</B>, - -but a zero value) -specifies a reasonable default, -and is in fact the only format currently available in -<I>subnettot</I>. - -<I>Addrtot</I> - -also accepts format values -<B>'r'</B> - -(signifying a text form suitable for DNS reverse lookups, -e.g. -<B>4.3.2.1.IN-ADDR.ARPA.</B> - -for IPv4 and -RFC 2874 format for IPv6), -and -<B>'R'</B> - -(signifying an alternate reverse-lookup form, -an error for IPv4 and RFC 1886 format for IPv6). -Reverse-lookup names always end with a ``.''. -<P> - -The text-to-binary functions return NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -The binary-to-text functions return -<B>0</B> - -for a failure, and otherwise -always return the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>ttoaddr</I> - -are: -empty input; -unknown address family; -attempt to allocate temporary storage for a very long name failed; -name lookup failed; -syntax error in dotted-decimal or colon-hex form; -dotted-decimal or colon-hex component too large. -<P> - -Fatal errors in -<I>ttosubnet</I> - -are: -no -<B>/</B> - -in -<I>src</I>; - -<I>ttoaddr</I> - -error in conversion of -<I>network</I> - -or -<I>mask</I>; - -bit-count mask too big; -mask non-contiguous. -<P> - -Fatal errors in -<I>addrtot</I> - -and -<I>subnettot</I> - -are: -unknown format. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -The interpretation of incomplete dotted-decimal addresses -(e.g. -<B>10/24</B> - -means -<B>10.0.0.0/24</B>) - -differs from that of some older conversion -functions, e.g. those of -<I><A HREF="inet.3.html">inet</A></I>(3). - -The behavior of the older functions has never been -particularly consistent or particularly useful. -<P> - -Ignoring leading zeros in dotted-decimal components and bit counts -is arguably the most useful behavior in this application, -but it might occasionally cause confusion with the historical use of leading -zeros to denote octal numbers. -<P> - -<I>Ttoaddr</I> - -does not support the mixed colon-hex-dotted-decimal -convention used to embed an IPv4 address in an IPv6 address. -<P> - -<I>Addrtot</I> - -always uses the -<B>::</B> - -abbreviation (which can appear only once in an address) for the -<I>first</I> - -sequence of multiple zeros in an IPv6 address. -One can construct addresses (unlikely ones) in which this is suboptimal. -<P> - -<I>Addrtot</I> - -<B>'r'</B> - -conversion of an IPv6 address uses lowercase hexadecimal, -not the uppercase used in RFC 2874's examples. -It takes careful reading of RFCs 2874, 2673, and 2234 to realize -that lowercase is technically legitimate here, -and there may be software which botches this -and hence would have trouble with lowercase hex. -<P> - -Possibly -<I>subnettot</I> - -ought to recognize the -<B>%default</B> - -case and generate that string as its output. -Currently it doesn't. -<P> - -It is barely possible that somebody, somewhere, -might have a legitimate use for non-contiguous subnet masks. -<P> - -<I><A HREF="Getnetbyname.3.html">Getnetbyname</A></I>(3) - -is a historical dreg. -<P> - -<I>Tnatoaddr</I> - -probably should enforce completeness of dotted-decimal addresses. -<P> - -The restriction of text-to-binary error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The text-to-binary error-reporting convention lends itself -to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = ttoaddr( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_ttoul.3.html b/doc/manpage.d/ipsec_ttoul.3.html deleted file mode 100644 index b722dcc13..000000000 --- a/doc/manpage.d/ipsec_ttoul.3.html +++ /dev/null @@ -1,310 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TTOUL</TITLE> -</HEAD><BODY> -<H1>IPSEC_TTOUL</H1> -Section: C Library Functions (3)<BR>Updated: 16 Aug 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ttoul, ultot - convert unsigned-long numbers to and from text -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *ttoul(const char *src, size_t srclen,</B> - -<BR> - -<B>int base, unsigned long *n);</B> - -<BR> - -<B>size_t ultot(unsigned long n, int format, char *dst,</B> - -<BR> - -<B>size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ttoul</I> - -converts a text-string number into a binary -<B>unsigned long</B> - -value. -<I>Ultot</I> - -does the reverse conversion, back to a text version. -<P> - -Numbers are specified in text as -decimal (e.g. -<B>123</B>), - -octal with a leading zero (e.g. -<B>012</B>, - -which has value 10), -or hexadecimal with a leading -<B>0x</B> - -(e.g. -<B>0x1f</B>, - -which has value 31) -in either upper or lower case. -<P> - -The -<I>srclen</I> - -parameter of -<I>ttoul</I> - -specifies the length of the string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>base</I> - -parameter of -<I>ttoul</I> - -can be -<B>8</B>, - -<B>10</B>, - -or -<B>16</B>, - -in which case the number supplied is assumed to be of that form -(and in the case of -<B>16</B>, - -to lack any -<B>0x</B> - -prefix). -It can also be -<B>0</B>, - -in which case the number is examined for a leading zero -or a leading -<B>0x</B> - -to determine its base. -<P> - -The -<I>dstlen</I> - -parameter of -<I>ultot</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines a constant, -<B>ULTOT_BUF</B>, - -which is the size of a buffer just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>ultot</I> - -must be one of: -<DL COMPACT><DT><DD> -<DL COMPACT> -<DT><B>'o'</B><DD> -octal conversion with leading -<B>0</B> - -<DT><B> 8</B><DD> -octal conversion with no leading -<B>0</B> - -<DT><B>'d'</B><DD> -decimal conversion -<DT><B>10</B><DD> -same as -<B>d</B> - -<DT><B>'x'</B><DD> -hexadecimal conversion, including leading -<B>0x</B> - -<DT><B>16</B><DD> -hexadecimal conversion with no leading -<B>0x</B> - -<DT><B>17</B><DD> -like -<B>16</B> - -except padded on left with -<B>0</B>s - -to eight digits (full width of a 32-bit number) -</DL> -</DL> - -<P> - -<I>Ttoul</I> - -returns NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<I>Ultot</I> - -returns -<B>0</B> - -for a failure, and otherwise -returns the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL -(it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred). -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="atol.3.html">atol</A>(3), <A HREF="strtoul.3.html">strtoul</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>ttoul</I> - -are: -empty input; -unknown -<I>base</I>; - -non-digit character found; -number too large for an -<B>unsigned long</B>. - -<P> - -Fatal errors in -<I>ultot</I> - -are: -unknown -<I>format</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -Conversion of -<B>0</B> - -with format -<B>o</B> - -yields -<B>00</B>. - -<P> - -<I>Ultot</I> - -format -<B>17</B> - -is a bit of a kludge. -<P> - -The restriction of error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The error-reporting convention lends itself to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = ttoul( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_ultoa.3.html b/doc/manpage.d/ipsec_ultoa.3.html deleted file mode 100644 index 7669dce52..000000000 --- a/doc/manpage.d/ipsec_ultoa.3.html +++ /dev/null @@ -1,266 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ATOUL</TITLE> -</HEAD><BODY> -<H1>IPSEC_ATOUL</H1> -Section: C Library Functions (3)<BR>Updated: 11 June 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec atoul, ultoa - convert unsigned-long numbers to and from ASCII -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *atoul(const char *src, size_t srclen,</B> - -<BR> - -<B>int base, unsigned long *n);</B> - -<BR> - -<B>size_t ultoa(unsigned long n, int base, char *dst,</B> - -<BR> - -<B>size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions are obsolete; see -<I><A HREF="ipsec_ttoul.3.html">ipsec_ttoul</A></I>(3) - -for their replacements. -<P> - -<I>Atoul</I> - -converts an ASCII number into a binary -<B>unsigned long</B> - -value. -<I>Ultoa</I> - -does the reverse conversion, back to an ASCII version. -<P> - -Numbers are specified in ASCII as -decimal (e.g. -<B>123</B>), - -octal with a leading zero (e.g. -<B>012</B>, - -which has value 10), -or hexadecimal with a leading -<B>0x</B> - -(e.g. -<B>0x1f</B>, - -which has value 31) -in either upper or lower case. -<P> - -The -<I>srclen</I> - -parameter of -<I>atoul</I> - -specifies the length of the ASCII string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>base</I> - -parameter of -<I>atoul</I> - -can be -<B>8</B>, - -<B>10</B>, - -or -<B>16</B>, - -in which case the number supplied is assumed to be of that form -(and in the case of -<B>16</B>, - -to lack any -<B>0x</B> - -prefix). -It can also be -<B>0</B>, - -in which case the number is examined for a leading zero -or a leading -<B>0x</B> - -to determine its base, -or -<B>13</B> - -(halfway between 10 and 16), -which has the same effect as -<B>0</B> - -except that a non-hexadecimal -number is considered decimal regardless of any leading zero. -<P> - -The -<I>dstlen</I> - -parameter of -<I>ultoa</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -<P> - -The -<I>base</I> - -parameter of -<I>ultoa</I> - -must be -<B>8</B>, - -<B>10</B>, - -or -<B>16</B>. - -<P> - -<I>Atoul</I> - -returns NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<I>Ultoa</I> - -returns the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL; -it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="atol.3.html">atol</A>(3), <A HREF="strtoul.3.html">strtoul</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>atoul</I> - -are: -empty input; -unknown -<I>base</I>; - -non-digit character found; -number too large for an -<B>unsigned long</B>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -There is no provision for reporting an invalid -<I>base</I> - -parameter given to -<I>ultoa</I>. - -<P> - -The restriction of error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The error-reporting convention lends itself to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = atoul( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_ultot.3.html b/doc/manpage.d/ipsec_ultot.3.html deleted file mode 100644 index b722dcc13..000000000 --- a/doc/manpage.d/ipsec_ultot.3.html +++ /dev/null @@ -1,310 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_TTOUL</TITLE> -</HEAD><BODY> -<H1>IPSEC_TTOUL</H1> -Section: C Library Functions (3)<BR>Updated: 16 Aug 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ttoul, ultot - convert unsigned-long numbers to and from text -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *ttoul(const char *src, size_t srclen,</B> - -<BR> - -<B>int base, unsigned long *n);</B> - -<BR> - -<B>size_t ultot(unsigned long n, int format, char *dst,</B> - -<BR> - -<B>size_t dstlen);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>Ttoul</I> - -converts a text-string number into a binary -<B>unsigned long</B> - -value. -<I>Ultot</I> - -does the reverse conversion, back to a text version. -<P> - -Numbers are specified in text as -decimal (e.g. -<B>123</B>), - -octal with a leading zero (e.g. -<B>012</B>, - -which has value 10), -or hexadecimal with a leading -<B>0x</B> - -(e.g. -<B>0x1f</B>, - -which has value 31) -in either upper or lower case. -<P> - -The -<I>srclen</I> - -parameter of -<I>ttoul</I> - -specifies the length of the string pointed to by -<I>src</I>; - -it is an error for there to be anything else -(e.g., a terminating NUL) within that length. -As a convenience for cases where an entire NUL-terminated string is -to be converted, -a -<I>srclen</I> - -value of -<B>0</B> - -is taken to mean -<B>strlen(src)</B>. - -<P> - -The -<I>base</I> - -parameter of -<I>ttoul</I> - -can be -<B>8</B>, - -<B>10</B>, - -or -<B>16</B>, - -in which case the number supplied is assumed to be of that form -(and in the case of -<B>16</B>, - -to lack any -<B>0x</B> - -prefix). -It can also be -<B>0</B>, - -in which case the number is examined for a leading zero -or a leading -<B>0x</B> - -to determine its base. -<P> - -The -<I>dstlen</I> - -parameter of -<I>ultot</I> - -specifies the size of the -<I>dst</I> - -parameter; -under no circumstances are more than -<I>dstlen</I> - -bytes written to -<I>dst</I>. - -A result which will not fit is truncated. -<I>Dstlen</I> - -can be zero, in which case -<I>dst</I> - -need not be valid and no result is written, -but the return value is unaffected; -in all other cases, the (possibly truncated) result is NUL-terminated. -The -<I>freeswan.h</I> - -header file defines a constant, -<B>ULTOT_BUF</B>, - -which is the size of a buffer just large enough for worst-case results. -<P> - -The -<I>format</I> - -parameter of -<I>ultot</I> - -must be one of: -<DL COMPACT><DT><DD> -<DL COMPACT> -<DT><B>'o'</B><DD> -octal conversion with leading -<B>0</B> - -<DT><B> 8</B><DD> -octal conversion with no leading -<B>0</B> - -<DT><B>'d'</B><DD> -decimal conversion -<DT><B>10</B><DD> -same as -<B>d</B> - -<DT><B>'x'</B><DD> -hexadecimal conversion, including leading -<B>0x</B> - -<DT><B>16</B><DD> -hexadecimal conversion with no leading -<B>0x</B> - -<DT><B>17</B><DD> -like -<B>16</B> - -except padded on left with -<B>0</B>s - -to eight digits (full width of a 32-bit number) -</DL> -</DL> - -<P> - -<I>Ttoul</I> - -returns NULL for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<I>Ultot</I> - -returns -<B>0</B> - -for a failure, and otherwise -returns the size of buffer which would -be needed to -accommodate the full conversion result, including terminating NUL -(it is the caller's responsibility to check this against the size of -the provided buffer to determine whether truncation has occurred). -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="atol.3.html">atol</A>(3), <A HREF="strtoul.3.html">strtoul</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in -<I>ttoul</I> - -are: -empty input; -unknown -<I>base</I>; - -non-digit character found; -number too large for an -<B>unsigned long</B>. - -<P> - -Fatal errors in -<I>ultot</I> - -are: -unknown -<I>format</I>. - -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<A NAME="lbAH"> </A> -<H2>BUGS</H2> - -Conversion of -<B>0</B> - -with format -<B>o</B> - -yields -<B>00</B>. - -<P> - -<I>Ultot</I> - -format -<B>17</B> - -is a bit of a kludge. -<P> - -The restriction of error reports to literal strings -(so that callers don't need to worry about freeing them or copying them) -does limit the precision of error reporting. -<P> - -The error-reporting convention lends itself to slightly obscure code, -because many readers will not think of NULL as signifying success. -A good way to make it clearer is to write something like: -<P> - -<DL COMPACT><DT><DD> -<PRE> -<B>const char *error;</B> - -<B>error = ttoul( /* ... */ );</B> -<B>if (error != NULL) {</B> -<B> /* something went wrong */</B> -</PRE> - -</DL> - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -<DT><A HREF="#lbAH">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_unspecaddr.3.html b/doc/manpage.d/ipsec_unspecaddr.3.html deleted file mode 100644 index 92f69d99c..000000000 --- a/doc/manpage.d/ipsec_unspecaddr.3.html +++ /dev/null @@ -1,166 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_ANYADDR</TITLE> -</HEAD><BODY> -<H1>IPSEC_ANYADDR</H1> -Section: C Library Functions (3)<BR>Updated: 8 Sept 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec anyaddr - get "any" address -<BR> - -ipsec isanyaddr - test address for equality to "any" address -<BR> - -ipsec unspecaddr - get "unspecified" address -<BR> - -ipsec isunspecaddr - test address for equality to "unspecified" address -<BR> - -ipsec loopbackaddr - get loopback address -<BR> - -ipsec isloopbackaddr - test address for equality to loopback address -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *anyaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isanyaddr(const ip_address *src);</B> - -<BR> - -<B>const char *unspecaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isunspecaddr(const ip_address *src);</B> - -<BR> - -<B>const char *loopbackaddr(int af, ip_address *dst);</B> - -<BR> - -<B>int isloopbackaddr(const ip_address *src);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions fill in, and test for, special values of the -<I>ip_address</I> - -type. -<P> - -<I>Anyaddr</I> - -fills in the destination -<I>*dst</I> - -with the ``any'' address of address family -<I>af</I> - -(normally -<B>AF_INET</B> - -or -<B>AF_INET6</B>). - -The IPv4 ``any'' address is the one embodied in the old -<B>INADDR_ANY</B> - -macro. -<P> - -<I>Isanyaddr</I> - -returns -<B>1</B> - -if the -<I>src</I> - -address equals the ``any'' address, -and -<B>0</B> - -otherwise. -<P> - -Similarly, -<I>unspecaddr</I> - -supplies, and -<I>isunspecaddr</I> - -tests for, -the ``unspecified'' address, -which may be the same as the ``any'' address. -<P> - -Similarly, -<I>loopbackaddr</I> - -supplies, and -<I>islookbackaddr</I> - -tests for, -the loopback address. -<P> - -<I>Anyaddr</I>, - -<I>unspecaddr</I>, - -and -<I>loopbackaddr</I> - -return -<B>NULL</B> - -for success and -a pointer to a string-literal error message for failure; -see DIAGNOSTICS. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="inet.3.html">inet</A>(3), <A HREF="ipsec_addrtot.3.html">ipsec_addrtot</A>(3), <A HREF="ipsec_sameaddr.3.html">ipsec_sameaddr</A>(3) -<A NAME="lbAF"> </A> -<H2>DIAGNOSTICS</H2> - -Fatal errors in the address-supplying functions are: -unknown address family. -<A NAME="lbAG"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">DIAGNOSTICS</A><DD> -<DT><A HREF="#lbAG">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_verify.8.html b/doc/manpage.d/ipsec_verify.8.html deleted file mode 100644 index 09d04894b..000000000 --- a/doc/manpage.d/ipsec_verify.8.html +++ /dev/null @@ -1,107 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_VERIFY</TITLE> -</HEAD><BODY> -<H1>IPSEC_VERIFY</H1> -Section: Maintenance Commands (8)<BR>Updated: 8 June 2002<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec verify - see if FreeSWAN has been installed correctly -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>ipsec</B> - -<B>verify</B> - -[ -<B>--host</B> - - name ] -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<P> - -Invoked without argument, -<I>verify </I> - -examines the local system for a number of common system faults: -IPsec not in path, no secrets file generated, -pluto not running, and IPsec support not present in kernel -(or IPsec module not loaded). -If two or more interfaces are found, it performs checks relevant on an -IPsec gateway: whether IP forwarding is allowed, and if so, -whether MASQ or NAT rules are in play. -<P> - -In addition, -<I>verify </I> - -performs checks relevant to Opportunistic Encryption. -It looks in forward DNS for a TXT record for the system's hostname, and -in reverse DNS for a TXT record for the system's IP addresses. -It checks whether the system has a public IP. -<P> - -The -<B>--host</B> - -option causes -<B>verify</B> - -to look for a TXT record for -<I>name</I> - -in forward and reverse DNS. -<A NAME="lbAE"> </A> -<H2>FILES</H2> - -<PRE> -/proc/net/ipsec_eroute -/etc/ipsec.secrets -</PRE> - -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Michael Richardson. -<A NAME="lbAG"> </A> -<H2>BUGS</H2> - -<I>Verify </I> - -does not check for -<B>ipchains</B> - -masquerading. -<P> - -<I>Verify</I> - -does not look for TXT records for Opportunistic clients behind the system. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">FILES</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -<DT><A HREF="#lbAG">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_version.3.html b/doc/manpage.d/ipsec_version.3.html deleted file mode 100644 index bcad75a46..000000000 --- a/doc/manpage.d/ipsec_version.3.html +++ /dev/null @@ -1,94 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_VERSION</TITLE> -</HEAD><BODY> -<H1>IPSEC_VERSION</H1> -Section: C Library Functions (3)<BR>Updated: 21 Nov 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ipsec_version_code - get IPsec version code -<BR> - -ipsec ipsec_version_string - get full IPsec version string -<BR> - -ipsec ipsec_copyright_notice - get IPsec copyright notice -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *ipsec_version_code(void);</B> - -<BR> - -<B>const char *ipsec_version_string(void);</B> - -<BR> - -<B>const char **ipsec_copyright_notice(void);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions provide information on version numbering and copyright -of the Linux FreeS/WAN IPsec implementation. -<P> - -<I>Ipsec_version_code</I> - -returns a pointer to a string constant -containing the current IPsec version code, -such as ``1.92'' or ``snap2001Nov19b''. -<P> - -<I>Ipsec_version_string</I> - -returns a pointer to a string constant giving a full version identification, -consisting of the version code preceded by a prefix identifying the software, -e.g. ``Linux FreeS/WAN 1.92''. -<P> - -<I>Ipsec_copyright_notice</I> - -returns a pointer to a vector of pointers, -terminated by a -<B>NULL</B>, - -which is the text of a suitable copyright notice. -Each pointer points to a string constant (possibly empty) which is one line -of the somewhat-verbose copyright notice. -The strings are NUL-terminated and do not contain a newline; -supplying suitable line termination for the output device is -the caller's responsibility. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_version.5.html b/doc/manpage.d/ipsec_version.5.html deleted file mode 100644 index 89bee0f97..000000000 --- a/doc/manpage.d/ipsec_version.5.html +++ /dev/null @@ -1,103 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_VERSION</TITLE> -</HEAD><BODY> -<H1>IPSEC_VERSION</H1> -Section: File Formats (5)<BR>Updated: 29 Jun 2000<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec_version - lists KLIPS version information -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>cat</B> - -<B>/proc/net/ipsec_version</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<I>/proc/net/ipsec_version</I> - -is a read-only file which lists the currently running KLIPS version -information. -<P> - -<A NAME="lbAE"> </A> -<H2>EXAMPLES</H2> - -<DL COMPACT> -<DT><B>FreeS/WAN version: 1.4</B> - -<DD> -</DL> -<P> - -shows that the currently loaded -<B>KLIPS</B> - -is from -<B>FreeS/WAN 1.4.</B> - -<P> - -<A NAME="lbAF"> </A> -<H2>FILES</H2> - -/proc/net/ipsec_version -<A NAME="lbAG"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8), <A HREF="ipsec_manual.8.html">ipsec_manual</A>(8), <A HREF="ipsec_eroute.5.html">ipsec_eroute</A>(5), <A HREF="ipsec_spi.5.html">ipsec_spi</A>(5), -<A HREF="ipsec_spigrp.5.html">ipsec_spigrp</A>(5), <A HREF="ipsec_klipsdebug.5.html">ipsec_klipsdebug</A>(5), <A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A>(8), <A HREF="ipsec_pf_key.5.html">ipsec_pf_key</A>(5) -<A NAME="lbAH"> </A> -<H2>HISTORY</H2> - -Written for the Linux FreeS/WAN project -<<A HREF="http://www.freeswan.org/">http://www.freeswan.org/</A>> -by Richard Guy Briggs. - - - - - - - - - - - - - - - - - - - -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">EXAMPLES</A><DD> -<DT><A HREF="#lbAF">FILES</A><DD> -<DT><A HREF="#lbAG">SEE ALSO</A><DD> -<DT><A HREF="#lbAH">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_version_code.3.html b/doc/manpage.d/ipsec_version_code.3.html deleted file mode 100644 index bcad75a46..000000000 --- a/doc/manpage.d/ipsec_version_code.3.html +++ /dev/null @@ -1,94 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_VERSION</TITLE> -</HEAD><BODY> -<H1>IPSEC_VERSION</H1> -Section: C Library Functions (3)<BR>Updated: 21 Nov 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ipsec_version_code - get IPsec version code -<BR> - -ipsec ipsec_version_string - get full IPsec version string -<BR> - -ipsec ipsec_copyright_notice - get IPsec copyright notice -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *ipsec_version_code(void);</B> - -<BR> - -<B>const char *ipsec_version_string(void);</B> - -<BR> - -<B>const char **ipsec_copyright_notice(void);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions provide information on version numbering and copyright -of the Linux FreeS/WAN IPsec implementation. -<P> - -<I>Ipsec_version_code</I> - -returns a pointer to a string constant -containing the current IPsec version code, -such as ``1.92'' or ``snap2001Nov19b''. -<P> - -<I>Ipsec_version_string</I> - -returns a pointer to a string constant giving a full version identification, -consisting of the version code preceded by a prefix identifying the software, -e.g. ``Linux FreeS/WAN 1.92''. -<P> - -<I>Ipsec_copyright_notice</I> - -returns a pointer to a vector of pointers, -terminated by a -<B>NULL</B>, - -which is the text of a suitable copyright notice. -Each pointer points to a string constant (possibly empty) which is one line -of the somewhat-verbose copyright notice. -The strings are NUL-terminated and do not contain a newline; -supplying suitable line termination for the output device is -the caller's responsibility. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_version_string.3.html b/doc/manpage.d/ipsec_version_string.3.html deleted file mode 100644 index bcad75a46..000000000 --- a/doc/manpage.d/ipsec_version_string.3.html +++ /dev/null @@ -1,94 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_VERSION</TITLE> -</HEAD><BODY> -<H1>IPSEC_VERSION</H1> -Section: C Library Functions (3)<BR>Updated: 21 Nov 2001<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec ipsec_version_code - get IPsec version code -<BR> - -ipsec ipsec_version_string - get full IPsec version string -<BR> - -ipsec ipsec_copyright_notice - get IPsec copyright notice -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - -<B>#include <<A HREF="file:/usr/include/freeswan.h">freeswan.h</A>></B> - -<P> -<B>const char *ipsec_version_code(void);</B> - -<BR> - -<B>const char *ipsec_version_string(void);</B> - -<BR> - -<B>const char **ipsec_copyright_notice(void);</B> - -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -These functions provide information on version numbering and copyright -of the Linux FreeS/WAN IPsec implementation. -<P> - -<I>Ipsec_version_code</I> - -returns a pointer to a string constant -containing the current IPsec version code, -such as ``1.92'' or ``snap2001Nov19b''. -<P> - -<I>Ipsec_version_string</I> - -returns a pointer to a string constant giving a full version identification, -consisting of the version code preceded by a prefix identifying the software, -e.g. ``Linux FreeS/WAN 1.92''. -<P> - -<I>Ipsec_copyright_notice</I> - -returns a pointer to a vector of pointers, -terminated by a -<B>NULL</B>, - -which is the text of a suitable copyright notice. -Each pointer points to a string constant (possibly empty) which is one line -of the somewhat-verbose copyright notice. -The strings are NUL-terminated and do not contain a newline; -supplying suitable line termination for the output device is -the caller's responsibility. -<A NAME="lbAE"> </A> -<H2>SEE ALSO</H2> - -<A HREF="ipsec.8.html">ipsec</A>(8) -<A NAME="lbAF"> </A> -<H2>HISTORY</H2> - -Written for the FreeS/WAN project by Henry Spencer. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DT><A HREF="#lbAE">SEE ALSO</A><DD> -<DT><A HREF="#lbAF">HISTORY</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/manpage.d/ipsec_whack.8.html b/doc/manpage.d/ipsec_whack.8.html deleted file mode 100644 index 2e2ce4c2f..000000000 --- a/doc/manpage.d/ipsec_whack.8.html +++ /dev/null @@ -1,1824 +0,0 @@ -Content-type: text/html - -<HTML><HEAD><TITLE>Manpage of IPSEC_PLUTO</TITLE> -</HEAD><BODY> -<H1>IPSEC_PLUTO</H1> -Section: Maintenance Commands (8)<BR>Updated: 28 March 1999<BR><A HREF="#index">Index</A> -<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR> - -<A NAME="lbAB"> </A> -<H2>NAME</H2> - -ipsec pluto - IPsec IKE keying daemon -<BR> - -ipsec whack - control interface for IPSEC keying daemon -<A NAME="lbAC"> </A> -<H2>SYNOPSIS</H2> - - - -<DL COMPACT> -<DT> -<B> -<DD>ipsec pluto -[--help] -[--version] -[--optionsfrom </B><I>filename</I>] -[--nofork] -[--stderrlog] -[--noklips] -[--uniqueids] -[<B>--interface</B> <I>interfacename</I>] -[--ikeport <I>portnumber</I>] -[--ctlbase <I>path</I>] -[--secretsfile <I>secrets-file</I>] -[--adns <I>pathname</I>] -[--lwdnsq <I>pathname</I>] -[--perpeerlog] -[--perpeerlogbase <I>dirname</I>] -[--debug-none] -[--debug-all] -[--debug-raw] -[--debug-crypt] -[--debug-parsing] -[--debug-emitting] -[--debug-control] -[--debug-lifecycle] -[--debug-klips] -[--debug-dns] -[--debug-oppo] -[--debug-private] -<DT> -<B> -<DD>ipsec whack -[--help] -[--version] -<DT> - -<DD>ipsec whack ---name </B><I>connection-name</I> -<BR> - -[--id <I>id</I>] [--host <I>ip-address</I>] -[--ikeport <I>port-number</I>] -[--nexthop <I>ip-address</I>] -[--client <I>subnet</I>] -[--dnskeyondemand] -[--updown <I>updown</I>] -<BR> - ---to -<BR> - -[--id <I>id</I>] -[--host <I>ip-address</I>] -[--ikeport <I>port-number</I>] -[--nexthop <I>ip-address</I>] -[--client <I>subnet</I>] -[--dnskeyondemand] -[--updown <I>updown</I>] -<BR> - -[--psk] -[--rsasig] -[--encrypt] -[--authenticate] -[--compress] -[--tunnel] -[--pfs] -[--disablearrivalcheck] -[--ipv4] -[--ipv6] -[--tunnelipv4] -[--tunnelipv6] -[--ikelifetime <I>seconds</I>] -[--ipseclifetime <I>seconds</I>] -[--rekeymargin <I>seconds</I>] -[--rekeyfuzz <I>percentage</I>] -[--keyingtries <I>count</I>] -[--dontrekey] -[--delete] -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---keyid </B><I>id</I> -[--addkey] -[--pubkeyrsa <I>key</I>] -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---myid </B><I>id</I> -<DT> -<B> -<DD>ipsec whack ---listen|--unlisten -[--ctlbase </B><I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---route|--unroute ---name </B><I>connection-name</I> -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---initiate|--terminate ---name </B><I>connection-name</I> -[--asynchronous] -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack -[--tunnelipv4] -[--tunnelipv6] ---oppohere </B><I>ip-address</I> ---oppothere <I>ip-address</I> -<DT> -<B> -<DD>ipsec whack ---delete ---name </B><I>connection-name</I> -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---deletestate </B><I>state-number</I> -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack -[--name </B><I>connection-name</I>] -[--debug-none] -[--debug-all] -[--debug-raw] -[--debug-crypt] -[--debug-parsing] -[--debug-emitting] -[--debug-control] -[--debug-lifecycle] -[--debug-klips] -[--debug-dns] -[--debug-oppo] -[--debug-private] -[--ctlbase <I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---status -[--ctlbase </B><I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] -<DT> -<B> -<DD>ipsec whack ---shutdown -[--ctlbase </B><I>path</I>] -[--optionsfrom <I>filename</I>] -[--label <I>string</I>] - - - -</DL> -<A NAME="lbAD"> </A> -<H2>DESCRIPTION</H2> - -<B>pluto</B> - -is an IKE (``IPsec Key Exchange'') daemon. -<B>whack</B> - -is an auxiliary program to allow requests to be made to a running -<B>pluto</B>. - -<P> - -<B>pluto</B> - -is used to automatically build shared ``security associations'' on a -system that has IPsec, the secure IP protocol. -In other words, -<B>pluto</B> - -can eliminate much of the work of manual keying. -The actual -secure transmission of packets is the responsibility of other parts of -the system (see -<B>KLIPS</B>, - -the companion implementation of IPsec). -<I><A HREF="ipsec_auto.8.html">ipsec_auto</A></I>(8) provides a more convenient interface to -<B>pluto</B> and <B>whack</B>. -<A NAME="lbAE"> </A> -<H3>IKE's Job</H3> - -<P> - -A <I>Security Association</I> (<I>SA</I>) is an agreement between two network nodes on -how to process certain traffic between them. This processing involves -encapsulation, authentication, encryption, or compression. -<P> - -IKE can be deployed on a network node to negotiate Security -Associations for that node. These IKE implementations can only -negotiate with other IKE implementations, so IKE must be on each node -that is to be an endpoint of an IKE-negotiated Security Association. -No other nodes need to be running IKE. -<P> - -An IKE instance (i.e. an IKE implementation on a particular network -node) communicates with another IKE instance using UDP IP packets, so -there must be a route between the nodes in each direction. -<P> - -The negotiation of Security Associations requires a number of choices -that involve tradeoffs between security, convenience, trust, and -efficiency. These are policy issues and are normally specified to the -IKE instance by the system administrator. -<P> - -IKE deals with two kinds of Security Associations. The first part of -a negotiation between IKE instances is to build an ISAKMP SA. An -ISAKMP SA is used to protect communication between the two IKEs. -IPsec SAs can then be built by the IKEs - these are used to carry -protected IP traffic between the systems. -<P> - -The negotiation of the ISAKMP SA is known as Phase 1. In theory, -Phase 1 can be accomplished by a couple of different exchange types, -but we only implement one called Main Mode (we don't implement -Aggressive Mode). -<P> - -Any negotiation under the protection of an ISAKMP SA, including the -negotiation of IPsec SAs, is part of Phase 2. The exchange type -that we use to negotiate an IPsec SA is called Quick Mode. -<P> - -IKE instances must be able to authenticate each other as part of their -negotiation of an ISAKMP SA. This can be done by several mechanisms -described in the draft standards. -<P> - -IKE negotiation can be initiated by any instance with any other. If -both can find an agreeable set of characteristics for a Security -Association, and both recognize each others authenticity, they can set -up a Security Association. The standards do not specify what causes -an IKE instance to initiate a negotiation. -<P> - -In summary, an IKE instance is prepared to automate the management of -Security Associations in an IPsec environment, but a number of issues -are considered policy and are left in the system administrator's hands. -<A NAME="lbAF"> </A> -<H3>Pluto</H3> - -<P> - -<B>pluto</B> is an implementation of IKE. It runs as a daemon on a network -node. Currently, this network node must be a LINUX system running the -<B>KLIPS</B> implementation of IPsec. -<P> - -<B>pluto</B> only implements a subset of IKE. This is enough for it to -interoperate with other instances of <B>pluto</B>, and many other IKE -implementations. We are working on implementing more of IKE. -<P> - -The policy for acceptable characteristics for Security Associations is -mostly hardwired into the code of <B>pluto</B> (spdb.c). Eventually -this will be moved into a security policy database with reasonable -expressive power and more convenience. -<P> - -<B>pluto</B> uses shared secrets or RSA signatures to authenticate -peers with whom it is negotiating. -<P> - -<B>pluto</B> initiates negotiation of a Security Association when it is -manually prodded: the program <B>whack</B> is run to trigger this. -It will also initiate a negotiation when <B>KLIPS</B> traps an outbound packet -for Opportunistic Encryption. -<P> - -<B>pluto</B> implements ISAKMP SAs itself. After it has negotiated the -characteristics of an IPsec SA, it directs <B>KLIPS</B> to implement it. -It also invokes a script to adjust any firewall and issue <I><A HREF="route.8.html">route</A></I>(8) -commands to direct IP packets through <B>KLIPS</B>. -<P> - -When <B>pluto</B> shuts down, it closes all Security Associations. -<A NAME="lbAG"> </A> -<H3>Before Running Pluto</H3> - -<P> - -<B>pluto</B> runs as a daemon with userid root. Before running it, a few -things must be set up. -<P> - -<B>pluto</B> requires <B>KLIPS</B>, the FreeS/WAN implementation of IPsec. -All of the components of <B>KLIPS</B> and <B>pluto</B> should be installed. -<P> - -<B>pluto</B> supports multiple public networks (that is, networks -that are considered insecure and thus need to have their traffic -encrypted or authenticated). It discovers the -public interfaces to use by looking at all interfaces that are -configured (the <B>--interface</B> option can be used to limit -the interfaces considered). -It does this only when <B>whack</B> tells it to --listen, -so the interfaces must be configured by then. Each interface with a name of the form -<B>ipsec</B>[<B>0</B>-<B>9</B>] is taken as a <B>KLIPS</B> virtual public interface. -Another network interface with the same IP address (there should be only -one) is taken as the corresponding real public -interface. <I><A HREF="ifconfig.8.html">ifconfig</A></I>(8) with the <B>-a</B> flag will show -the name and status of each network interface. -<P> - -<B>pluto</B> requires a database of preshared secrets and RSA private keys. -This is described in the -<I><A HREF="ipsec.secrets.5.html">ipsec.secrets</A></I>(5). - -<B>pluto</B> is told of RSA public keys via <B>whack</B> commands. -If the connection is Opportunistic, and no RSA public key is known, -<B>pluto</B> will attempt to fetch RSA keys using the Domain Name System. -<A NAME="lbAH"> </A> -<H3>Setting up <B>KLIPS</B> for <B>pluto</B></H3> - -<P> - -The most basic network topology that <B>pluto</B> supports has two security -gateways negotiating on behalf of client subnets. The diagram of RGB's -testbed is a good example (see <I>klips/doc/rgb_setup.txt</I>). -<P> - -The file <I>INSTALL</I> in the base directory of this distribution -explains how to start setting up the whole system, including <B>KLIPS</B>. -<P> - -Make sure that the security gateways have routes to each other. This -is usually covered by the default route, but may require issuing -<I><A HREF="route.8.html">route</A></I>(8) - -commands. The route must go through a particular IP -interface (we will assume it is <I>eth0</I>, but it need not be). The -interface that connects the security gateway to its client must be a -different one. -<P> - -It is necessary to issue a -<I><A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A></I>(8) - -command on each gateway. The required command is: -<P> - ipsec tncfg --attach --virtual ipsec0 --physical eth0 -<P> -A command to set up the ipsec0 virtual interface will also need to be -run. It will have the same parameters as the command used to set up -the physical interface to which it has just been connected using -<I><A HREF="ipsec_tncfg.8.html">ipsec_tncfg</A></I>(8). - -<A NAME="lbAI"> </A> -<H3>ipsec.secrets file</H3> - -<P> - -A <B>pluto</B> daemon and another IKE daemon (for example, another instance -of <B>pluto</B>) must convince each other that they are who they are supposed -to be before any negotiation can succeed. This authentication is -accomplished by using either secrets that have been shared beforehand -(manually) or by using RSA signatures. There are other techniques, -but they have not been implemented in <B>pluto</B>. -<P> - -The file <I>/etc/ipsec.secrets</I> is used to keep preshared secret keys -and RSA private keys for -authentication with other IKE daemons. For debugging, there is an -argument to the <B>pluto</B> command to use a different file. -This file is described in -<I><A HREF="ipsec.secrets.5.html">ipsec.secrets</A></I>(5). - -<A NAME="lbAJ"> </A> -<H3>Running Pluto</H3> - -<P> - -To fire up the daemon, just type <B>pluto</B> (be sure to be running as -the superuser). -The default IKE port number is 500, the UDP port assigned by IANA for IKE Daemons. -<B>pluto</B> must be run by the superuser to be able to use the UDP 500 port. -<P> - -<B>pluto</B> attempts to create a lockfile with the name -<I>/var/run/pluto.pid</I>. If the lockfile cannot be created, -<B>pluto</B> exits - this prevents multiple <B>pluto</B>s from -competing Any ``leftover'' lockfile must be removed before -<B>pluto</B> will run. <B>pluto</B> writes its pid into this file so -that scripts can find it. This lock will not function properly if it -is on an NFS volume (but sharing locks on multiple machines doesn't -make sense anyway). -<P> - -<B>pluto</B> then forks and the parent exits. This is the conventional -``daemon fork''. It can make debugging awkward, so there is an option -to suppress this fork. -<P> - -All logging, including diagnostics, is sent to -<I><A HREF="syslog.3.html">syslog</A></I>(3) - -with facility=authpriv; -it decides where to put these messages (possibly in /var/log/secure). -Since this too can make debugging awkward, there is an option to -steer logging to stderr. -<P> - -If the <B>--perpeerlog</B> option is given, then pluto will open -a log file per connection. By default, this is in /var/log/pluto/peer, -in a subdirectory formed by turning all dot (.) [IPv4} or colon (:) -[IPv6] into slashes (/). -<P> - -The base directory can be changed with the <B>--perpeerlogbase</B>. -<P> - -Once <B>pluto</B> is started, it waits for requests from <B>whack</B>. -<A NAME="lbAK"> </A> -<H3>Pluto's Internal State</H3> - -<P> - -To understand how to use <B>pluto</B>, it is helpful to understand a little -about its internal state. Furthermore, the terminology is needed to decipher -some of the diagnostic messages. -<P> - -The <I>(potential) connection</I> database describes attributes of a -connection. These include the IP addresses of the hosts and client -subnets and the security characteristics desired. <B>pluto</B> -requires this information (simply called a connection) before it can -respond to a request to build an SA. Each connection is given a name -when it is created, and all references are made using this name. -<P> - -During the IKE exchange to build an SA, the information about the -negotiation is represented in a <I>state object</I>. Each state object -reflects how far the negotiation has reached. Once the negotiation is -complete and the SA established, the state object remains to represent -the SA. When the SA is terminated, the state object is discarded. -Each State object is given a serial number and this is used to refer -to the state objects in logged messages. -<P> - -Each state object corresponds to a connection and can be thought of -as an instantiation of that connection. -At any particular time, there may be any number of state objects -corresponding to a particular connection. -Often there is one representing an ISAKMP SA and another representing -an IPsec SA. -<P> - -<B>KLIPS</B> hooks into the routing code in a LINUX kernel. -Traffic to be processed by an IPsec SA must be directed through -<B>KLIPS</B> by routing commands. Furthermore, the processing to be -done is specified by <I>ipsec <A HREF="eroute.8.html">eroute</A>(8)</I> commands. -<B>pluto</B> takes the responsibility of managing both of these special -kinds of routes. -<P> - -Each connection may be routed, and must be while it has an IPsec SA. -The connection specifies the characteristics of the route: the -interface on this machine, the ``gateway'' (the nexthop), -and the peer's client subnet. Two -connections may not be simultaneously routed if they are for the same -peer's client subnet but use different interfaces or gateways -(<B>pluto</B>'s logic does not reflect any advanced routing capabilities). -<P> - -Each eroute is associated with the state object for an IPsec SA -because it has the particular characteristics of the SA. -Two eroutes conflict if they specify the identical local -and remote clients (unlike for routes, the local clients are -taken into account). -<P> - -When <B>pluto</B> needs to install a route for a connection, -it must make sure that no conflicting route is in use. If another -connection has a conflicting route, that route will be taken down, as long -as there is no IPsec SA instantiating that connection. -If there is such an IPsec SA, the attempt to install a route will fail. -<P> - -There is an exception. If <B>pluto</B>, as Responder, needs to install -a route to a fixed client subnet for a connection, and there is -already a conflicting route, then the SAs using the route are deleted -to make room for the new SAs. The rationale is that the new -connection is probably more current. The need for this usually is a -product of Road Warrior connections (these are explained later; they -cannot be used to initiate). -<P> - -When <B>pluto</B> needs to install an eroute for an IPsec SA (for a -state object), first the state object's connection must be routed (if -this cannot be done, the eroute and SA will not be installed). -If a conflicting eroute is already in place for another connection, -the eroute and SA will not be installed (but note that the routing -exception mentioned above may have already deleted potentially conflicting SAs). -If another IPsec -SA for the same connection already has an eroute, all its outgoing traffic -is taken over by the new eroute. The incoming traffic will still be -processed. This characteristic is exploited during rekeying. -<P> - -All of these routing characteristics are expected change when -<B>KLIPS</B> is modified to use the firewall hooks in the LINUX 2.4.x -kernel. -<A NAME="lbAL"> </A> -<H3>Using Whack</H3> - -<P> - -<B>whack</B> is used to command a running <B>pluto</B>. -<B>whack</B> uses a UNIX domain socket to speak to <B>pluto</B> -(by default, <I>/var/pluto.ctl</I>). -<P> - -<B>whack</B> has an intricate argument syntax. -This syntax allows many different functions to be specified. -The help form shows the usage or version information. -The connection form gives <B>pluto</B> a description of a potential connection. -The public key form informs <B>pluto</B> of the RSA public key for a potential peer. -The delete form deletes a connection description and all SAs corresponding -to it. -The listen form tells <B>pluto</B> to start or stop listening on the public interfaces -for IKE requests from peers. -The route form tells <B>pluto</B> to set up routing for a connection; -the unroute form undoes this. -The initiate form tells <B>pluto</B> to negotiate an SA corresponding to a connection. -The terminate form tells <B>pluto</B> to remove all SAs corresponding to a connection, -including those being negotiated. -The status form displays the <B>pluto</B>'s internal state. -The debug form tells <B>pluto</B> to change the selection of debugging output -``on the fly''. The shutdown form tells -<B>pluto</B> to shut down, deleting all SAs. -<P> - -Most options are specific to one of the forms, and will be described -with that form. There are three options that apply to all forms. -<DL COMPACT> -<DT><B>--ctlbase</B> <I>path</I><DD> -<I>path</I>.ctl is used as the UNIX domain socket for talking -to <B>pluto</B>. -This option facilitates debugging. -<DT><B>--optionsfrom</B> <I>filename</I><DD> -adds the contents of the file to the argument list. -<DT><B>--label</B> <I>string</I><DD> -adds the string to all error messages generated by <B>whack</B>. -</DL> -<P> - -The help form of <B>whack</B> is self-explanatory. -<DL COMPACT> -<DT><B>--help</B><DD> -display the usage message. -<DT><B>--version</B><DD> -display the version of <B>whack</B>. -</DL> -<P> - -The connection form describes a potential connection to <B>pluto</B>. -<B>pluto</B> needs to know what connections can and should be negotiated. -When <B>pluto</B> is the initiator, it needs to know what to propose. -When <B>pluto</B> is the responder, it needs to know enough to decide whether -is is willing to set up the proposed connection. -<P> - -The description of a potential connection can specify a large number -of details. Each connection has a unique name. This name will appear -in a updown shell command, so it should not contain punctuation -that would make the command ill-formed. -<DL COMPACT> -<DT><B>--name</B> <I>connection-name</I><DD> -</DL> -<P> - -The topology of -a connection is symmetric, so to save space here is half a picture: -<P> - client_subnet<-->host:ikeport<-->nexthop<--- -<P> -A similar trick is used in the flags. The same flag names are used for -both ends. Those before the <B>--to</B> flag describe the left side -and those afterwards describe the right side. When <B>pluto</B> attempts -to use the connection, it decides whether it is the left side or the right -side of the connection, based on the IP numbers of its interfaces. -<DL COMPACT> -<DT><B>--id</B> <I>id</I><DD> -the identity of the end. Currently, this can be an IP address (specified -as dotted quad or as a Fully Qualified Domain Name, which will be resolved -immediately) or as a Fully Qualified Domain Name itself (prefixed by ``@'' -to signify that it should not be resolved), or as <A HREF="mailto:user@FQDN">user@FQDN</A>, or as the -magic value <B>%myid</B>. -<B>Pluto</B> only authenticates the identity, and does not use it for -addressing, so, for example, an IP address need not be the one to which -packets are to be sent. If the option is absent, the -identity defaults to the IP address specified by <B>--host</B>. -<B>%myid</B> allows the identity to be separately specified (by the <B>pluto</B> or <B>whack</B> option <B>--myid</B> -or by the <B><A HREF="ipsec.conf.5.html">ipsec.conf</A></B>(5) <B>config setup</B> parameter myid). -Otherwise, <B>pluto</B> tries to guess what <B>%myid</B> should stand for: -the IP address of <B>%defaultroute</B>, if it is supported by a suitable TXT record in the reverse domain for that IP address, -or the system's hostname, if it is supported by a suitable TXT record in its forward domain. - -<DT><B>--host</B> <I>ip-address</I><DD> -<DT><B>--host</B> <B>%any</B><DD> -<DT><B>--host</B> <B>%opportunistic</B><DD> -the IP address of the end (generally the public interface). -If <B>pluto</B> is to act as a responder -for IKE negotiations initiated from unknown IP addresses (the -``Road Warrior'' case), the -IP address should be specified as <B>%any</B> (currently, -the obsolete notation <B>0.0.0.0</B> is also accepted for this). -If <B>pluto</B> is to opportunistically initiate the connection, -use <B>%opportunistic</B> -<DT><B>--ikeport</B> <I>port-number</I><DD> -the UDP port that IKE listens to on that host. The default is 500. -(<B>pluto</B> on this machine uses the port specified by its own command -line argument, so this only affects where <B>pluto</B> sends messages.) -<DT><B>--nexthop</B> <I>ip-address</I><DD> -where to route packets for the peer's client (presumably for the peer too, -but it will not be used for this). -When <B>pluto</B> installs an IPsec SA, it issues a route command. -It uses the nexthop as the gateway. -The default is the peer's IP address (this can be explicitly written as -<B>%direct</B>; the obsolete notation <B>0.0.0.0</B> is accepted). -This option is necessary if <B>pluto</B>'s host's interface used for sending -packets to the peer is neither point-to-point nor directly connected to the -peer. -<DT><B>--client</B> <I>subnet</I><DD> -the subnet for which the IPsec traffic will be destined. If not specified, -the host will be the client. -The subnet can be specified in any of the forms supported by <I><A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A></I>(3). -The general form is <I>address</I>/<I>mask</I>. The <I>address</I> can be either -a domain name or four decimal numbers (specifying octets) separated by dots. -The most convenient form of the <I>mask</I> is a decimal integer, specifying -the number of leading one bits in the mask. So, for example, 10.0.0.0/8 -would specify the class A network ``Net 10''. -<DT><B>--dnskeyondemand]</B><DD> -specifies that when an RSA public key is needed to authenticate this -host, and it isn't already known, fetch it from DNS. -<DT><B>--updown</B> <I>updown</I><DD> -specifies an external shell command to be run whenever <B>pluto</B> -brings up or down a connection. -The script is used to build a shell command, so it may contain positional -parameters, but ought not to have punctuation that would cause the -resulting command to be ill-formed. -The default is <I>ipsec _updown</I>. -<DT><B>--to</B><DD> -separates the specification of the left and right ends of the connection. -</DL> -<P> - -The potential connection description also specifies characteristics of -rekeying and security. -<DL COMPACT> -<DT><B>--psk</B><DD> -Propose and allow preshared secret authentication for IKE peers. This authentication -requires that each side use the same secret. May be combined with <B>--rsasig</B>; -at least one must be specified. -<DT><B>--rsasig</B><DD> -Propose and allow RSA signatures for authentication of IKE peers. This authentication -requires that each side have have a private key of its own and know the -public key of its peer. May be combined with <B>--psk</B>; -at least one must be specified. -<DT><B>--encrypt</B><DD> -All proposed or accepted IPsec SAs will include non-null ESP. -The actual choices of transforms are wired into <B>pluto</B>. -<DT><B>--authenticate</B><DD> -All proposed IPsec SAs will include AH. -All accepted IPsec SAs will include AH or ESP with authentication. -The actual choices of transforms are wired into <B>pluto</B>. -Note that this has nothing to do with IKE authentication. -<DT><B>--compress</B><DD> -All proposed IPsec SAs will include IPCOMP (compression). -This will be ignored if KLIPS is not configured with IPCOMP support. -<DT><B>--tunnel</B><DD> -the IPsec SA should use tunneling. Implicit if the SA is for clients. -Must only be used with <B>--authenticate</B> or <B>--encrypt</B>. -<DT><B>--ipv4</B><DD> -The host addresses will be interpreted as IPv4 addresses. This is the -default. Note that for a connection, all host addresses must be of -the same Address Family (IPv4 and IPv6 use different Address Families). -<DT><B>--ipv6</B><DD> -The host addresses (including nexthop) will be interpreted as IPv6 addresses. -Note that for a connection, all host addresses must be of -the same Address Family (IPv4 and IPv6 use different Address Families). -<DT><B>--tunnelipv4</B><DD> -The client addresses will be interpreted as IPv4 addresses. The default is -to match what the host will be. This does not imply <B>--tunnel</B> so the -flag can be safely used when no tunnel is actually specified. -Note that for a connection, all tunnel addresses must be of the same -Address Family. -<DT><B>--tunnelipv6</B><DD> -The client addresses will be interpreted as IPv6 addresses. The default is -to match what the host will be. This does not imply <B>--tunnel</B> so the -flag can be safely used when no tunnel is actually specified. -Note that for a connection, all tunnel addresses must be of the same -Address Family. -<DT><B>--pfs</B><DD> -There should be Perfect Forward Secrecy - new keying material will -be generated for each IPsec SA rather than being derived from the ISAKMP -SA keying material. -Since the group to be used cannot be negotiated (a dubious feature of the -standard), <B>pluto</B> will propose the same group that was used during Phase 1. -We don't implement a stronger form of PFS which would require that the -ISAKMP SA be deleted after the IPSEC SA is negotiated. -<DT><B>--disablearrivalcheck</B><DD> -If the connection is a tunnel, allow packets arriving through the tunnel -to have any source and destination addresses. -</DL> -<P> - -If none of the <B>--encrypt</B>, <B>--authenticate</B>, <B>--compress</B>, -or <B>--pfs</B> flags is given, the initiating the connection will -only build an ISAKMP SA. For such a connection, client subnets have -no meaning and must not be specified. -<P> - -More work is needed to allow for flexible policies. Currently -policy is hardwired in the source file spdb.c. The ISAKMP SAs may use -Oakley groups MODP1024 and MODP1536; 3DES encryption; SHA1-96 -and MD5-96 authentication. The IPsec SAs may use 3DES and -MD5-96 or SHA1-96 for ESP, or just MD5-96 or SHA1-96 for AH. -IPCOMP Compression is always Deflate. -<DL COMPACT> -<DT><B>--ikelifetime</B> <I>seconds</I><DD> -how long <B>pluto</B> will propose that an ISAKMP SA be allowed to live. -The default is 3600 (one hour) and the maximum is 28800 (8 hours). -This option will not affect what is accepted. -<B>pluto</B> will reject proposals that exceed the maximum. -<DT><B>--ipseclifetime</B> <I>seconds</I><DD> -how long <B>pluto</B> will propose that an IPsec SA be allowed to live. -The default is 28800 (eight hours) and the maximum is 86400 (one day). -This option will not affect what is accepted. -<B>pluto</B> will reject proposals that exceed the maximum. -<DT><B>--rekeymargin</B> <I>seconds</I><DD> -how long before an SA's expiration should <B>pluto</B> try to negotiate -a replacement SA. This will only happen if <B>pluto</B> was the initiator. -The default is 540 (nine minutes). -<DT><B>--rekeyfuzz</B> <I>percentage</I><DD> -maximum size of random component to add to rekeymargin, expressed as -a percentage of rekeymargin. <B>pluto</B> will select a delay uniformly -distributed within this range. By default, the percentage will be 100. -If greater determinism is desired, specify 0. It may be appropriate -for the percentage to be much larger than 100. -<DT><B>--keyingtries</B> <I>count</I><DD> -how many times <B>pluto</B> should try to negotiate an SA, -either for the first time or for rekeying. -A value of 0 is interpreted as a very large number: never give up. -The default is three. -<DT><B>--dontrekey</B><DD> -A misnomer. -Only rekey a connection if we were the Initiator and there was recent -traffic on the existing connection. -This applies to Phase 1 and Phase 2. -This is currently the only automatic way for a connection to terminate. -It may be useful with Road Warrior or Opportunistic connections. -<BR> - -Since SA lifetime negotiation is take-it-or-leave it, a Responder -normally uses the shorter of the negotiated or the configured lifetime. -This only works because if the lifetime is shorter than negotiated, -the Responder will rekey in time so that everything works. -This interacts badly with <B>--dontrekey</B>. In this case, -the Responder will end up rekeying to rectify a shortfall in an IPsec SA -lifetime; for an ISAKMP SA, the Responder will accept the negotiated -lifetime. -<DT><B>--delete</B><DD> -when used in the connection form, it causes any previous connection -with this name to be deleted before this one is added. Unlike a -normal delete, no diagnostic is produced if there was no previous -connection to delete. Any routing in place for the connection is undone. -</DL> -<P> - -The delete form deletes a named connection description and any -SAs established or negotiations initiated using this connection. -Any routing in place for the connection is undone. -<DL COMPACT> -<DT><B>--delete</B><DD> -<DT><B>--name</B> <I>connection-name</I><DD> -</DL> -<P> - -The deletestate form deletes the state object with the specified serial number. -This is useful for selectively deleting instances of connections. -<DL COMPACT> -<DT><B>--deletestate</B> <I>state-number</I><DD> -</DL> -<P> - -The route form of the <B>whack</B> command tells <B>pluto</B> to set up -routing for a connection. -Although like a traditional route, it uses an ipsec device as a -virtual interface. -Once routing is set up, no packets will be -sent ``in the clear'' to the peer's client specified in the connection. -A TRAP shunt eroute will be installed; if outbound traffic is caught, -Pluto will initiate the connection. -An explicit <B>whack</B> route is not always needed: if it hasn't been -done when an IPsec SA is being installed, one will be automatically attempted. -<P> - -When a routing is attempted for a connection, there must not already -be a routing for a different connection with the same subnet but different -interface or destination, or if -there is, it must not be being used by an IPsec SA. Otherwise the -attempt will fail. -<DL COMPACT> -<DT><B>--route</B><DD> -<DT><B>--name</B> <I>connection-name</I><DD> -</DL> -<P> - -The unroute form of the <B>whack</B> command tells <B>pluto</B> to undo -a routing. <B>pluto</B> will refuse if an IPsec SA is using the connection. -If another connection is sharing the same routing, it will be left in place. -Without a routing, packets will be sent without encryption or authentication. -<DL COMPACT> -<DT><B>--unroute</B><DD> -<DT><B>--name</B> <I>connection-name</I><DD> -</DL> -<P> - -The initiate form tells <B>pluto</B> to initiate a negotiation with another -<B>pluto</B> (or other IKE daemon) according to the named connection. -Initiation requires a route that <B>--route</B> would provide; -if none is in place at the time an IPsec SA is being installed, -<B>pluto</B> attempts to set one up. -<DL COMPACT> -<DT><B>--initiate</B><DD> -<DT><B>--name</B> <I>connection-name</I><DD> -<DT><B>--asynchronous<DD> -</DL> -<P> - -The initiate form of the whack</B> command will relay back from -<B>pluto</B> status information via the UNIX domain socket (unless ---asynchronous is specified). The status information is meant to -look a bit like that from <B>FTP</B>. Currently <B>whack</B> simply -copies this to stderr. When the request is finished (eg. the SAs are -established or <B>pluto</B> gives up), <B>pluto</B> closes the channel, -causing <B>whack</B> to terminate. -<P> - -The opportunistic initiate form is mainly used for debugging. -<DL COMPACT> -<DT><B>--tunnelipv4</B><DD> -<DT><B>--tunnelipv6</B><DD> -<DT><B>--oppohere</B> <I>ip-address</I><DD> -<DT><B>--oppothere</B> <I>ip-address</I><DD> -</DL> -<P> - -This will cause <B>pluto</B> to attempt to opportunistically initiate a -connection from here to the there, even if a previous attempt -had been made. -The whack log will show the progress of this attempt. -<P> - -The terminate form tells <B>pluto</B> to delete any SAs that use the specified -connection and to stop any negotiations in process. -It does not prevent new negotiations from starting (the delete form -has this effect). -<DL COMPACT> -<DT><B>--terminate</B><DD> -<DT><B>--name</B> <I>connection-name</I><DD> -</DL> -<P> - -The public key for informs <B>pluto</B> of the RSA public key for a potential peer. -Private keys must be kept secret, so they are kept in -<I><A HREF="ipsec.secrets.5.html">ipsec.secrets</A></I>(5). - -<DL COMPACT> -<DT><B>--keyid </B><I>id</I><DD> -specififies the identity of the peer for which a public key should be used. -Its form is identical to the identity in the connection. -If no public key is specified, <B>pluto</B> attempts to find KEY records -from DNS for the id (if a FQDN) or through reverse lookup (if an IP address). -Note that there several interesting ways in which this is not secure. -<DT><B>--addkey</B><DD> -specifies that the new key is added to the collection; otherwise the -new key replaces any old ones. -<DT><B>--pubkeyrsa </B><I>key</I><DD> -specifies the value of the RSA public key. It is a sequence of bytes -as described in RFC 2537 ``RSA/MD5 KEYs and SIGs in the Domain Name System (DNS)''. -It is denoted in a way suitable for <I><A HREF="ipsec_ttodata.3.html">ipsec_ttodata</A></I>(3). -For example, a base 64 numeral starts with 0s. -</DL> -<P> - -The listen form tells <B>pluto</B> to start listening for IKE requests -on its public interfaces. To avoid race conditions, it is normal to -load the appropriate connections into <B>pluto</B> before allowing it -to listen. If <B>pluto</B> isn't listening, it is pointless to -initiate negotiations, so it will refuse requests to do so. Whenever -the listen form is used, <B>pluto</B> looks for public interfaces and -will notice when new ones have been added and when old ones have been -removed. This is also the trigger for <B>pluto</B> to read the -<I>ipsec.secrets</I> file. So listen may useful more than once. -<DL COMPACT> -<DT><B>--listen</B><DD> -start listening for IKE traffic on public interfaces. -<DT><B>--unlisten</B><DD> -stop listening for IKE traffic on public interfaces. -</DL> -<P> - -The status form will display information about the internal state of -<B>pluto</B>: information about each potential connection, about -each state object, and about each shunt that <B>pluto</B> is managing -without an associated connection. -<DL COMPACT> -<DT><B>--status</B><DD> -</DL> -<P> - -The shutdown form is the proper way to shut down <B>pluto</B>. -It will tear down the SAs on this machine that <B>pluto</B> has negotiated. -It does not inform its peers, so the SAs on their machines remain. -<DL COMPACT> -<DT><B>--shutdown</B><DD> -</DL> -<A NAME="lbAM"> </A> -<H3>Examples</H3> - -<P> - -It would be normal to start <B>pluto</B> in one of the system initialization -scripts. It needs to be run by the superuser. Generally, no arguments are needed. -To run in manually, the superuser can simply type -<P> - ipsec pluto -<P> -The command will immediately return, but a <B>pluto</B> process will be left -running, waiting for requests from <B>whack</B> or a peer. -<P> - -Using <B>whack</B>, several potential connections would be described: -<DL COMPACT> -<DT> - - ipsec whack --name silly ---host 127.0.0.1 --to --host 127.0.0.2 ---ikelifetime 900 --ipseclifetime 800 --keyingtries 3 - -</DL> -<P> - -<DD>Since this silly connection description specifies neither encryption, -authentication, nor tunneling, it could only be used to establish -an ISAKMP SA. -<DL COMPACT> -<DT> - - ipsec whack --name secret --host 10.0.0.1 --client 10.0.1.0/24 ---to --host 10.0.0.2 --client 10.0.2.0/24 ---encrypt - -</DL> -<P> - -<DD>This is something that must be done on both sides. If the other -side is <B>pluto</B>, the same <B>whack</B> command could be used on it -(the command syntax is designed to not distinguish which end is ours). -<P> - -Now that the connections are specified, <B>pluto</B> is ready to handle -requests and replies via the public interfaces. We must tell it to discover -those interfaces and start accepting messages from peers: -<P> - ipsec whack --listen -<P> - -If we don't immediately wish to bring up a secure connection between -the two clients, we might wish to prevent insecure traffic. -The routing form asks <B>pluto</B> to cause the packets sent from -our client to the peer's client to be routed through the ipsec0 -device; if there is no SA, they will be discarded: -<P> - ipsec whack --route secret -<P> - -Finally, we are ready to get <B>pluto</B> to initiate negotiation -for an IPsec SA (and implicitly, an ISAKMP SA): -<P> - ipsec whack --initiate --name secret -<P> -A small log of interesting events will appear on standard output -(other logging is sent to syslog). -<P> - -<B>whack</B> can also be used to terminate <B>pluto</B> cleanly, tearing down -all SAs that it has negotiated. -<P> - ipsec whack --shutdown -<P> -Notification of any IPSEC SA deletion, but not ISAKMP SA deletion -is sent to the peer. Unfortunately, such Notification is not reliable. -Furthermore, <B>pluto</B> itself ignores Notifications. -<A NAME="lbAN"> </A> -<H3>The updown command</H3> - -<P> - -Whenever <B>pluto</B> brings a connection up or down, it invokes -the updown command. This command is specified using the <B>--updown</B> -option. This allows for customized control over routing and firewall manipulation. -<P> - -The updown is invoked for five different operations. Each of -these operations can be for our client subnet or for our host itself. -<DL COMPACT> -<DT><B>prepare-host</B> or <B>prepare-client</B><DD> -is run before bringing up a new connection if no other connection -with the same clients is up. Generally, this is useful for deleting a -route that might have been set up before <B>pluto</B> was run or -perhaps by some agent not known to <B>pluto</B>. -<DT><B>route-host</B> or <B>route-client</B><DD> -is run when bringing up a connection for a new peer client subnet -(even if <B>prepare-host</B> or <B>prepare-client</B> was run). The -command should install a suitable route. Routing decisions are based -only on the destination (peer's client) subnet address, unlike eroutes -which discriminate based on source too. -<DT><B>unroute-host</B> or <B>unroute-client</B><DD> -is run when bringing down the last connection for a particular peer -client subnet. It should undo what the <B>route-host</B> or <B>route-client</B> -did. -<DT><B>up-host</B> or <B>up-client</B><DD> -is run when bringing up a tunnel eroute with a pair of client subnets -that does not already have a tunnel eroute. -This command should install firewall rules as appropriate. -It is generally a good idea to allow IKE messages (UDP port 500) -travel between the hosts. -<DT><B>down-host</B> or <B>down-client</B><DD> -is run when bringing down the eroute for a pair of client subnets. -This command should delete firewall rules as appropriate. Note that -there may remain some inbound IPsec SAs with these client subnets. -</DL> -<P> - -The script is passed a large number of environment variables to specify -what needs to be done. -<DL COMPACT> -<DT><B>PLUTO_VERSION</B><DD> -indicates what version of this interface is being used. This document -describes version 1.1. This is upwardly compatible with version 1.0. -<DT><B>PLUTO_VERB</B><DD> -specifies the name of the operation to be performed -(<B>prepare-host</B>,r <B>prepare-client</B>, -<B>up-host</B>, <B>up-client</B>, -<B>down-host</B>, or <B>down-client</B>). If the address family for -security gateway to security gateway communications is IPv6, then -a suffix of -v6 is added to the verb. -<DT><B>PLUTO_CONNECTION</B><DD> -is the name of the connection for which we are routing. -<DT><B>PLUTO_NEXT_HOP</B><DD> -is the next hop to which packets bound for the peer must be sent. -<DT><B>PLUTO_INTERFACE</B><DD> -is the name of the ipsec interface to be used. -<DT><B>PLUTO_ME</B><DD> -is the IP address of our host. -<DT><B>PLUTO_MY_CLIENT</B><DD> -is the IP address / count of our client subnet. -If the client is just the host, this will be the host's own IP address / max -(where max is 32 for IPv4 and 128 for IPv6). -<DT><B>PLUTO_MY_CLIENT_NET</B><DD> -is the IP address of our client net. -If the client is just the host, this will be the host's own IP address. -<DT><B>PLUTO_MY_CLIENT_MASK</B><DD> -is the mask for our client net. -If the client is just the host, this will be 255.255.255.255. -<DT><B>PLUTO_PEER</B><DD> -is the IP address of our peer. -<DT><B>PLUTO_PEER_CLIENT</B><DD> -is the IP address / count of the peer's client subnet. -If the client is just the peer, this will be the peer's own IP address / max -(where max is 32 for IPv4 and 128 for IPv6). -<DT><B>PLUTO_PEER_CLIENT_NET</B><DD> -is the IP address of the peer's client net. -If the client is just the peer, this will be the peer's own IP address. -<DT><B>PLUTO_PEER_CLIENT_MASK</B><DD> -is the mask for the peer's client net. -If the client is just the peer, this will be 255.255.255.255. -</DL> -<P> - -All output sent by the script to stderr or stdout is logged. The -script should return an exit status of 0 if and only if it succeeds. -<P> - -<B>Pluto</B> waits for the script to finish and will not do any other -processing while it is waiting. -The script may assume that <B>pluto</B> will not change anything -while the script runs. -The script should avoid doing anything that takes much time and it -should not issue any command that requires processing by <B>pluto</B>. -Either of these activities could be performed by a background -subprocess of the script. -<A NAME="lbAO"> </A> -<H3>Rekeying</H3> - -<P> - -When an SA that was initiated by <B>pluto</B> has only a bit of -lifetime left, -<B>pluto</B> will initiate the creation of a new SA. This applies to -ISAKMP and IPsec SAs. -The rekeying will be initiated when the SA's remaining lifetime is -less than the rekeymargin plus a random percentage, between 0 and -rekeyfuzz, of the rekeymargin. -<P> - -Similarly, when an SA that was initiated by the peer has only a bit of -lifetime left, <B>pluto</B> will try to initiate the creation of a -replacement. -To give preference to the initiator, this rekeying will only be initiated -when the SA's remaining lifetime is half of rekeymargin. -If rekeying is done by the responder, the roles will be reversed: the -responder for the old SA will be the initiator for the replacement. -The former initiator might also initiate rekeying, so there may -be redundant SAs created. -To avoid these complications, make sure that rekeymargin is generous. -<P> - -One risk of having the former responder initiate is that perhaps -none of its proposals is acceptable to the former initiator -(they have not been used in a successful negotiation). -To reduce the chances of this happening, and to prevent loss of security, -the policy settings are taken from the old SA (this is the case even if -the former initiator is initiating). -These may be stricter than those of the connection. -<P> - -<B>pluto</B> will not rekey an SA if that SA is not the most recent of its -type (IPsec or ISAKMP) for its potential connection. -This avoids creating redundant SAs. -<P> - -The random component in the rekeying time (rekeyfuzz) is intended to -make certain pathological patterns of rekeying unstable. If both -sides decide to rekey at the same time, twice as many SAs as necessary -are created. This could become a stable pattern without the -randomness. -<P> - -Another more important case occurs when a security gateway has SAs -with many other security gateways. Each of these connections might -need to be rekeyed at the same time. This would cause a high peek -requirement for resources (network bandwidth, CPU time, entropy for -random numbers). The rekeyfuzz can be used to stagger the rekeying -times. -<P> - -Once a new set of SAs has been negotiated, <B>pluto</B> will never send -traffic on a superseded one. Traffic will be accepted on an old SA -until it expires. -<A NAME="lbAP"> </A> -<H3>Selecting a Connection When Responding: Road Warrior Support</H3> - -<P> - -When <B>pluto</B> receives an initial Main Mode message, it needs to -decide which connection this message is for. It picks based solely on -the source and destination IP addresses of the message. There might -be several connections with suitable IP addresses, in which case one -of them is arbitrarily chosen. (The ISAKMP SA proposal contained in -the message could be taken into account, but it is not.) -<P> - -The ISAKMP SA is negotiated before the parties pass further -identifying information, so all ISAKMP SA characteristics specified in -the connection description should be the same for every connection -with the same two host IP addresses. At the moment, the only -characteristic that might differ is authentication method. -<P> - -Up to this point, -all configuring has presumed that the IP addresses -are known to all parties ahead of time. This will not work -when either end is mobile (or assigned a dynamic IP address for other -reasons). We call this situation ``Road Warrior''. It is fairly tricky -and has some important limitations, most of which are features of -the IKE protocol. -<P> - -Only the initiator may be mobile: -the initiator may have an IP number unknown to the responder. When -the responder doesn't recognize the IP address on the first Main Mode -packet, it looks for a connection with itself as one end and <B>%any</B> -as the other. -If it cannot find one, it refuses to negotiate. If it -does find one, it creates a temporary connection that is a duplicate -except with the <B>%any</B> replaced by the source IP address from the -packet; if there was no identity specified for the peer, the new IP -address will be used. -<P> - -When <B>pluto</B> is using one of these temporary connections and -needs to find the preshared secret or RSA private key in <I>ipsec.secrets</I>, -and and the connection specified no identity for the peer, <B>%any</B> -is used as its identity. After all, the real IP address was apparently -unknown to the configuration, so it is unreasonable to require that -it be used in this table. -<P> - -Part way into the Phase 1 (Main Mode) negotiation using one of these -temporary connection descriptions, <B>pluto</B> will be receive an -Identity Payload. At this point, <B>pluto</B> checks for a more -appropriate connection, one with an identity for the peer that matches -the payload but which would use the same keys so-far used for -authentication. If it finds one, it will switch to using this better -connection (or a temporary derived from this, if it has <B>%any</B> -for the peer's IP address). It may even turn out that no connection -matches the newly discovered identity, including the current connection; -if so, <B>pluto</B> terminates negotiation. -<P> - -Unfortunately, if preshared secret authentication is being used, the -Identity Payload is encrypted using this secret, so the secret must be -selected by the responder without knowing this payload. This -limits there to being at most one preshared secret for all Road Warrior -systems connecting to a host. RSA Signature authentications does not -require that the responder know how to select the initiator's public key -until after the initiator's Identity Payload is decoded (using the -responder's private key, so that must be preselected). -<P> - -When <B>pluto</B> is responding to a Quick Mode negotiation via one of these -temporary connection descriptions, it may well find that the subnets -specified by the initiator don't match those in the temporary -connection description. If so, it will look for a connection with -matching subnets, its own host address, a peer address of <B>%any</B> -and matching identities. -If it finds one, a new temporary connection is derived from this one -and used for the Quick Mode negotiation of IPsec SAs. If it does not -find one, <B>pluto</B> terminates negotiation. -<P> - -Be sure to specify an appropriate nexthop for the responder -to send a message to the initiator: <B>pluto</B> has no way of guessing -it (if forwarding isn't required, use an explicit <B>%direct</B> as the nexthop -and the IP address of the initiator will be filled in; the obsolete -notation <B>0.0.0.0</B> is still accepted). -<P> - -<B>pluto</B> has no special provision for the initiator side. The current -(possibly dynamic) IP address and nexthop must be used in defining -connections. These must be -properly configured each time the initiator's IP address changes. -<B>pluto</B> has no mechanism to do this automatically. -<P> - -Although we call this Road Warrior Support, it could also be used to -support encrypted connections with anonymous initiators. The -responder's organization could announce the preshared secret that would be used -with unrecognized initiators and let anyone connect. Of course the initiator's -identity would not be authenticated. -<P> - -If any Road Warrior connections are supported, <B>pluto</B> cannot -reject an exchange initiated by an unknown host until it has -determined that the secret is not shared or the signature is invalid. -This must await the -third Main Mode message from the initiator. If no Road Warrior -connection is supported, the first message from an unknown source -would be rejected. This has implications for ease of debugging -configurations and for denial of service attacks. -<P> - -Although a Road Warrior connection must be initiated by the mobile -side, the other side can and will rekey using the temporary connection -it has created. If the Road Warrior wishes to be able to disconnect, -it is probably wise to set <B>--keyingtries</B> to 1 in the -connection on the non-mobile side to prevent it trying to rekey the -connection. Unfortunately, there is no mechanism to unroute the -connection automatically. -<A NAME="lbAQ"> </A> -<H3>Debugging</H3> - -<P> - -<B>pluto</B> accepts several optional arguments, useful mostly for debugging. -Except for <B>--interface</B>, each should appear at most once. -<DL COMPACT> -<DT><B>--interface</B> <I>interfacename</I><DD> -specifies that the named real public network interface should be considered. -The interface name specified should not be <B>ipsec</B><I>N</I>. -If the option doesn't appear, all interfaces are considered. -To specify several interfaces, use the option once for each. -One use of this option is to specify which interface should be used -when two or more share the same IP address. -<DT><B>--ikeport</B> <I>port-number</I><DD> -changes the UDP port that <B>pluto</B> will use -(default, specified by IANA: 500) -<DT><B>--ctlbase</B> <I>path</I><DD> -basename for control files. -<I>path</I>.ctl is the socket through which <B>whack</B> communicates with -<B>pluto</B>. -<I>path</I>.pid is the lockfile to prevent multiple <B>pluto</B> instances. -The default is <I>/var/run/pluto</I>). -<DT><B>--secretsfile</B> <I>file</I><DD> -specifies the file for authentication secrets -(default: <I>/etc/ipsec.secrets</I>). -This name is subject to ``globbing'' as in <I><A HREF="sh.1.html">sh</A></I>(1), -so every file with a matching name is processed. -Quoting is generally needed to prevent the shell from doing the globbing. -<DT><B>--adns</B> <I>pathname</I><DD> -<DT><B>--lwdnsq</B> <I>pathname</I><DD> -specifies where to find <B>pluto</B>'s helper program for asynchronous DNS lookup. -<B>pluto</B> can be built to use one of two helper programs: <B>_pluto_adns</B> -or <B>lwdnsq</B>. You must use the program for which it was built. -By default, <B>pluto</B> will look for the program in -<B>$IPSEC_DIR</B> (if that environment variable is defined) or, failing that, -in the same directory as <B>pluto</B>. -<DT><B>--nofork</B><DD> -disable ``daemon fork'' (default is to fork). In addition, after the -lock file and control socket are created, print the line ``Pluto -initialized'' to standard out. -<DT><B>--noklips</B><DD> -don't actually implement negotiated IPsec SAs -<DT><B>--uniqueids</B><DD> -if this option has been selected, whenever a new ISAKMP SA is -established, any connection with the same Peer ID but a different -Peer IP address is unoriented (causing all its SAs to be deleted). -This helps clean up dangling SAs when a connection is lost and -then regained at another IP address. -<DT><B>--stderrlog</B><DD> -log goes to standard out {default is to use <I><A HREF="syslogd.8.html">syslogd</A></I>(8)) -</DL> -<P> - -For example -<DL COMPACT> -<DT>pluto --secretsfile ipsec.secrets --ctlbase pluto.base --ikeport 8500 --nofork --noklips --stderrlog<DD> -</DL> -<P> - -lets one test <B>pluto</B> without using the superuser account. -<P> - -<B>pluto</B> is willing to produce a prodigious amount of debugging -information. To do so, it must be compiled with -DDEBUG. There are -several classes of debugging output, and <B>pluto</B> may be directed to -produce a selection of them. All lines of -debugging output are prefixed with ``| '' to distinguish them from error -messages. -<P> - -When <B>pluto</B> is invoked, it may be given arguments to specify -which classes to output. The current options are: -<DL COMPACT> -<DT><B>--debug-raw</B><DD> -show the raw bytes of messages -<DT><B>--debug-crypt</B><DD> -show the encryption and decryption of messages -<DT><B>--debug-parsing</B><DD> -show the structure of input messages -<DT><B>--debug-emitting</B><DD> -show the structure of output messages -<DT><B>--debug-control</B><DD> -show <B>pluto</B>'s decision making -<DT><B>--debug-lifecycle</B><DD> -[this option is temporary] log more detail of lifecycle of SAs -<DT><B>--debug-klips</B><DD> -show <B>pluto</B>'s interaction with <B>KLIPS</B> -<DT><B>--debug-dns</B><DD> -show <B>pluto</B>'s interaction with <B>DNS</B> for KEY and TXT records -<DT><B>--debug-oppo</B><DD> -show why <B>pluto</B> didn't find a suitable DNS TXT record to authorize opportunistic initiation -<DT><B>--debug-all</B><DD> -all of the above -<DT><B>--debug-private</B><DD> -allow debugging output with private keys. -<DT><B>--debug-none</B><DD> -none of the above -</DL> -<P> - -The debug form of the -<B>whack</B> command will change the selection in a running -<B>pluto</B>. -If a connection name is specified, the flags are added whenever -<B>pluto</B> has identified that it is dealing with that connection. -Unfortunately, this is often part way into the operation being observed. -<P> - -For example, to start a <B>pluto</B> with a display of the structure of input -and output: -<DL COMPACT> -<DT><DD> -pluto --debug-emitting --debug-parsing -</DL> -<P> - -To later change this <B>pluto</B> to only display raw bytes: -<DL COMPACT> -<DT><DD> -whack --debug-raw -</DL> -<P> - -For testing, SSH's IKE test page is quite useful: -<DL COMPACT> -<DT><DD> -<I><A HREF="http://isakmp-test.ssh.fi/">http://isakmp-test.ssh.fi/</A></I> -</DL> -<P> - -Hint: ISAKMP SAs are often kept alive by IKEs even after the IPsec SA -is established. This allows future IPsec SA's to be negotiated -directly. If one of the IKEs is restarted, the other may try to use -the ISAKMP SA but the new IKE won't know about it. This can lead to -much confusion. <B>pluto</B> is not yet smart enough to get out of such a -mess. -<A NAME="lbAR"> </A> -<H3>Pluto's Behaviour When Things Go Wrong</H3> - -<P> - -When <B>pluto</B> doesn't understand or accept a message, it just -ignores the message. It is not yet capable of communicating the -problem to the other IKE daemon (in the future it might use -Notifications to accomplish this in many cases). It does log a diagnostic. -<P> - -When <B>pluto</B> gets no response from a message, it resends the same -message (a message will be sent at most three times). This is -appropriate: UDP is unreliable. -<P> - -When pluto gets a message that it has already seen, there are many -cases when it notices and discards it. This too is appropriate for UDP. -<P> - -Combine these three rules, and you can explain many apparently -mysterious behaviours. In a <B>pluto</B> log, retrying isn't usually the -interesting event. The critical thing is either earlier (<B>pluto</B> -got a message which it didn't like and so ignored, so it was still -awaiting an acceptable message and got impatient) or on the other -system (<B>pluto</B> didn't send a reply because it wasn't happy with -the previous message). -<A NAME="lbAS"> </A> -<H3>Notes</H3> - -<P> - -If <B>pluto</B> is compiled without -DKLIPS, it negotiates Security -Associations but never ask the kernel to put them in place and never -makes routing changes. This allows <B>pluto</B> to be tested on systems -without <B>KLIPS</B>, but makes it rather useless. -<P> - -Each IPsec SA is assigned an SPI, a 32-bit number used to refer to the SA. -The IKE protocol lets the destination of the SA choose the SPI. -The range 0 to 0xFF is reserved for IANA. -<B>Pluto</B> also avoids choosing an SPI in the range 0x100 to 0xFFF, -leaving these SPIs free for manual keying. -Remember that the peer, if not <B>pluto</B>, may well chose -SPIs in this range. -<A NAME="lbAT"> </A> -<H3>Policies</H3> - -<P> - -This catalogue of policies may be of use when trying to configure -<B>Pluto</B> and another IKE implementation to interoperate. -<P> - -In Phase 1, only Main Mode is supported. We are not sure that -Aggressive Mode is secure. For one thing, it does not support -identity protection. It may allow more severe Denial Of Service -attacks. -<P> - -No Informational Exchanges are supported. These are optional and -since their delivery is not assured, they must not matter. -It is the case that some IKE implementations won't interoperate -without Informational Exchanges, but we feel they are broken. -<P> - -No Informational Payloads are supported. These are optional, but -useful. It is of concern that these payloads are not authenticated in -Phase 1, nor in those Phase 2 messages authenticated with <A HREF="HASH.3.html">HASH</A>(3). -<DL COMPACT> -<DT>*<DD> -Diffie Hellman Groups MODP 1024 and MODP 1536 (2 and 5) -are supported. -Group MODP768 (1) is not supported because it is too weak. -<DT>*<DD> -Host authetication can be done by RSA Signatures or Pre-Shared -Secrets. -<DT>*<DD> -3DES CBC (Cypher Block Chaining mode) is the only encryption -supported, both for ISAKMP SAs and IPSEC SAs. -<DT>*<DD> -MD5 and SHA1 hashing are supported for packet authentication in both -kinds of SAs. -<DT>*<DD> -The ESP, AH, or AH plus ESP are supported. If, and only if, AH and -ESP are combined, the ESP need not have its own authentication -component. The selection is controlled by the --encrypt and ---authenticate flags. -<DT>*<DD> -Each of these may be combined with IPCOMP Deflate compression, -but only if the potential connection specifies compression and only -if KLIPS is configured with IPCOMP support. -<DT>*<DD> -The IPSEC SAs may be tunnel or transport mode, where appropriate. -The --tunnel flag controls this when <B>pluto</B> is initiating. -<DT>*<DD> -When responding to an ISAKMP SA proposal, the maximum acceptable -lifetime is eight hours. The default is one hour. There is no -minimum. The --ikelifetime flag controls this when <B>pluto</B> -is initiating. -<DT>*<DD> -When responding to an IPSEC SA proposal, the maximum acceptable -lifetime is one day. The default is eight hours. There is no -minimum. The --ipseclifetime flag controls this when <B>pluto</B> -is initiating. -<DT>*<DD> -PFS is acceptable, and will be proposed if the --pfs flag was -specified. The DH group proposed will be the same as negotiated for -Phase 1. -</DL> -<A NAME="lbAU"> </A> -<H2>SIGNALS</H2> - -<P> - -<B>Pluto</B> responds to <B>SIGHUP</B> by issuing a suggestion that ``<B>whack</B> ---listen'' might have been intended. -<P> - -<B>Pluto</B> exits when it recieves <B>SIGTERM</B>. -<A NAME="lbAV"> </A> -<H2>EXIT STATUS</H2> - -<P> - -<B>pluto</B> normally forks a daemon process, so the exit status is -normally a very preliminary result. -<DL COMPACT> -<DT>0<DD> -means that all is OK so far. -<DT>1<DD> -means that something was wrong. -<DT>10<DD> -means that the lock file already exists. -</DL> -<P> - -If <B>whack</B> detects a problem, it will return an exit status of 1. -If it received progress messages from <B>pluto</B>, it returns as status -the value of the numeric prefix from the last such message -that was not a message sent to syslog or a comment -(but the prefix for success is treated as 0). -Otherwise, the exit status is 0. -<A NAME="lbAW"> </A> -<H2>FILES</H2> - -<I>/var/run/pluto.pid</I> -<BR> - -<I>/var/run/pluto.ctl</I> -<BR> - -<I>/etc/ipsec.secrets</I> -<BR> - -<I>$IPSEC_LIBDIR/_pluto_adns</I> -<BR> - -<I>$IPSEC_EXECDIR/lwdnsq</I> -<BR> - -<I>/dev/urandom</I> -<A NAME="lbAX"> </A> -<H2>ENVIRONMENT</H2> - -<I>IPSEC_LIBDIR</I> -<BR> - -<I>IPSEC_EXECDIR</I> -<BR> - -<I>IPSECmyid</I> -<A NAME="lbAY"> </A> -<H2>SEE ALSO</H2> - -<P> - -The rest of the FreeS/WAN distribution, in particular <I><A HREF="ipsec.8.html">ipsec</A></I>(8). -<P> - -<I><A HREF="ipsec_auto.8.html">ipsec_auto</A></I>(8) is designed to make using <B>pluto</B> more pleasant. -Use it! -<P> - -<I><A HREF="ipsec.secrets.5.html">ipsec.secrets</A></I>(5) - -describes the format of the secrets file. -<P> - -<I><A HREF="ipsec_atoaddr.3.html">ipsec_atoaddr</A></I>(3), part of the FreeS/WAN distribution, describes the -forms that IP addresses may take. -<I><A HREF="ipsec_atosubnet.3.html">ipsec_atosubnet</A></I>(3), part of the FreeS/WAN distribution, describes the -forms that subnet specifications. -<P> - -For more information on IPsec, the mailing list, and the relevant -documents, see: -<DL COMPACT> -<DT><DD> - -<I><A HREF="http://www.ietf.cnri.reston.va.us/html.charters/ipsec-charter.html">http://www.ietf.cnri.reston.va.us/html.charters/ipsec-charter.html</A></I> - -</DL> -<P> - -At the time of writing, the most relevant IETF RFCs are: -<DL COMPACT> -<DT><DD> -RFC2409 The Internet Key Exchange (IKE) -<DT><DD> -RFC2408 Internet Security Association and Key Management Protocol (ISAKMP) -<DT><DD> -RFC2407 The Internet IP Security Domain of Interpretation for ISAKMP -</DL> -<P> - -The FreeS/WAN web site <<A HREF="htp://www.freeswan.org">htp://www.freeswan.org</A>> -and the mailing lists described there. -<A NAME="lbAZ"> </A> -<H2>HISTORY</H2> - -This code is released under the GPL terms. -See the accompanying file COPYING-2.0 for more details. -The GPL does NOT apply to those pieces of code written by others -which are included in this distribution, except as noted by the -individual authors. -<P> - -This software was originally written -for the FreeS/WAN project -<<A HREF="http://www.freeswan.org">http://www.freeswan.org</A>> -by Angelos D. Keromytis -(<A HREF="mailto:angelos@dsl.cis.upenn.edu">angelos@dsl.cis.upenn.edu</A>), in May/June 1997, in Athens, Greece. -Thanks go to John Ioannidis for his help. -<P> - -It is currently (2000) -being developed and maintained by D. Hugh Redelmeier -(<A HREF="mailto:hugh@mimosa.com">hugh@mimosa.com</A>), in Canada. The regulations of Greece and Canada -allow us to make the code freely redistributable. -<P> - -Kai Martius (<A HREF="mailto:admin@imib.med.tu-dresden.de">admin@imib.med.tu-dresden.de</A>) contributed the initial -version of the code supporting PFS. -<P> - -Richard Guy Briggs <<A HREF="mailto:rgb@conscoop.ottawa.on.ca">rgb@conscoop.ottawa.on.ca</A>> and Peter Onion -<<A HREF="mailto:ponion@srd.bt.co.uk">ponion@srd.bt.co.uk</A>> added the PFKEY2 support. -<P> - -We gratefully acknowledge that we use parts of Eric Young's <I>libdes</I> -package; see <I>../libdes/COPYRIGHT</I>. -<A NAME="lbBA"> </A> -<H2>BUGS</H2> - -<B>pluto</B> - -is a work-in-progress. It currently has many limitations. -For example, it ignores notification messages that it receives, and -it generates only Delete Notifications and those only for IPSEC SAs. -<P> - -<B>pluto</B> does not support the Commit Flag. -The Commit Flag is a bad feature of the IKE protocol. -It isn't protected -- neither encrypted nor authenticated. -A man in the middle could turn it on, leading to DoS. -We just ignore it, with a warning. -This should let us interoperate with -implementations that insist on it, with minor damage. -<P> - -<B>pluto</B> does not check that the SA returned by the Responder -is actually one that was proposed. It only checks that the SA is -acceptable. The difference is not large, but can show up in attributes -such as SA lifetime. -<P> - -There is no good way for a connection to be automatically terminated. -This is a problem for Road Warrior and Opportunistic connections. -The <B>--dontrekey</B> option does prevent the SAs from -being rekeyed on expiry. -Additonally, if a Road Warrior connection has a client subnet with a fixed IP -address, a negotiation with that subnet will cause any other -connection instantiations with that same subnet to be unoriented -(deleted, in effect). -See also the --uniqueids option for an extension of this. -<P> - -When <B>pluto</B> sends a message to a peer that has disappeared, -<B>pluto</B> receives incomplete information from the kernel, so it -logs the unsatisfactory message ``some IKE message we sent has been -rejected with ECONNREFUSED (kernel supplied no details)''. John -Denker suggests that this command is useful for tracking down the -source of these problems: -<BR> - -<TT> </TT>tcpdump -i eth0 icmp[0] != 8 and icmp[0] != 0<BR> -<BR> - -Substitute your public interface for eth0 if it is different. -<P> - -The word ``authenticate'' is used for two different features. We must -authenticate each IKE peer to the other. This is an important task of -Phase 1. Each packet must be authenticated, both in IKE and in IPsec, -and the method for IPsec is negotiated as an AH SA or part of an ESP SA. -Unfortunately, the protocol has no mechanism for authenticating the Phase 2 -identities. -<P> - -Bugs should be reported to the <<A HREF="mailto:users@lists.freeswan.org">users@lists.freeswan.org</A>> mailing list. -Caution: we cannot accept -actual code from US residents, or even US citizens living outside the -US, because that would bring FreeS/WAN under US export law. Some -other countries cause similar problems. In general, we would prefer -that you send detailed problem reports rather than code: we want -FreeS/WAN to be unquestionably freely exportable, which means being -very careful about where the code comes from, and for a small bug fix, -that is often more time-consuming than just reinventing the fix -ourselves. -<P> - -<HR> -<A NAME="index"> </A><H2>Index</H2> -<DL> -<DT><A HREF="#lbAB">NAME</A><DD> -<DT><A HREF="#lbAC">SYNOPSIS</A><DD> -<DT><A HREF="#lbAD">DESCRIPTION</A><DD> -<DL> -<DT><A HREF="#lbAE">IKE's Job</A><DD> -<DT><A HREF="#lbAF">Pluto</A><DD> -<DT><A HREF="#lbAG">Before Running Pluto</A><DD> -<DT><A HREF="#lbAH">Setting up <B>KLIPS</B> for <B>pluto</B></A><DD> -<DT><A HREF="#lbAI">ipsec.secrets file</A><DD> -<DT><A HREF="#lbAJ">Running Pluto</A><DD> -<DT><A HREF="#lbAK">Pluto's Internal State</A><DD> -<DT><A HREF="#lbAL">Using Whack</A><DD> -<DT><A HREF="#lbAM">Examples</A><DD> -<DT><A HREF="#lbAN">The updown command</A><DD> -<DT><A HREF="#lbAO">Rekeying</A><DD> -<DT><A HREF="#lbAP">Selecting a Connection When Responding: Road Warrior Support</A><DD> -<DT><A HREF="#lbAQ">Debugging</A><DD> -<DT><A HREF="#lbAR">Pluto's Behaviour When Things Go Wrong</A><DD> -<DT><A HREF="#lbAS">Notes</A><DD> -<DT><A HREF="#lbAT">Policies</A><DD> -</DL> -<DT><A HREF="#lbAU">SIGNALS</A><DD> -<DT><A HREF="#lbAV">EXIT STATUS</A><DD> -<DT><A HREF="#lbAW">FILES</A><DD> -<DT><A HREF="#lbAX">ENVIRONMENT</A><DD> -<DT><A HREF="#lbAY">SEE ALSO</A><DD> -<DT><A HREF="#lbAZ">HISTORY</A><DD> -<DT><A HREF="#lbBA">BUGS</A><DD> -</DL> -<HR> -This document was created by -<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, -using the manual pages.<BR> -Time: 21:40:18 GMT, November 11, 2003 -</BODY> -</HTML> diff --git a/doc/src/draft-richardson-ipsec-opportunistic.html b/doc/src/draft-richardson-ipsec-opportunistic.html deleted file mode 100644 index 87a13365a..000000000 --- a/doc/src/draft-richardson-ipsec-opportunistic.html +++ /dev/null @@ -1,2456 +0,0 @@ -<html><head><title>Opportunistic Encryption using The Internet Key Exchange (IKE)</title> -<STYLE type='text/css'> - .title { color: #990000; font-size: 22px; line-height: 22px; font-weight: bold; text-align: right; - font-family: helvetica, arial, sans-serif } - .filename { color: #666666; font-size: 18px; line-height: 28px; font-weight: bold; text-align: right; - font-family: helvetica, arial, sans-serif } - p.copyright { color: #000000; font-size: 10px; - font-family: verdana, charcoal, helvetica, arial, sans-serif } - p { margin-left: 2em; margin-right: 2em; } - li { margin-left: 3em; } - ol { margin-left: 2em; margin-right: 2em; } - ul.text { margin-left: 2em; margin-right: 2em; } - pre { margin-left: 3em; color: #333333 } - ul.toc { color: #000000; line-height: 16px; - font-family: verdana, charcoal, helvetica, arial, sans-serif } - H3 { color: #333333; font-size: 16px; line-height: 16px; font-family: helvetica, arial, sans-serif } - H4 { color: #000000; font-size: 14px; font-family: helvetica, arial, sans-serif } - TD.header { color: #ffffff; font-size: 10px; font-family: arial, helvetica, san-serif; valign: top } - TD.author-text { color: #000000; font-size: 10px; - font-family: verdana, charcoal, helvetica, arial, sans-serif } - TD.author { color: #000000; font-weight: bold; margin-left: 4em; font-size: 10px; font-family: verdana, charcoal, helvetica, arial, sans-serif } - A:link { color: #990000; font-weight: bold; - font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif } - A:visited { color: #333333; font-weight: bold; - font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif } - A:name { color: #333333; font-weight: bold; - font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif } - .link2 { color:#ffffff; font-weight: bold; text-decoration: none; - font-family: monaco, charcoal, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif; - font-size: 9px } - .RFC { color:#666666; font-weight: bold; text-decoration: none; - font-family: monaco, charcoal, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif; - font-size: 9px } - .hotText { color:#ffffff; font-weight: normal; text-decoration: none; - font-family: charcoal, monaco, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif; - font-size: 9px } -</style> -</head> -<body bgcolor="#ffffff" text="#000000" alink="#000000" vlink="#666666" link="#990000"> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<table width="66%" border="0" cellpadding="0" cellspacing="0"><tr><td><table width="100%" border="0" cellpadding="2" cellspacing="1"> -<tr valign="top"><td width="33%" bgcolor="#666666" class="header">Independent submission</td><td width="33%" bgcolor="#666666" class="header">M. Richardson</td></tr> -<tr valign="top"><td width="33%" bgcolor="#666666" class="header">Internet-Draft</td><td width="33%" bgcolor="#666666" class="header">SSW</td></tr> -<tr valign="top"><td width="33%" bgcolor="#666666" class="header">Expires: November 19, 2003</td><td width="33%" bgcolor="#666666" class="header">D. Redelmeier</td></tr> -<tr valign="top"><td width="33%" bgcolor="#666666" class="header"> </td><td width="33%" bgcolor="#666666" class="header">Mimosa</td></tr> -<tr valign="top"><td width="33%" bgcolor="#666666" class="header"> </td><td width="33%" bgcolor="#666666" class="header">May 21, 2003</td></tr> -</table></td></tr></table> -<div align="right"><font face="monaco, MS Sans Serif" color="#990000" size="+3"><b><br><span class="title">Opportunistic Encryption using The Internet Key Exchange (IKE)</span></b></font></div> -<div align="right"><font face="monaco, MS Sans Serif" color="#666666" size="+2"><b><span class="filename">draft-richardson-ipsec-opportunistic-11.txt</span></b></font></div> -<font face="verdana, helvetica, arial, sans-serif" size="2"> - -<h3>Status of this Memo</h3> -<p> -This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026.</p> -<p> -Internet-Drafts are working documents of the Internet Engineering -Task Force (IETF), its areas, and its working groups. -Note that other groups may also distribute working documents as -Internet-Drafts.</p> -<p> -Internet-Drafts are draft documents valid for a maximum of six months -and may be updated, replaced, or obsoleted by other documents at any time. -It is inappropriate to use Internet-Drafts as reference material or to cite -them other than as "work in progress."</p> -<p> -The list of current Internet-Drafts can be accessed at -<a href='http://www.ietf.org/ietf/1id-abstracts.txt'>http://www.ietf.org/ietf/1id-abstracts.txt</a>.</p> -<p> -The list of Internet-Draft Shadow Directories can be accessed at -<a href='http://www.ietf.org/shadow.html'>http://www.ietf.org/shadow.html</a>.</p> -<p> -This Internet-Draft will expire on November 19, 2003.</p> - -<h3>Copyright Notice</h3> -<p> -Copyright (C) The Internet Society (2003). All Rights Reserved.</p> - -<h3>Abstract</h3> - -<p> -This document describes opportunistic encryption (OE) using the Internet Key -Exchange (IKE) and IPsec. -Each system administrator adds new -resource records to his or her Domain Name System (DNS) to support -opportunistic encryption. The objective is to allow encryption for secure communication without -any pre-arrangement specific to the pair of systems involved. - -</p> -<p> -DNS is used to distribute the public keys of each -system involved. This is resistant to passive attacks. The use of DNS -Security (DNSSEC) secures this system against active attackers as well. - -</p> -<p> -As a result, the administrative overhead is reduced -from the square of the number of systems to a linear dependence, and it becomes -possible to make secure communication the default even -when the partner is not known in advance. - -</p> -<p> -This document is offered up as an Informational RFC. - -</p><a name="toc"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<h3>Table of Contents</h3> -<ul compact class="toc"> -<b><a href="#anchor1">1.</a> -Introduction<br></b> -<b><a href="#anchor6">2.</a> -Overview<br></b> -<b><a href="#anchor13">3.</a> -Specification<br></b> -<b><a href="#anchor31">4.</a> -Impacts on IKE<br></b> -<b><a href="#anchor38">5.</a> -DNS issues<br></b> -<b><a href="#anchor42">6.</a> -Network address translation interaction<br></b> -<b><a href="#anchor46">7.</a> -Host implementations<br></b> -<b><a href="#anchor47">8.</a> -Multi-homing<br></b> -<b><a href="#anchor48">9.</a> -Failure modes<br></b> -<b><a href="#anchor52">10.</a> -Unresolved issues<br></b> -<b><a href="#anchor54">11.</a> -Examples<br></b> -<b><a href="#securityconsiderations">12.</a> -Security considerations<br></b> -<b><a href="#anchor79">13.</a> -IANA Considerations<br></b> -<b><a href="#anchor80">14.</a> -Acknowledgments<br></b> -<b><a href="#rfc.references1">§</a> -Normative references<br></b> -<b><a href="#rfc.authors">§</a> -Authors' Addresses<br></b> -<b><a href="#rfc.copyright">§</a> -Full Copyright Statement<br></b> -</ul> -<br clear="all"> - -<a name="anchor1"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.1"></a><h3>1. Introduction</h3> - -<a name="rfc.section.1.1"></a><h4><a name="anchor2">1.1</a> Motivation</h4> - -<p> -The objective of opportunistic encryption is to allow encryption without -any pre-arrangement specific to the pair of systems involved. Each -system administrator adds -public key information to DNS records to support opportunistic -encryption and then enables this feature in the nodes' IPsec stack. -Once this is done, any two such nodes can communicate securely. - -</p> -<p> -This document describes opportunistic encryption as designed and -mostly implemented by the Linux FreeS/WAN project. -For project information, see http://www.freeswan.org. - -</p> -<p> -The Internet Architecture Board (IAB) and Internet Engineering -Steering Group (IESG) have taken a strong stand that the Internet -should use powerful encryption to provide security and -privacy <a href="#RFC1984">[4]</a>. -The Linux FreeS/WAN project attempts to provide a practical means to implement this policy. - -</p> -<p> -The project uses the IPsec, ISAKMP/IKE, DNS and DNSSEC -protocols because they are -standardized, widely available and can often be deployed very easily -without changing hardware or software or retraining users. - -</p> -<p> -The extensions to support opportunistic encryption are simple. No -changes to any on-the-wire formats are needed. The only changes are to -the policy decision making system. This means that opportunistic -encryption can be implemented with very minimal changes to an existing -IPsec implementation. - -</p> -<p> -Opportunistic encryption creates a "fax effect". The proliferation -of the fax machine was possible because it did not require that everyone -buy one overnight. Instead, as each person installed one, the value -of having one increased - as there were more people that could receive faxes. -Once opportunistic encryption is installed it -automatically recognizes -other boxes using opportunistic encryption, without any further configuration -by the network -administrator. So, as opportunistic encryption software is installed on more -boxes, its value -as a tool increases. - -</p> -<p> -This document describes the infrastructure to permit deployment of -Opportunistic Encryption. - -</p> -<p> -The term S/WAN is a trademark of RSA Data Systems, and is used with permission -by this project. - -</p> -<a name="rfc.section.1.2"></a><h4><a name="anchor3">1.2</a> Types of network traffic</h4> - -<p> - To aid in understanding the relationship between security processing and IPsec - we divide network traffic into four categories: - -<blockquote class="text"><dl> -<dt>* Deny:</dt> -<dd> networks to which traffic is always forbidden. -</dd> -<dt>* Permit:</dt> -<dd> networks to which traffic in the clear is permitted. -</dd> -<dt>* Opportunistic tunnel:</dt> -<dd> networks to which traffic is encrypted if possible, but otherwise is in the clear - or fails depending on the default policy in place. - -</dd> -<dt>* Configured tunnel:</dt> -<dd> networks to which traffic must be encrypted, and traffic in the clear is never permitted. -</dd> -</dl></blockquote><p> -</p> -<p> -Traditional firewall devices handle the first two categories. No authentication is required. -The permit policy is currently the default on the Internet. - -</p> -<p> -This document describes the third category - opportunistic tunnel, which is -proposed as the new default for the Internet. - -</p> -<p> - Category four, encrypt traffic or drop it, requires authentication of the - end points. As the number of end points is typically bounded and is typically - under a single authority, arranging for distribution of - authentication material, while difficult, does not require any new - technology. The mechanism described here provides an additional way to - distribute the authentication materials, that of a public key method that does not - require deployment of an X.509 based infrastructure. - -</p> -<p> -Current Virtual Private Networks can often be replaced by an "OE paranoid" -policy as described herein. - -</p> -<a name="rfc.section.1.3"></a><h4><a name="anchor4">1.3</a> Peer authentication in opportunistic encryption</h4> - -<p> - Opportunistic encryption creates tunnels between nodes that - are essentially strangers. This is done without any prior bilateral - arrangement. - There is, therefore, the difficult question of how one knows to whom one is - talking. - -</p> -<p> - One possible answer is that since no useful - authentication can be done, none should be tried. This mode of operation is - named "anonymous encryption". An active man-in-the-middle attack can be - used to thwart the privacy of this type of communication. - Without peer authentication, there is no way to prevent this kind of attack. - -</p> -<p> -Although a useful mode, anonymous encryption is not the goal of this -project. Simpler methods are available that can achieve anonymous -encryption only, but authentication of the peer is a desireable goal. -The latter is achieved through key distribution in DNS, leveraging upon -the authentication of the DNS in DNSSEC. - -</p> -<p> - Peers are, therefore, authenticated with DNSSEC when available. Local policy -determines how much trust to extend when DNSSEC is not available. - -</p> -<p> - However, an essential premise of building private connections with - strangers is that datagrams received through opportunistic tunnels - are no more special than datagrams that arrive in the clear. - Unlike in a VPN, these datagrams should not be given any special - exceptions when it comes to auditing, further authentication or - firewalling. - -</p> -<p> - When initiating outbound opportunistic encryption, local - configuration determines what happens if tunnel setup fails. It may be that - the packet goes out in the clear, or it may be dropped. - -</p> -<a name="rfc.section.1.4"></a><h4><a name="anchor5">1.4</a> Use of RFC2119 terms</h4> - -<p> - The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, - SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL, when they appear in this - document, are to be interpreted as described in <a href="#RFC2119">[5]</a> -</p> -<a name="anchor6"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.2"></a><h3>2. Overview</h3> - -<a name="rfc.section.2.1"></a><h4><a name="anchor7">2.1</a> Reference diagram</h4> -<br><hr size="1" shade="0"> -<a name="networkdiagram"></a> - -<p>The following network diagram is used in the rest of - this document as the canonical diagram: -</p></font><pre> - [Q] [R] - . . AS2 - [A]----+----[SG-A].......+....+.......[SG-B]-------[B] - | ...... - AS1 | ..PI.. - | ...... - [D]----+----[SG-D].......+....+.......[C] AS3 - - - </pre><font face="verdana, helvetica, arial, sans-serif" size="2"> - -<p> -</p><table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Reference Network Diagram </b></font><br></td></tr></table><hr size="1" shade="0"> - -<p> - In this diagram, there are four end-nodes: A, B, C and D. - There are three gateways, SG-A, SG-B, SG-D. A, D, SG-A and SG-D are part - of the same administrative authority, AS1. SG-A and SG-D are on two different exit - paths from organization 1. SG-B/B is an independent organization, AS2. - Nodes Q and R are nodes on the Internet. PI is the Public - Internet ("The Wild"). - -</p> -<a name="rfc.section.2.2"></a><h4><a name="anchor8">2.2</a> Terminology</h4> - -<p> - The following terminology is used in this document: - -</p> -<blockquote class="text"><dl> -<dt>Security gateway:</dt> -<dd> a system that performs IPsec tunnel - mode encapsulation/decapsulation. [SG-x] in the diagram. -</dd> -<dt>Alice:</dt> -<dd> node [A] in the diagram. When an IP address is needed, this is 192.1.0.65. -</dd> -<dt>Bob:</dt> -<dd> node [B] in the diagram. When an IP address is needed, this is 192.2.0.66. -</dd> -<dt>Carol:</dt> -<dd> node [C] in the diagram. When an IP address is needed, this is 192.1.1.67. -</dd> -<dt>Dave:</dt> -<dd> node [D] in the diagram. When an IP address is needed, this is 192.3.0.68. -</dd> -<dt>SG-A:</dt> -<dd> Alice's security gateway. Internally it is 192.1.0.1, externally it is 192.1.1.4. -</dd> -<dt>SG-B:</dt> -<dd> Bob's security gateway. Internally it is 192.2.0.1, externally it is 192.1.1.5. -</dd> -<dt>SG-D:</dt> -<dd> Dave's security gateway. Also Alice's backup security gateway. Internally it is 192.3.0.1, externally it is 192.1.1.6. -</dd> -<dt>-</dt> -<dd> A single dash represents clear-text datagrams. -</dd> -<dt>=</dt> -<dd> An equals sign represents phase 2 (IPsec) cipher-text - datagrams. -</dd> -<dt>~</dt> -<dd> A single tilde represents clear-text phase 1 datagrams. -</dd> -<dt>#</dt> -<dd> A hash sign represents phase 1 (IKE) cipher-text - datagrams. -</dd> -<dt>.</dt> -<dd> A period represents an untrusted network of unknown - type. -</dd> -<dt>Configured tunnel:</dt> -<dd> a tunnel that - is directly and deliberately hand configured on participating gateways. - Configured tunnels are typically given a higher level of - trust than opportunistic tunnels. -</dd> -<dt>Road warrior tunnel:</dt> -<dd> a configured tunnel connecting one - node with a fixed IP address and one node with a variable IP address. - A road warrior (RW) connection must be initiated by the - variable node, since the fixed node cannot know the - current address for the road warrior. -</dd> -<dt>Anonymous encryption:</dt> -<dd> - the process of encrypting a session without any knowledge of who the - other parties are. No authentication of identities is done. -</dd> -<dt>Opportunistic encryption:</dt> -<dd> - the process of encrypting a session with authenticated knowledge of - who the other parties are. -</dd> -<dt>Lifetime:</dt> -<dd> - the period in seconds (bytes or datagrams) for which a security - association will remain alive before needing to be re-keyed. -</dd> -<dt>Lifespan:</dt> -<dd> - the effective time for which a security association remains useful. A - security association with a lifespan shorter than its lifetime would - be removed when no longer needed. A security association with a - lifespan longer than its lifetime would need to be re-keyed one or - more times. -</dd> -<dt>Phase 1 SA:</dt> -<dd> an ISAKMP/IKE security association sometimes - referred to as a keying channel. -</dd> -<dt>Phase 2 SA:</dt> -<dd> an IPsec security association. -</dd> -<dt>Tunnel:</dt> -<dd> another term for a set of phase 2 SA (one in each direction). -</dd> -<dt>NAT:</dt> -<dd> Network Address Translation - (see <a href="#RFC2663">[20]</a>). -</dd> -<dt>NAPT:</dt> -<dd> Network Address and Port Translation - (see <a href="#RFC2663">[20]</a>). -</dd> -<dt>AS:</dt> -<dd> an autonomous system (AS) is a group of systems (a network) that - are under the administrative control of a single organization. -</dd> -<dt>Default-free zone:</dt> -<dd> - a set of routers that maintain a complete set of routes to - all currently reachable destinations. Having such a list, these routers - never make use of a default route. A datagram with a destination address - not matching any route will be dropped by such a router. - -</dd> -</dl></blockquote><p> -<a name="rfc.section.2.3"></a><h4><a name="anchor9">2.3</a> Model of operation</h4> - -<p> -The opportunistic encryption security gateway (OE gateway) is a regular -gateway node as described in <a href="#RFC0791">[2]</a> section 2.4 and -<a href="#RFC1009">[3]</a> with the additional capabilities described here and -in <a href="#RFC2401">[7]</a>. -The algorithm described here provides a way to determine, for each datagram, -whether or not to encrypt and tunnel the datagram. Two important things -that must be determined are whether or not to encrypt and tunnel and, if -so, the destination address or name of the tunnel end point which should be used. - -</p> -<a name="rfc.section.2.3.1"></a><h4><a name="anchor10">2.3.1</a> Tunnel authorization</h4> - -<p> -The OE gateway determines whether or not to create a tunnel based on -the destination address of each packet. Upon receiving a packet with a destination -address not recently seen, the OE gateway performs a lookup in DNS for an -authorization resource record (see <a href="#TXT">Use of TXT delegation record</a>). The record is located using -the IP address to perform a search in the in-addr.arpa (IPv4) or ip6.arpa -(IPv6) maps. If an authorization record is found, the OE gateway -interprets this as a request for a tunnel to be formed. - -</p> -<a name="rfc.section.2.3.2"></a><h4><a name="anchor11">2.3.2</a> Tunnel end-point discovery</h4> - -<p> -The authorization resource record also provides the address or name of the tunnel -end point which should be used. - -</p> -<p> -The record may also provide the public RSA key of the tunnel end point -itself. This is provided for efficiency only. If the public RSA key is not -present, the OE gateway performs a second lookup to find a KEY -resource record for the end point address or name. - -</p> -<p> -Origin and integrity protection of the resource records is provided by -DNSSEC (<a href="#RFC2535">[16]</a>). <a href="#nodnssec">Restriction on unauthenticated TXT delegation records</a> -documents an optional restriction on the tunnel end point if DNSSEC signatures -are not available for the relevant records. - -</p> -<a name="rfc.section.2.3.3"></a><h4><a name="anchor12">2.3.3</a> Caching of authorization results</h4> - -<p> -The OE gateway maintains a cache, in the forwarding plane, of -source/destination pairs for which opportunistic encryption has been -attempted. This cache maintains a record of whether or not OE was -successful so that subsequent datagrams can be forwarded properly -without additional delay. - -</p> -<p> -Successful negotiation of OE instantiates a new security association. -Failure to negotiate OE results in creation of a -forwarding policy entry either to drop or transmit in the clear future -datagrams. This negative cache is necessary to avoid the possibly lengthy process of repeatedly looking -up the same information. - -</p> -<p> -The cache is timed out periodically, as described in <a href="#teardown">Renewal and teardown</a>. -This removes entries that are no longer -being used and permits the discovery of changes in authorization policy. - -</p> -<a name="anchor13"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.3"></a><h3>3. Specification</h3> - -<p> -The OE gateway is modeled to have a forwarding plane and a control -plane. A control channel, such as PF_KEY, connects the two planes. -(See <a href="#RFC2367">[6]</a>.) -The forwarding plane performs per datagram operations. The control plane -contains a keying -daemon, such as ISAKMP/IKE, and performs all authorization, peer authentication and -key derivation functions. - -</p> -<a name="rfc.section.3.1"></a><h4><a name="anchor14">3.1</a> Datagram state machine</h4> - -<p> -Let the OE gateway maintain a collection of objects -- a superset of the -security policy database (SPD) specified in <a href="#RFC2401">[7]</a>. For -each combination of source and destination address, an SPD -object exists in one of five following states. -Prior to forwarding each datagram, the -responder uses the source and destination addresses to pick an entry from the SPD. -The SPD then determines if and how the packet is forwarded. - -</p> -<a name="rfc.section.3.1.1"></a><h4><a name="anchor15">3.1.1</a> Non-existent policy</h4> - -<p> -If the responder does not find an entry, then this policy applies. -The responder creates an entry with an initial state of "hold policy" and requests -keying material from the keying daemon. The responder does not forward the datagram, -rather it attaches the datagram to the SPD entry as the "first" datagram and retains it -for eventual transmission in a new state. - - -</p> -<a name="rfc.section.3.1.2"></a><h4><a name="anchor16">3.1.2</a> Hold policy</h4> - -<p> -The responder requests keying material. If the interface to the keying -system is lossy (PF_KEY, for instance, can be), the implementation -SHOULD include a mechanism to retransmit the -keying request at a rate limited to less than 1 request per second. -The responder does not forward the datagram. It attaches the -datagram to the SPD entry as the "last" datagram where it is retained -for eventual transmission. If there is -a datagram already so stored, then that already stored datagram is discarded. - -</p> -<p> -Because the "first" datagram is probably a TCP SYN packet, the -responder retains the "first" datagram in an attempt to avoid waiting for a -TCP retransmit. The responder retains the "last" -datagram in deference to streaming protocols that find it useful to know -how much data has been lost. These are recommendations to -decrease latency. There are no operational requirements for this. - -</p> -<a name="rfc.section.3.1.3"></a><h4><a name="anchor17">3.1.3</a> Pass-through policy</h4> - -<p> -The responder forwards the datagram using the normal forwarding table. -The responder enters this state only by command from the keying daemon, -and upon entering this state, also forwards the "first" and "last" datagrams. - -</p> -<a name="rfc.section.3.1.4"></a><h4><a name="anchor18">3.1.4</a> Deny policy</h4> - -<p> -The responder discards the datagram. The responder enters this state only by -command -from the keying daemon, and upon entering this state, discards the "first" -and "last" datagrams. -Local administration decides if further datagrams cause ICMP messages -to be generated (i.e. ICMP Destination Unreachable, Communication -Administratively Prohibited. type=3, code=13). - -</p> -<a name="rfc.section.3.1.5"></a><h4><a name="anchor19">3.1.5</a> Encrypt policy</h4> - -<p> -The responder encrypts the datagram using the indicated security association database -(SAD) entry. The responder enters this state only by command from the keying daemon, and upon entering -this state, releases and forwards the "first" and "last" datagrams using the -new encrypt policy. - -</p> -<p> -If the associated SAD entry expires because of byte, packet or time limits, then -the entry returns to the Hold policy, and an expire message is sent to the keying daemon. - -</p> -<p> -All states may be created directly by the keying daemon while acting as a -responder. - -</p> -<a name="rfc.section.3.2"></a><h4><a name="initclasses">3.2</a> Keying state machine - initiator</h4> - -<p> -Let the keying daemon maintain a collection of objects. Let them be -called "connections" or "conn"s. There are two categories of -connection objects: classes and instances. A class represents an -abstract policy - what could be. An instance represents an actual connection - -what is implemented at the time. - -</p> -<p> -Let there be two further subtypes of connections: keying channels (Phase -1 SAs) and data channels (Phase 2 SAs). Each data channel object may have -a corresponding SPD and SAD entry maintained by the datagram state machine. - -</p> -<p> -For the purposes of opportunistic encryption, there MUST, at least, be -connection classes known as "deny", "always-clear-text", "OE-permissive", and -"OE-paranoid". -The latter two connection classes define a set of source and/or destination -addresses for which opportunistic encryption will be attempted. The administrator MAY set policy -options in a number of additional places. An implementation MAY create additional connection classes to further refine -these policies. - -</p> -<p> -The simplest system may need only the "OE-permissive" connection, and would -list its own (single) IP address as the source address of this policy and -the wild-card address 0.0.0.0/0 as the destination IPv4 address. That is, the -simplest policy is to try opportunistic encryption with all destinations. - -</p> -<p> -The distinction between permissive and paranoid OE use will become clear -in the state transition differences. In general a permissive OE will, on -failure, install a pass-through policy, while a paranoid OE will, on failure, -install a drop policy. - -</p> -<p> -In this description of the keying machine's state transitions, the states -associated with the keying system itself are omitted because they are best documented in the keying system -(<a href="#RFC2407">[8]</a>, -<a href="#RFC2408">[9]</a> and <a href="#RFC2409">[10]</a> for ISAKMP/IKE), -and the details are keying system specific. Opportunistic encryption is not -dependent upon any specific keying protocol, but this document does provide -requirements for those using ISAKMP/IKE to assure that implementations inter-operate. - -</p> -<p> -The state transitions that may be involved in communicating with the -forwarding plane are omitted. PF_KEY and similar protocols have their own -set of states required for message sends and completion notifications. - -</p> -<p> -Finally, the retransmits and recursive lookups that are normal for DNS are -not included in this description of the state machine. - -</p> -<a name="rfc.section.3.2.1"></a><h4><a name="anchor20">3.2.1</a> Nonexistent connection</h4> - -<p> -There is no connection instance for a given source/destination address pair. -Upon receipt of a request for keying material for this -source/destination pair, the initiator searches through the connection classes to -determine the most appropriate policy. Upon determining an appropriate -connection class, an instance object is created of that type. -Both of the OE types result in a potential OE connection. - -</p> -<p>Failure to find an appropriate connection class results in an -administrator defined default. - -</p> -<p> -In each case, when the initiator finds an appropriate class for the new flow, -an instance connection is made of the class which matched. - -</p> -<a name="rfc.section.3.2.2"></a><h4><a name="anchor21">3.2.2</a> Clear-text connection</h4> - -<p> -The non-existent connection makes a transition to this state when an -always-clear-text class is instantiated, or when an OE-permissive -connection fails. During the transition, the initiator creates a pass-through -policy object in the forwarding plane for the appropriate flow. - -</p> -<p> -Timing out is the only way to leave this state -(see <a href="#expiring">Expiring connection</a>). - -</p> -<a name="rfc.section.3.2.3"></a><h4><a name="anchor22">3.2.3</a> Deny connection</h4> - -<p> -The empty connection makes a transition to this state when a -deny class is instantiated, or when an OE-paranoid connection fails. -During the transition, the initiator creates a deny policy object in the forwarding plane -for the appropriate flow. - -</p> -<p> -Timing out is the only way to leave this state -(see <a href="#expiring">Expiring connection</a>). - -</p> -<a name="rfc.section.3.2.4"></a><h4><a name="anchor23">3.2.4</a> Potential OE connection</h4> - -<p> -The empty connection makes a transition to this state when one of either OE class is instantiated. -During the transition to this state, the initiator creates a hold policy object in the -forwarding plane for the appropriate flow. - -</p> -<p> -In addition, when making a transition into this state, DNS lookup is done in -the reverse-map for a TXT delegation resource record (see <a href="#TXT">Use of TXT delegation record</a>). -The lookup key is the destination address of the flow. - -</p> -<p> -There are three ways to exit this state: - -<ol class="text"> -<li>DNS lookup finds a TXT delegation resource record. -</li> -<li>DNS lookup does not find a TXT delegation resource record. -</li> -<li>DNS lookup times out. -</li> -</ol><p> -</p> -<p> -Based upon the results of the DNS lookup, the potential OE connection makes a -transition to the pending OE connection state. The conditions for a -successful DNS look are: - -<ol class="text"> -<li>DNS finds an appropriate resource record -</li> -<li>It is properly formatted according to <a href="#TXT">Use of TXT delegation record</a> -</li> -<li> if DNSSEC is enabled, then the signature has been vouched for. -</li> -</ol><p> - -Note that if the initiator does not find the public key -present in the TXT delegation record, then the public key must -be looked up as a sub-state. Only successful completion of all the -DNS lookups is considered a success. - -</p> -<p> -If DNS lookup does not find a resource record or DNS times out, then the -initiator considers the receiver not OE capable. If this is an OE-paranoid instance, -then the potential OE connection makes a transition to the deny connection state. -If this is an OE-permissive instance, then the potential OE connection makes a transition to the -clear-text connection state. - -</p> -<p> -If the initiator finds a resource record but it is not properly formatted, or -if DNSSEC is -enabled and reports a failure to authenticate, then the potential OE -connection should make a -transition to the deny connection state. This action SHOULD be logged. If the -administrator wishes to override this transition between states, then an -always-clear class can be installed for this flow. An implementation MAY make -this situation a new class. - -</p> -<a name="rfc.section.3.2.4.1"></a><h4><a name="nodnssec">3.2.4.1</a> Restriction on unauthenticated TXT delegation records</h4> - -<p> -An implementation SHOULD also provide an additional administrative control -on delegation records and DNSSEC. This control would apply to delegation -records (the TXT records in the reverse-map) that are not protected by -DNSSEC. -Records of this type are only permitted to delegate to their own address as -a gateway. When this option is enabled, an active attack on DNS will be -unable to redirect packets to other than the original destination. - -</p> -<a name="rfc.section.3.2.5"></a><h4><a name="anchor24">3.2.5</a> Pending OE connection</h4> - -<p> -The potential OE connection makes a transition to this state when -the initiator determines that all the information required from the DNS lookup is present. -Upon entering this state, the initiator attempts to initiate keying to the gateway -provided. - -</p> -<p> -Exit from this state occurs either with a successfully created IPsec SA, or -with a failure of some kind. Successful SA creation results in a transition -to the key connection state. - -</p> -<p> -Three failures have caused significant problems. They are clearly not the -only possible failures from keying. - -</p> -<p> -Note that if there are multiple gateways available in the TXT delegation -records, then a failure can only be declared after all have been -tried. Further, creation of a phase 1 SA does not constitute success. A set -of phase 2 SAs (a tunnel) is considered success. - -</p> -<p> -The first failure occurs when an ICMP port unreachable is consistently received -without any other communication, or when there is silence from the remote -end. This usually means that either the gateway is not alive, or the -keying daemon is not functional. For an OE-permissive connection, the initiator makes a transition -to the clear-text connection but with a low lifespan. For an OE-pessimistic connection, -the initiator makes a transition to the deny connection again with a low lifespan. The lifespan in both -cases is kept low because the remote gateway may -be in the process of rebooting or be otherwise temporarily unavailable. - -</p> -<p> -The length of time to wait for the remote keying daemon to wake up is -a matter of some debate. If there is a routing failure, 5 minutes is usually long enough for the network to -re-converge. Many systems can reboot in that amount of -time as well. However, 5 minutes is far too long for most users to wait to -hear that they can not connect using OE. Implementations SHOULD make this a -tunable parameter. - -</p> -<p> -The second failure occurs after a phase 1 SA has been created, but there is -either no response to the phase 2 proposal, or the initiator receives a -negative notify (the notify must be -authenticated). The remote gateway is not prepared to do OE at this time. -As before, the initiator makes a transition to the clear-text or the deny -connection based upon connection class, but this -time with a normal lifespan. - -</p> -<p> -The third failure occurs when there is signature failure while authenticating -the remote gateway. This can occur when there has been a -key roll-over, but DNS has not caught up. In this case again, the initiator makes a -transition to the clear-text or the deny connection based -upon the connection class. However, the lifespan depends upon the remaining -time to live in the DNS. (Note that DNSSEC signed resource records have a different -expiry time than non-signed records.) - -</p> -<a name="rfc.section.3.2.6"></a><h4><a name="keyed">3.2.6</a> Keyed connection</h4> - -<p> -The pending OE connection makes a transition to this state when -session keying material (the phase 2 SAs) is derived. The initiator creates an encrypt -policy in the forwarding plane for this flow. - -</p> -<p> -There are three ways to exit this state. The first is by receipt of an -authenticated delete message (via the keying channel) from the peer. This is -normal teardown and results in a transition to the expired connection state. - -</p> -<p> -The second exit is by expiry of the forwarding plane keying material. This -starts a re-key operation with a transition back to pending OE -connection. In general, the soft expiry occurs with sufficient time left -to continue to use the keys. A re-key can fail, which may -result in the connection failing to clear-text or deny as -appropriate. In the event of a failure, the forwarding plane -policy does not change until the phase 2 SA (IPsec SA) reaches its -hard expiry. - -</p> -<p> -The third exit is in response to a negotiation from a remote -gateway. If the forwarding plane signals the control plane that it has received an -unknown SPI from the remote gateway, or an ICMP is received from the remote gateway -indicating an unknown SPI, the initiator should consider that -the remote gateway has rebooted or restarted. Since these -indications are easily forged, the implementation must -exercise care. The initiator should make a cautious -(rate-limited) attempt to re-key the connection. - -</p> -<a name="rfc.section.3.2.7"></a><h4><a name="expiring">3.2.7</a> Expiring connection</h4> - -<p> -The initiator will periodically place each of the deny, clear-text, and keyed -connections into this -sub-state. See <a href="#teardown">Renewal and teardown</a> for more details of how often this -occurs. -The initiator queries the forwarding plane for last use time of the -appropriate -policy. If the last use time is relatively recent, then the connection -returns to the -previous deny, clear-text or keyed connection state. If not, then the -connection enters -the expired connection state. - -</p> -<p> -The DNS query and answer that lead to the expiring connection state are also -examined. The DNS query may become stale. (A negative, i.e. no such record, answer -is valid for the period of time given by the MINIMUM field in an attached SOA -record. See <a href="#RFC1034">[12]</a> section 4.3.4.) -If the DNS query is stale, then a new query is made. If the results change, then the connection -makes a transition to a new state as described in potential OE connection state. - -</p> -<p> -Note that when considering how stale a connection is, both outgoing SPD and -incoming SAD must be queried as some flows may be unidirectional for some time. - -</p> -<p> -Also note that the policy at the forwarding plane is not updated unless there -is a conclusion that there should be a change. - -</p> -<a name="rfc.section.3.2.8"></a><h4><a name="anchor25">3.2.8</a> Expired connection</h4> - -<p> -Entry to this state occurs when no datagrams have been forwarded recently via the -appropriate SPD and SAD objects. The objects in the forwarding plane are -removed (logging any final byte and packet counts if appropriate) and the -connection instance in the keying plane is deleted. - -</p> -<p> -The initiator sends an ISAKMP/IKE delete to clean up the phase 2 SAs as described in -<a href="#teardown">Renewal and teardown</a>. - -</p> -<p> -Whether or not to delete the phase 1 SAs -at this time is left as a local implementation issue. Implementations -that do delete the phase 1 SAs MUST send authenticated delete messages to -indicate that they are doing so. There is an advantage to keeping -the phase 1 SAs until they expire - they may prove useful again in the -near future. - -</p> -<a name="rfc.section.3.3"></a><h4><a name="anchor26">3.3</a> Keying state machine - responder</h4> - -<p> -The responder has a set of objects identical to those of the initiator. - -</p> -<p> -The responder receives an invitation to create a keying channel from an initiator. - -</p> -<a name="rfc.section.3.3.1"></a><h4><a name="anchor27">3.3.1</a> Unauthenticated OE peer</h4> - -<p> -Upon entering this state, the responder starts a DNS lookup for a KEY record for the -initiator. -The responder looks in the reverse-map for a KEY record for the initiator if the -initiator has offered an ID_IPV4_ADDR, and in the forward map if the -initiator has offered an ID_FQDN type. (See <a href="#RFC2407">[8]</a> section -4.6.2.1.) - -</p> -<p> -The responder exits this state upon successful receipt of a KEY from DNS, and use of the key -to verify the signature of the initiator. - -</p> -<p> -Successful authentication of the peer results in a transition to the -authenticated OE Peer state. - -</p> -<p> -Note that the unauthenticated OE peer state generally occurs in the middle of the key negotiation -protocol. It is really a form of pseudo-state. - -</p> -<a name="rfc.section.3.3.2"></a><h4><a name="anchor28">3.3.2</a> Authenticated OE Peer</h4> - -<p> -The peer will eventually propose one or more phase 2 SAs. The responder uses the source and -destination address in the proposal to -finish instantiating the connection state -using the connection class table. -The responder MUST search for an identical connection object at this point. - -</p> -<p> -If an identical connection is found, then the responder deletes the old instance, -and the new object makes a transition to the pending OE connection state. This means -that new ISAKMP connections with a given peer will always use the latest -instance, which is the correct one if the peer has rebooted in the interim. - -</p> -<p> -If an identical connection is not found, then the responder makes the transition according to the -rules given for the initiator. - -</p> -<p> -Note that if the initiator is in OE-paranoid mode and the responder is in -either always-clear-text or deny, then no communication is possible according -to policy. An implementation is permitted to create new types of policies -such as "accept OE but do not initiate it". This is a local matter. - -</p> -<a name="rfc.section.3.4"></a><h4><a name="teardown">3.4</a> Renewal and teardown</h4> - -<a name="rfc.section.3.4.1"></a><h4><a name="anchor29">3.4.1</a> Aging</h4> - -<p> -A potentially unlimited number of tunnels may exist. In practice, only a few -tunnels are used during a period of time. Unused tunnels MUST, therefore, be -torn down. Detecting when tunnels are no longer in use is the subject of this section. - -</p> -<p> -There are two methods for removing tunnels: explicit deletion or expiry. - -</p> -<p> -Explicit deletion requires an IKE delete message. As the deletes -MUST be authenticated, both ends of the tunnel must maintain the -key channel (phase 1 ISAKMP SA). An implementation which refuses to either maintain or -recreate the keying channel SA will be unable to use this method. - -</p> -<p> -The tunnel expiry method, simply allows the IKE daemon to -expire normally without attempting to re-key it. - -</p> -<p> -Regardless of which method is used to remove tunnels, the implementation requires -a method to determine if the tunnel is still in use. The specifics are a -local matter, but the FreeS/WAN project uses the following criteria. These -criteria are currently implemented in the key management daemon, but could -also be implemented at the SPD layer using an idle timer. - -</p> -<p> -Set a short initial (soft) lifespan of 1 minute since many net flows last -only a few seconds. - -</p> -<p> -At the end of the lifespan, check to see if the tunnel was used by -traffic in either direction during the last 30 seconds. If so, assign a -longer tentative lifespan of 20 minutes after which, look again. If the -tunnel is not in use, then close the tunnel. - -</p> -<p> -The expiring state in the key management -system (see <a href="#expiring">Expiring connection</a>) implements these timeouts. -The timer above may be in the forwarding plane, -but then it must be re-settable. - -</p> -<p> -The tentative lifespan is independent of re-keying; it is just the time when -the tunnel's future is next considered. -(The term lifespan is used here rather than lifetime for this reason.) -Unlike re-keying, this tunnel use check is not costly and should happen -reasonably frequently. - -</p> -<p> -A multi-step back-off algorithm is not considered worth the effort here. - -</p> -<p> -If the security gateway and the client host are the -same and not a Bump-in-the-Stack or Bump-in-the-Wire implementation, tunnel -teardown decisions MAY pay attention to TCP connection status as reported -by the local TCP layer. A still-open TCP connection is almost a guarantee that more traffic is -expected. Closing of the only TCP connection through a tunnel is a -strong hint that no more traffic is expected. - -</p> -<a name="rfc.section.3.4.2"></a><h4><a name="anchor30">3.4.2</a> Teardown and cleanup</h4> - -<p> -Teardown should always be coordinated between the two ends of the tunnel by -interpreting and sending delete notifications. There is a -detailed sub-state in the expired connection state of the key manager that -relates to retransmits of the delete notifications, but this is considered to -be a keying system detail. - -</p> -<p> -On receiving a delete for the outbound SAs of a tunnel (or some subset of -them), tear down the inbound ones also and notify the remote end with a -delete. If the local system receives a delete for a tunnel which is no longer in -existence, then two delete messages have crossed paths. Ignore the delete. -The operation has already been completed. Do not generate any messages in this -situation. - -</p> -<p> -Tunnels are to be considered as bidirectional entities, even though the -low-level protocols don't treat them this way. - -</p> -<p> -When the deletion is initiated locally, rather than as a -response to a received delete, send a delete for (all) the -inbound SAs of a tunnel. If the local system does not receive a responding delete -for the outbound SAs, try re-sending the original -delete. Three tries spaced 10 seconds apart seems a reasonable -level of effort. A failure of the other end to respond after 3 attempts, -indicates that the possibility of further communication is unlikely. Remove the outgoing SAs. -(The remote system may be a mobile node that is no longer present or powered on.) - -</p> -<p> -After re-keying, transmission should switch to using the new -outgoing SAs (ISAKMP or IPsec) immediately, and the old leftover -outgoing SAs should be cleared out promptly (delete should be sent -for the outgoing SAs) rather than waiting for them to expire. This -reduces clutter and minimizes confusion for the operator doing diagnostics. - -</p> -<a name="anchor31"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.4"></a><h3>4. Impacts on IKE</h3> - -<a name="rfc.section.4.1"></a><h4><a name="anchor32">4.1</a> ISAKMP/IKE protocol</h4> - -<p> - The IKE wire protocol needs no modifications. The major changes are - implementation issues relating to how the proposals are interpreted, and from - whom they may come. - -</p> -<p> - As opportunistic encryption is designed to be useful between peers without - prior operator configuration, an IKE daemon must be prepared to negotiate - phase 1 SAs with any node. This may require a large amount of resources to - maintain cookie state, as well as large amounts of entropy for nonces, - cookies and so on. - -</p> -<p> - The major changes to support opportunistic encryption are at the IKE daemon - level. These changes relate to handling of key acquisition requests, lookup - of public keys and TXT records, and interactions with firewalls and other - security facilities that may be co-resident on the same gateway. - -</p> -<a name="rfc.section.4.2"></a><h4><a name="anchor33">4.2</a> Gateway discovery process</h4> - -<p> - In a typical configured tunnel, the address of SG-B is provided - via configuration. Furthermore, the mapping of an SPD entry to a gateway is - typically a 1:1 mapping. When the 0.0.0.0/0 SPD entry technique is used, then - the mapping to a gateway is determined by the reverse DNS records. - -</p> -<p> - The need to do a DNS lookup and wait for a reply will typically introduce a - new state and a new event source (DNS replies) to IKE. Although a -synchronous DNS request can be implemented for proof of concept, experience -is that it can cause very high latencies when a queue of queries must -all timeout in series. - -</p> -<p> - Use of an asynchronous DNS lookup will also permit overlap of DNS lookups with - some of the protocol steps. - -</p> -<a name="rfc.section.4.3"></a><h4><a name="anchor34">4.3</a> Self identification</h4> - -<p> - SG-A will have to establish its identity. Use an - IPv4 ID in phase 1. - -</p> -<p> There are many situations where the administrator of SG-A may not be - able to control the reverse DNS records for SG-A's public IP address. - Typical situations include dialup connections and most residential-type broadband Internet access - (ADSL, cable-modem) connections. In these situations, a fully qualified domain - name that is under the control of SG-A's administrator may be used - when acting as an initiator only. - The FQDN ID should be used in phase 1. See <a href="#fqdn">Use of FQDN IDs</a> - for more details and restrictions. - -</p> -<a name="rfc.section.4.4"></a><h4><a name="anchor35">4.4</a> Public key retrieval process</h4> - -<p> - Upon receipt of a phase 1 SA proposal with either an IPv4 (IPv6) ID or - an FQDN ID, an IKE daemon needs to examine local caches and - configuration files to determine if this is part of a configured tunnel. - If no configured tunnels are found, then the implementation should attempt to retrieve - a KEY record from the reverse DNS in the case of an IPv4/IPv6 ID, or - from the forward DNS in the case of FQDN ID. - -</p> -<p> - It is reasonable that if other non-local sources of policy are used - (COPS, LDAP), they be consulted concurrently but some - clear ordering of policy be provided. Note that due to variances in - latency, implementations must wait for positive or negative replies from all sources - of policy before making any decisions. - -</p> -<a name="rfc.section.4.5"></a><h4><a name="anchor36">4.5</a> Interactions with DNSSEC</h4> - -<p> - The implementation described (1.98) neither uses DNSSEC directly to - explicitly verify the authenticity of zone information, nor uses the NXT - records to provide authentication of the absence of a TXT or KEY - record. Rather, this implementation uses a trusted path to a DNSSEC - capable caching resolver. - -</p> -<p> - To distinguish between an authenticated and an unauthenticated DNS - resource record, a stub resolver capable of returning DNSSEC - information MUST be used. - -</p> -<a name="rfc.section.4.6"></a><h4><a name="anchor37">4.6</a> Required proposal types</h4> - -<a name="rfc.section.4.6.1"></a><h4><a name="phase1id">4.6.1</a> Phase 1 parameters</h4> - -<p> - Main mode MUST be used. - -</p> -<p> - The initiator MUST offer at least one proposal using some combination - of: 3DES, HMAC-MD5 or HMAC-SHA1, DH group 2 or 5. Group 5 SHOULD be - proposed first. - <a href="#RFC3526">[11]</a> -</p> -<p> - The initiator MAY offer additional proposals, but the cipher MUST not - be weaker than 3DES. The initiator SHOULD limit the number of proposals - such that the IKE datagrams do not need to be fragmented. - -</p> -<p> - The responder MUST accept one of the proposals. If any configuration - of the responder is required then the responder is not acting in an - opportunistic way. - -</p> -<p> - SG-A SHOULD use an ID_IPV4_ADDR (ID_IPV6_ADDR for IPv6) of the external - interface of SG-A for phase 1. (There is an exception, see <a href="#fqdn">Use of FQDN IDs</a>.) The authentication method MUST be RSA public key signatures. - The RSA key for SG-A SHOULD be placed into a DNS KEY record in - the reverse space of SG-A (i.e. using in-addr.arpa). - -</p> -<a name="rfc.section.4.6.2"></a><h4><a name="phase2id">4.6.2</a> Phase 2 parameters</h4> - -<p> - SG-A MUST propose a tunnel between Alice and Bob, using 3DES-CBC - mode, MD5 or SHA1 authentication. Perfect Forward Secrecy MUST be specified. - -</p> -<p> - Tunnel mode MUST be used. - -</p> -<p> - Identities MUST be ID_IPV4_ADDR_SUBNET with the mask being /32. - -</p> -<p> - Authorization for SG-A to act on Alice's behalf is determined by - looking for a TXT record in the reverse-map at Alice's address. - -</p> -<p> - Compression SHOULD NOT be mandatory. It may be offered as an option. - -</p> -<a name="anchor38"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.5"></a><h3>5. DNS issues</h3> - -<a name="rfc.section.5.1"></a><h4><a name="KEY">5.1</a> Use of KEY record</h4> - -<p> - In order to establish their own identities, SG-A and SG-B SHOULD publish - their public keys in their reverse DNS via - DNSSEC's KEY record. - See section 3 of <a href="#RFC2535">RFC 2535</a>[16]. - -</p> -<p> -<p>For example: -</p></font><pre> -KEY 0x4200 4 1 AQNJjkKlIk9...nYyUkKK8 -</pre><font face="verdana, helvetica, arial, sans-serif" size="2"> - -<blockquote class="text"><dl> -<dt>0x4200:</dt> -<dd> The flag bits, indicating that this key is prohibited - for confidentiality use (it authenticates the peer only, a separate - Diffie-Hellman exchange is used for - confidentiality), and that this key is associated with the non-zone entity - whose name is the RR owner name. No other flags are set. -</dd> -<dt>4:</dt> -<dd>This indicates that this key is for use by IPsec. -</dd> -<dt>1:</dt> -<dd>An RSA key is present. -</dd> -<dt>AQNJjkKlIk9...nYyUkKK8:</dt> -<dd>The public key of the host as described in <a href="#RFC3110">[17]</a>. -</dd> -</dl></blockquote><p> -</p> -<p>Use of several KEY records allows for key rollover. The SIG Payload in - IKE phase 1 SHOULD be accepted if the public key given by any KEY RR - validates it. - -</p> -<a name="rfc.section.5.2"></a><h4><a name="TXT">5.2</a> Use of TXT delegation record</h4> - -<p> -Alice publishes a TXT record to provide authorization for SG-A to act on -Alice's behalf. - -Bob publishes a TXT record to provide authorization for SG-B to act on Bob's -behalf. - -These records are located in the reverse DNS (in-addr.arpa) for their -respective IP addresses. The reverse DNS SHOULD be secured by DNSSEC, when -it is deployed. DNSSEC is required to defend against active attacks. - -</p> -<p> - If Alice's address is P.Q.R.S, then she can authorize another node to - act on her behalf by publishing records at: - </p> -</font><pre> -S.R.Q.P.in-addr.arpa - </pre><font face="verdana, helvetica, arial, sans-serif" size="2"> -<p> - -</p> -<p> - The contents of the resource record are expected to be a string that - uses the following syntax, as suggested in <a href="#RFC1464">[15]</a>. - (Note that the reply to query may include other TXT resource - records used by other applications.) - - <br><hr size="1" shade="0"> -<a name="txtformat"></a> -</p> -</font><pre> -X-IPsec-Server(P)=A.B.C.D KEY - </pre><font face="verdana, helvetica, arial, sans-serif" size="2"> -<p> -<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Format of reverse delegation record </b></font><br></td></tr></table><hr size="1" shade="0"> - -</p> -<blockquote class="text"><dl> -<dt>P:</dt> -<dd> Specifies a precedence for this record. This is - similar to MX record preferences. Lower numbers have stronger - preference. - -</dd> -<dt>A.B.C.D:</dt> -<dd> Specifies the IP address of the Security Gateway - for this client machine. - -</dd> -<dt>KEY:</dt> -<dd> Is the encoded RSA Public key of the Security - Gateway. The key is provided here to avoid a second DNS lookup. If this - field is absent, then a KEY resource record should be looked up in the - reverse-map of A.B.C.D. The key is transmitted in base64 format. - -</dd> -</dl></blockquote><p> -<p> - The pieces of the record are separated by any whitespace - (space, tab, newline, carriage return). An ASCII space SHOULD - be used. - -</p> -<p> - In the case where Alice is located at a public address behind a - security gateway that has no fixed address (or no control over its - reverse-map), then Alice may delegate to a public key by domain name. - - <br><hr size="1" shade="0"> -<a name="txtfqdnformat"></a> -</p> -</font><pre> -X-IPsec-Server(P)=@FQDN KEY - </pre><font face="verdana, helvetica, arial, sans-serif" size="2"> -<p> -<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Format of reverse delegation record (FQDN version) </b></font><br></td></tr></table><hr size="1" shade="0"> - -</p> -<blockquote class="text"><dl> -<dt>P:</dt> -<dd> Is as above. - -</dd> -<dt>FQDN:</dt> -<dd> Specifies the FQDN that the Security Gateway - will identify itself with. - -</dd> -<dt>KEY:</dt> -<dd> Is the encoded RSA Public key of the Security - Gateway. -</dd> -</dl></blockquote><p> -<p> - If there is more than one such TXT record with strongest (lowest - numbered) precedence, one Security Gateway is picked arbitrarily from - those specified in the strongest-preference records. - -</p> -<a name="rfc.section.5.2.1"></a><h4><a name="anchor39">5.2.1</a> Long TXT records</h4> - -<p> - When packed into transport format, TXT records which are longer than 255 - characters are divided into smaller <character-strings>. - (See <a href="#RFC1035">[13]</a> section 3.3 and 3.3.14.) These MUST - be reassembled into a single string for processing. - Whitespace characters in the base64 encoding are to be ignored. - -</p> -<a name="rfc.section.5.2.2"></a><h4><a name="anchor40">5.2.2</a> Choice of TXT record</h4> - -<p> - It has been suggested to use the KEY, OPT, CERT, or KX records - instead of a TXT record. None is satisfactory. - -</p> -<p> The KEY RR has a protocol field which could be used to indicate a new protocol, -and an algorithm field which could be used to - indicate different contents in the key data. However, the KEY record - is clearly not intended for storing what are really authorizations, - it is just for identities. Other uses have been discouraged. - -</p> -<p> OPT resource records, as defined in <a href="#RFC2671">[14]</a> are not - intended to be used for storage of information. They are not to be loaded, - cached or forwarded. They are, therefore, inappropriate for use here. - -</p> -<p> - CERT records <a href="#RFC2538">[18]</a> can encode almost any set of - information. A custom type code could be used permitting any suitable - encoding to be stored, not just X.509. According to - the RFC, the certificate RRs are to be signed internally which may add undesirable -and unnecessary bulk. Larger DNS records may require TCP instead of UDP transfers. - -</p> -<p> - At the time of protocol design, the CERT RR was not widely deployed and - could not be counted upon. Use of CERT records will be investigated, - and may be proposed in a future revision of this document. - -</p> -<p> - KX records are ideally suited for use instead of TXT records, but had not been deployed at - the time of implementation. - -</p> -<a name="rfc.section.5.3"></a><h4><a name="fqdn">5.3</a> Use of FQDN IDs</h4> - -<p> - Unfortunately, not every administrator has control over the contents - of the reverse-map. Where the initiator (SG-A) has no suitable reverse-map, the - authorization record present in the reverse-map of Alice may refer to a - FQDN instead of an IP address. - -</p> -<p> - In this case, the client's TXT record gives the fully qualified domain - name (FQDN) in place of its security gateway's IP address. - The initiator should use the ID_FQDN ID-payload in phase 1. - A forward lookup for a KEY record on the FQDN must yield the - initiator's public key. - -</p> -<p> - This method can also be used when the external address of SG-A is - dynamic. - -</p> -<p> - If SG-A is acting on behalf of Alice, then Alice must still delegate - authority for SG-A to do so in her reverse-map. When Alice and SG-A - are one and the same (i.e. Alice is acting as an end-node) then there - is no need for this when initiating only. -</p> -<p>However, Alice must still delegate to herself if she wishes others to - initiate OE to her. See <a href="#txtfqdnformat">Format of reverse delegation record (FQDN version)</a>. - -</p> -<a name="rfc.section.5.4"></a><h4><a name="anchor41">5.4</a> Key roll-over</h4> - -<p> -Good cryptographic hygiene says that one should replace public/private key pairs -periodically. Some administrators may wish to do this as often as daily. Typical DNS -propagation delays are determined by the SOA Resource Record MINIMUM -parameter, which controls how long DNS replies may be cached. For reasonable -operation of DNS servers, administrators usually want this value to be at least several -hours, sometimes as a long as a day. This presents a problem - a new key MUST -not be used prior to it propagating through DNS. - -</p> -<p> -This problem is dealt with by having the Security Gateway generate a new -public/private key pair at least MINIMUM seconds in advance of using it. It -then adds this key to the DNS (both as a second KEY record and in additional TXT -delegation records) at key generation time. Note: only one key is allowed in -each TXT record. - -</p> -<p> -When authenticating, all gateways MUST have available all public keys -that are found in DNS for this entity. This permits the authenticating end -to check both the key for "today" and the key for "tomorrow". Note that it is -the end which is creating the signature (possesses the private key) that -determines which key is to be used. - -</p> -<a name="anchor42"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.6"></a><h3>6. Network address translation interaction</h3> - -<p> - There are no fundamentally new issues for implementing opportunistic encryption - in the presence of network address translation. Rather there are - only the regular IPsec issues with NAT traversal. - -</p> -<p> - There are several situations to consider for NAT. - -</p> -<a name="rfc.section.6.1"></a><h4><a name="anchor43">6.1</a> Co-located NAT/NAPT</h4> - -<p> - If SG-A is also performing network address translation on - behalf of Alice, then the packet should be translated prior to - being subjected to opportunistic encryption. This is in contrast to - typically configured tunnels which often exist to bridge islands of - private network address space. SG-A will use the translated source - address for phase 2, and so SG-B will look up that address to - confirm SG-A's authorization. - -</p> -<p> In the case of NAT (1:1), the address space into which the - translation is done MUST be globally unique, and control over the - reverse-map is assumed. - Placing of TXT records is possible. - -</p> -<p> In the case of NAPT (m:1), the address will be SG-A. The ability to get - KEY and TXT records in place will again depend upon whether or not - there is administrative control over the reverse-map. This is - identical to situations involving a single host acting on behalf of - itself. - - FQDN style can be used to get around a lack of a reverse-map for - initiators only. - -</p> -<a name="rfc.section.6.2"></a><h4><a name="anchor44">6.2</a> SG-A behind NAT/NAPT</h4> - -<p> - If there is a NAT or NAPT between SG-A and SG-B, then normal IPsec - NAT traversal rules apply. In addition to the transport problem - which may be solved by other mechanisms, there - is the issue of what phase 1 and phase 2 IDs to use. While FQDN could - be used during phase 1 for SG-A, there is no appropriate ID for phase 2 - that permits SG-B to determine that SG-A is in fact authorized to speak for Alice. - -</p> -<a name="rfc.section.6.3"></a><h4><a name="anchor45">6.3</a> Bob is behind a NAT/NAPT</h4> - -<p> - If Bob is behind a NAT (perhaps SG-B), then there is, in fact, no way for - Alice to address a packet to Bob. Not only is opportunistic encryption - impossible, but it is also impossible for Alice to initiate any - communication to Bob. It may be possible for Bob to initiate in such - a situation. This creates an asymmetry, but this is common for - NAPT. - -</p> -<a name="anchor46"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.7"></a><h3>7. Host implementations</h3> - -<p> - When Alice and SG-A are components of the same system, they are - considered to be a host implementation. The packet sequence scenario remains unchanged. - -</p> -<p> - Components marked Alice are the upper layers (TCP, UDP, the - application), and SG-A is the IP layer. - -</p> -<p> - Note that tunnel mode is still required. - -</p> -<p> - As Alice and SG-A are acting on behalf of themselves, no TXT based delegation - record is necessary for Alice to initiate. She can rely on FQDN in a - forward map. This is particularly attractive to mobile nodes such as - notebook computers at conferences. - To respond, Alice/SG-A will still need an entry in Alice's reverse-map. - -</p> -<a name="anchor47"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.8"></a><h3>8. Multi-homing</h3> - -<p> -If there are multiple paths between Alice and Bob (as illustrated in -the diagram with SG-D), then additional DNS records are required to establish -authorization. - -</p> -<p> -In <a href="#networkdiagram">Reference Network Diagram</a>, Alice has two ways to -exit her network: SG-A and SG-D. Previously SG-D has been ignored. Postulate -that there are routers between Alice and her set of security gateways -(denoted by the + signs and the marking of an autonomous system number for -Alice's network). Datagrams may, therefore, travel to either SG-A or SG-D en -route to Bob. - -</p> -<p> -As long as all network connections are in good order, it does not matter how -datagrams exit Alice's network. When they reach either security gateway, the -security gateway will find the TXT delegation record in Bob's reverse-map, -and establish an SA with SG-B. - -</p> -<p> -SG-B has no problem establishing that either of SG-A or SG-D may speak for -Alice, because Alice has published two equally weighted TXT delegation records: - <br><hr size="1" shade="0"> -<a name="txtmultiexample"></a> -</p> -</font><pre> -X-IPsec-Server(10)=192.1.1.5 AQMM...3s1Q== -X-IPsec-Server(10)=192.1.1.6 AAJN...j8r9== - </pre><font face="verdana, helvetica, arial, sans-serif" size="2"> -<p> -<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Multiple gateway delegation example for Alice </b></font><br></td></tr></table><hr size="1" shade="0"> - -</p> -<p> -Alice's routers can now do any kind of load sharing needed. Both SG-A and SG-D send datagrams addressed to Bob through -their tunnel to SG-B. - -</p> -<p> -Alice's use of non-equal weight delegation records to show preference of one gateway over another, has relevance only when SG-B -is initiating to Alice. - -</p> -<p> -If the precedences are the same, then SG-B has a more difficult time. It -must decide which of the two tunnels to use. SG-B has no information about -which link is less loaded, nor which security gateway has more cryptographic -resources available. SG-B, in fact, has no knowledge of whether both gateways -are even reachable. - -</p> -<p> -The Public Internet's default-free zone may well know a good route to Alice, -but the datagrams that SG-B creates must be addressed to either SG-A or SG-D; -they can not be addressed to Alice directly. - -</p> -<p> -SG-B may make a number of choices: - -<ol class="text"> -<li>It can ignore the problem and round robin among the tunnels. This - causes losses during times when one or the other security gateway is - unreachable. If this worries Alice, she can change the weights in her - TXT delegation records. -</li> -<li>It can send to the gateway from which it most recently received datagrams. - This assumes that routing and reachability are symmetrical. -</li> -<li>It can listen to BGP information from the Internet to decide which - system is currently up. This is clearly much more complicated, but if SG-B is already participating - in the BGP peering system to announce Bob, the results data may already - be available to it. -</li> -<li>It can refuse to negotiate the second tunnel. (It is unclear whether or -not this is even an option.) -</li> -<li>It can silently replace the outgoing portion of the first tunnel with the -second one while still retaining the incoming portions of both. SG-B can, -thus, accept datagrams from either SG-A or SG-D, but -send only to the gateway that most recently re-keyed with it. -</li> -</ol><p> -</p> -<p> -Local policy determines which choice SG-B makes. Note that even if SG-B has perfect -knowledge about the reachability of SG-A and SG-D, Alice may not be reachable -from either of these security gateways because of internal reachability -issues. - -</p> -<p> -FreeS/WAN implements option 5. Implementing a different option is -being considered. The multi-homing aspects of OE are not well developed and may -be the subject of a future document. - -</p> -<a name="anchor48"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.9"></a><h3>9. Failure modes</h3> - -<a name="rfc.section.9.1"></a><h4><a name="anchor49">9.1</a> DNS failures</h4> - -<p> - If a DNS server fails to respond, local policy decides - whether or not to permit communication in the clear as embodied in - the connection classes in <a href="#initclasses">Keying state machine - initiator</a>. - It is easy to mount a denial of service attack on the DNS server - responsible for a particular network's reverse-map. - Such an attack may cause all communication with that network to go in - the clear if the policy is permissive, or fail completely - if the policy is paranoid. Please note that this is an active attack. - -</p> -<p> - There are still many networks - that do not have properly configured reverse-maps. Further, if the policy is not to communicate, - the above denial of service attack isolates the target network. Therefore, the decision of whether -or not to permit communication in the clear MUST be a matter of local policy. - -</p> -<a name="rfc.section.9.2"></a><h4><a name="anchor50">9.2</a> DNS configured, IKE failures</h4> - -<p> - DNS records claim that opportunistic encryption should - occur, but the target gateway either does not respond on port 500, or - refuses the proposal. This may be because of a crash or reboot, a - faulty configuration, or a firewall filtering port 500. - -</p> -<p> - The receipt of ICMP port, host or network unreachable - messages indicates a potential problem, but MUST NOT cause communication - to fail - immediately. ICMP messages are easily forged by attackers. If such a - forgery caused immediate failure, then an active attacker could easily - prevent any - encryption from ever occurring, possibly preventing all communication. - -</p> -<p> - In these situations a clear log should be produced - and local policy should dictate if communication is then - permitted in the clear. - -</p> -<a name="rfc.section.9.3"></a><h4><a name="anchor51">9.3</a> System reboots</h4> - -<p> -Tunnels sometimes go down because the remote end crashes, -disconnects, or has a network link break. In general there is no -notification of this. Even in the event of a crash and successful reboot, -other SGs don't hear about it unless the rebooted SG has specific -reason to talk to them immediately. Over-quick response to temporary -network outages is undesirable. Note that a tunnel can be torn -down and then re-established without any effect visible to the user -except a pause in traffic. On the other hand, if one end reboots, -the other end can't get datagrams to it at all (except via -IKE) until the situation is noticed. So a bias toward quick -response is appropriate even at the cost of occasional -false alarms. - -</p> -<p> -A mechanism for recovery after reboot is a topic of current research and is not specified in this -document. - -</p> -<p> -A deliberate shutdown should include an attempt, using deletes, to notify all other SGs -currently connected by phase 1 SAs that communication is -about to fail. Again, a remote SG will assume this is a teardown. Attempts by the -remote SGs to negotiate new tunnels as replacements should be ignored. When possible, -SGs should attempt to preserve information about currently-connected SGs in non-volatile storage, so -that after a crash, an Initial-Contact can be sent to previous partners to -indicate loss of all previously established connections. - -</p> -<a name="anchor52"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.10"></a><h3>10. Unresolved issues</h3> - -<a name="rfc.section.10.1"></a><h4><a name="anchor53">10.1</a> Control of reverse DNS</h4> - -<p> - The method of obtaining information by reverse DNS lookup causes - problems for people who cannot control their reverse DNS - bindings. This is an unresolved problem in this version, and is out - of scope. - -</p> -<a name="anchor54"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.11"></a><h3>11. Examples</h3> - -<a name="rfc.section.11.1"></a><h4><a name="anchor55">11.1</a> Clear-text usage (permit policy)</h4> - -<p> -Two example scenarios follow. In the first example GW-A -(Gateway A) and GW-B (Gateway B) have always-clear-text policies, and in the second example they have an OE -policy. - -</p><br><hr size="1" shade="0"> -<a name="regulartiming"></a> -</font><pre> - Alice SG-A DNS SG-B Bob - (1) - ------(2)--------------> - <-----(3)--------------- - (4)----(5)-----> - ----------(6)------> - ------(7)-----> - <------(8)------ - <----------(9)------ - <----(10)----- - (11)-----------> - ----------(12)-----> - --------------> - <--------------- - <------------------- - <------------- - </pre><font face="verdana, helvetica, arial, sans-serif" size="2"> -<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Timing of regular transaction </b></font><br></td></tr></table><hr size="1" shade="0"> - -<p> -Alice wants to communicate with Bob. Perhaps she wants to retrieve a -web page from Bob's web server. In the absence of opportunistic -encryptors, the following events occur: - -<blockquote class="text"><dl> -<dt>(1)</dt> -<dd>Human or application 'clicks' with a name. -</dd> -<dt>(2)</dt> -<dd>Application looks up name in DNS to get IP address. -</dd> -<dt>(3)</dt> -<dd>Resolver returns A record to application. -</dd> -<dt>(4)</dt> -<dd>Application starts a TCP session or UDP session and OS sends datagram. -</dd> -<dt>(5)</dt> -<dd>Datagram is seen at first gateway from Alice (SG-A). (SG-A -makes a transition through Empty connection to always-clear connection and -instantiates a pass-through policy at the forwarding plane.) -</dd> -<dt>(6)</dt> -<dd>Datagram is seen at last gateway before Bob (SG-B). -</dd> -<dt>(7)</dt> -<dd>First datagram from Alice is seen by Bob. -</dd> -<dt>(8)</dt> -<dd>First return datagram is sent by Bob. -</dd> -<dt>(9)</dt> -<dd>Datagram is seen at Bob's gateway. (SG-B makes a transition through -Empty connection to always-clear connection and instantiates a pass-through -policy at the forwarding plane.) -</dd> -<dt>(10)</dt> -<dd>Datagram is seen at Alice's gateway. -</dd> -<dt>(11)</dt> -<dd>OS hands datagram to application. Alice sends another datagram. -</dd> -<dt>(12)</dt> -<dd>A second datagram traverses the Internet. -</dd> -</dl></blockquote><p> -</p> -<a name="rfc.section.11.2"></a><h4><a name="anchor56">11.2</a> Opportunistic encryption</h4> - -<p> -In the presence of properly configured opportunistic encryptors, the -event list is extended. - -<br><hr size="1" shade="0"> -<a name="opportunistictiming"></a> -</p> -</font><pre> - Alice SG-A DNS SG-B Bob - (1) - ------(2)--------------> - <-----(3)--------------- - (4)----(5)----->+ - ----(5B)-> - <---(5C)-- - ~~~~~~~~~~~~~(5D)~~~> - <~~~~~~~~~~~~(5E1)~~~ - ~~~~~~~~~~~~~(5E2)~~> - <~~~~~~~~~~~~(5E3)~~~ - #############(5E4)##> - <############(5E5)### - <----(5F1)-- - -----(5F2)-> - #############(5G1)##> - <----(5H1)-- - -----(5H2)-> - <############(5G2)### - #############(5G3)##> - ============(6)====> - ------(7)-----> - <------(8)------ - <==========(9)====== - <-----(10)---- - (11)-----------> - ==========(12)=====> - --------------> - <--------------- - <=================== - <------------- - </pre><font face="verdana, helvetica, arial, sans-serif" size="2"> -<p> -<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Timing of opportunistic encryption transaction </b></font><br></td></tr></table><hr size="1" shade="0"> - -<blockquote class="text"><dl> -<dt>(1)</dt> -<dd>Human or application clicks with a name. -</dd> -<dt>(2)</dt> -<dd>Application initiates DNS mapping. -</dd> -<dt>(3)</dt> -<dd>Resolver returns A record to application. -</dd> -<dt>(4)</dt> -<dd>Application starts a TCP session or UDP. -</dd> -<dt>(5)</dt> -<dd>SG-A (host or SG) sees datagram to target, and buffers it. -</dd> -<dt>(5B)</dt> -<dd>SG-A asks DNS for TXT record. -</dd> -<dt>(5C)</dt> -<dd>DNS returns TXT record(s). -</dd> -<dt>(5D)</dt> -<dd>Initial IKE Main Mode Packet goes out. -</dd> -<dt>(5E)</dt> -<dd>IKE ISAKMP phase 1 succeeds. -</dd> -<dt>(5F)</dt> -<dd>SG-B asks DNS for TXT record to prove SG-A is an agent for Alice. -</dd> -<dt>(5G)</dt> -<dd>IKE phase 2 negotiation. -</dd> -<dt>(5H)</dt> -<dd>DNS lookup by responder (SG-B). -</dd> -<dt>(6)</dt> -<dd>Buffered datagram is sent by SG-A. -</dd> -<dt>(7)</dt> -<dd>Datagram is received by SG-B, decrypted, and sent to Bob. -</dd> -<dt>(8)</dt> -<dd>Bob replies, and datagram is seen by SG-B. -</dd> -<dt>(9)</dt> -<dd>SG-B already has tunnel up with SG-A, and uses it. -</dd> -<dt>(10)</dt> -<dd>SG-A decrypts datagram and gives it to Alice. -</dd> -<dt>(11)</dt> -<dd>Alice receives datagram. Sends new packet to Bob. -</dd> -<dt>(12)</dt> -<dd>SG-A gets second datagram, sees that tunnel is up, and uses it. -</dd> -</dl></blockquote><p> -</p> -<p> - For the purposes of this section, we will describe only the changes that - occur between <a href="#regulartiming">Timing of regular transaction</a> and - <a href="#opportunistictiming">Timing of opportunistic encryption transaction</a>. This corresponds to time points 5, 6, 7, 9 and 10 on the list above. - -</p> -<a name="rfc.section.11.2.1"></a><h4><a name="anchor57">11.2.1</a> (5) IPsec datagram interception</h4> - -<p> - At point (5), SG-A intercepts the datagram because this source/destination pair lacks a policy -(the non-existent policy state). SG-A creates a hold policy, and buffers the datagram. SG-A requests keys from the keying daemon. - -</p> -<a name="rfc.section.11.2.2"></a><h4><a name="anchor58">11.2.2</a> (5B) DNS lookup for TXT record</h4> - -<p> - SG-A's IKE daemon, having looked up the source/destination pair in the connection - class list, creates a new Potential OE connection instance. SG-A starts DNS - queries. - -</p> -<a name="rfc.section.11.2.3"></a><h4><a name="anchor59">11.2.3</a> (5C) DNS returns TXT record(s)</h4> - -<p> - DNS returns properly formed TXT delegation records, and SG-A's IKE daemon - causes this instance to make a transition from Potential OE connection to Pending OE - connection. - -</p> -<p> - Using the example above, the returned record might contain: - - <br><hr size="1" shade="0"> -<a name="txtexample"></a> -</p> -</font><pre> -X-IPsec-Server(10)=192.1.1.5 AQMM...3s1Q== - </pre><font face="verdana, helvetica, arial, sans-serif" size="2"> -<p> -<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Example of reverse delegation record for Bob </b></font><br></td></tr></table><hr size="1" shade="0"> - - with SG-B's IP address and public key listed. - -</p> -<a name="rfc.section.11.2.4"></a><h4><a name="anchor60">11.2.4</a> (5D) Initial IKE main mode packet goes out</h4> - -<p>Upon entering Pending OE connection, SG-A sends the initial ISAKMP - message with proposals. See <a href="#phase1id">Phase 1 parameters</a>. - -</p> -<a name="rfc.section.11.2.5"></a><h4><a name="anchor61">11.2.5</a> (5E1) Message 2 of phase 1 exchange</h4> - -<p> - SG-B receives the message. A new connection instance is created in the - unauthenticated OE peer state. - -</p> -<a name="rfc.section.11.2.6"></a><h4><a name="anchor62">11.2.6</a> (5E2) Message 3 of phase 1 exchange</h4> - -<p> - SG-A sends a Diffie-Hellman exponent. This is an internal state of the - keying daemon. - -</p> -<a name="rfc.section.11.2.7"></a><h4><a name="anchor63">11.2.7</a> (5E3) Message 4 of phase 1 exchange</h4> - -<p> - SG-B responds with a Diffie-Hellman exponent. This is an internal state of the - keying protocol. - -</p> -<a name="rfc.section.11.2.8"></a><h4><a name="anchor64">11.2.8</a> (5E4) Message 5 of phase 1 exchange</h4> - -<p> - SG-A uses the phase 1 SA to send its identity under encryption. - The choice of identity is discussed in <a href="#phase1id">Phase 1 parameters</a>. - This is an internal state of the keying protocol. - -</p> -<a name="rfc.section.11.2.9"></a><h4><a name="anchor65">11.2.9</a> (5F1) Responder lookup of initiator key</h4> - -<p> - SG-B asks DNS for the public key of the initiator. - DNS looks for a KEY record by IP address in the reverse-map. - That is, a KEY resource record is queried for 4.1.1.192.in-addr.arpa - (recall that SG-A's external address is 192.1.1.4). - SG-B uses the resulting public key to authenticate the initiator. See <a href="#KEY">Use of KEY record</a> for further details. - -</p> -<a name="rfc.section.11.2.10"></a><h4><a name="anchor66">11.2.10</a> (5F2) DNS replies with public key of initiator</h4> - -<p> -Upon successfully authenticating the peer, the connection instance makes a -transition to authenticated OE peer on SG-B. - -</p> -<p> -The format of the TXT record returned is described in -<a href="#TXT">Use of TXT delegation record</a>. - -</p> -<a name="rfc.section.11.2.11"></a><h4><a name="anchor67">11.2.11</a> (5E5) Responder replies with ID and authentication</h4> - -<p> - SG-B sends its ID along with authentication material. This is an internal - state for the keying protocol. - -</p> -<a name="rfc.section.11.2.12"></a><h4><a name="anchor68">11.2.12</a> (5G) IKE phase 2</h4> - -<a name="rfc.section.11.2.12.1"></a><h4><a name="anchor69">11.2.12.1</a> (5G1) Initiator proposes tunnel</h4> - -<p> - Having established mutually agreeable authentications (via KEY) and - authorizations (via TXT), SG-A proposes to create an IPsec tunnel for - datagrams transiting from Alice to Bob. This tunnel is established only for - the Alice/Bob combination, not for any subnets that may be behind SG-A and SG-B. - -</p> -<a name="rfc.section.11.2.12.2"></a><h4><a name="anchor70">11.2.12.2</a> (5H1) Responder determines initiator's authority</h4> - -<p> - While the identity of SG-A has been established, its authority to - speak for Alice has not yet been confirmed. SG-B does a reverse - lookup on Alice's address for a TXT record. - -</p> -<p>Upon receiving this specific proposal, SG-B's connection instance - makes a transition into the potential OE connection state. SG-B may already have an - instance, and the check is made as described above. -</p> -<a name="rfc.section.11.2.12.3"></a><h4><a name="anchor71">11.2.12.3</a> (5H2) DNS replies with TXT record(s)</h4> - -<p> - The returned key and IP address should match that of SG-A. - -</p> -<a name="rfc.section.11.2.12.4"></a><h4><a name="anchor72">11.2.12.4</a> (5G2) Responder agrees to proposal</h4> - -<p> - Should additional communication occur between, for instance, Dave and Bob using - SG-A and SG-B, a new tunnel (phase 2 SA) would be established. The phase 1 SA - may be reusable. - -</p> -<p>SG-A, having successfully keyed the tunnel, now makes a transition from - Pending OE connection to Keyed OE connection. - -</p> -<p>The responder MUST setup the inbound IPsec SAs before sending its reply. -</p> -<a name="rfc.section.11.2.12.5"></a><h4><a name="anchor73">11.2.12.5</a> (5G3) Final acknowledgment from initiator</h4> - -<p> - The initiator agrees with the responder's choice and sets up the tunnel. - The initiator sets up the inbound and outbound IPsec SAs. - -</p> -<p> - The proper authorization returned with keys prompts SG-B to make a transition - to the keyed OE connection state. - -</p> -<p>Upon receipt of this message, the responder may now setup the outbound - IPsec SAs. -</p> -<a name="rfc.section.11.2.13"></a><h4><a name="anchor74">11.2.13</a> (6) IPsec succeeds, and sets up tunnel for communication between Alice and Bob</h4> - -<p> - SG-A sends the datagram saved at step (5) through the newly created - tunnel to SG-B, where it gets decrypted and forwarded. - Bob receives it at (7) and replies at (8). - -</p> -<a name="rfc.section.11.2.14"></a><h4><a name="anchor75">11.2.14</a> (9) SG-B already has tunnel up with G1 and uses it</h4> - -<p> - At (9), SG-B has already established an SPD entry mapping Bob->Alice via a - tunnel, so this tunnel is simply applied. The datagram is encrypted to SG-A, - decrypted by SG-A and passed to Alice at (10). - -</p> -<a name="securityconsiderations"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.12"></a><h3>12. Security considerations</h3> - -<a name="rfc.section.12.1"></a><h4><a name="anchor76">12.1</a> Configured vs opportunistic tunnels</h4> - -<p> - Configured tunnels are those which are setup using bilateral mechanisms: exchanging -public keys (raw RSA, DSA, PKIX), pre-shared secrets, or by referencing keys that -are in known places (distinguished name from LDAP, DNS). These keys are then used to -configure a specific tunnel. - -</p> -<p> -A pre-configured tunnel may be on all the time, or may be keyed only when needed. -The end points of the tunnel are not necessarily static: many mobile -applications (road warrior) are considered to be configured tunnels. - -</p> -<p> -The primary characteristic is that configured tunnels are assigned specific -security properties. They may be trusted in different ways relating to exceptions to -firewall rules, exceptions to NAT processing, and to bandwidth or other quality of service restrictions. - -</p> -<p> -Opportunistic tunnels are not inherently trusted in any strong way. They are -created without prior arrangement. As the two parties are strangers, there -MUST be no confusion of datagrams that arrive from opportunistic peers and -those that arrive from configured tunnels. A security gateway MUST take care -that an opportunistic peer can not impersonate a configured peer. - -</p> -<p> -Ingress filtering MUST be used to make sure that only datagrams authorized by -negotiation (and the concomitant authentication and authorization) are -accepted from a tunnel. This is to prevent one peer from impersonating another. - -</p> -<p> -An implementation suggestion is to treat opportunistic tunnel -datagrams as if they arrive on a logical interface distinct from other -configured tunnels. As the number of opportunistic tunnels that may be -created automatically on a system is potentially very high, careful attention -to scaling should be taken into account. - -</p> -<p> -As with any IKE negotiation, opportunistic encryption cannot be secure -without authentication. Opportunistic encryption relies on DNS for its -authentication information and, therefore, cannot be fully secure without -a secure DNS. Without secure DNS, opportunistic encryption can protect against passive -eavesdropping but not against active man-in-the-middle attacks. - -</p> -<a name="rfc.section.12.2"></a><h4><a name="anchor77">12.2</a> Firewalls versus Opportunistic Tunnels</h4> - -<p> - Typical usage of per datagram access control lists is to implement various -kinds of security gateways. These are typically called "firewalls". - -</p> -<p> - Typical usage of a virtual private network (VPN) within a firewall is to -bypass all or part of the access controls between two networks. Additional -trust (as outlined in the previous section) is given to datagrams that arrive -in the VPN. - -</p> -<p> - Datagrams that arrive via opportunistically configured tunnels MUST not be -trusted. Any security policy that would apply to a datagram arriving in the -clear SHOULD also be applied to datagrams arriving opportunistically. - -</p> -<a name="rfc.section.12.3"></a><h4><a name="anchor78">12.3</a> Denial of service</h4> - -<p> - There are several different forms of denial of service that an implementor - should concern themselves with. Most of these problems are shared with - security gateways that have large numbers of mobile peers (road warriors). - -</p> -<p> - The design of ISAKMP/IKE, and its use of cookies, defend against many kinds - of denial of service. Opportunism changes the assumption that if the phase 1 (ISAKMP) - SA is authenticated, that it was worthwhile creating. Because the gateway will communicate with any machine, it is - possible to form phase 1 SAs with any machine on the Internet. - -</p> -<a name="anchor79"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.13"></a><h3>13. IANA Considerations</h3> - -<p> - There are no known numbers which IANA will need to manage. - -</p> -<a name="anchor80"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.14"></a><h3>14. Acknowledgments</h3> - -<p> - Substantive portions of this document are based upon previous work by - Henry Spencer. - -</p> -<p> - Thanks to Tero Kivinen, Sandy Harris, Wes Hardarker, Robert Moskowitz, - Jakob Schlyter, Bill Sommerfeld, John Gilmore and John Denker for their - comments and constructive criticism. - -</p> -<p> - Sandra Hoffman and Bill Dickie did the detailed proof reading and editing. - -</p> -<a name="rfc.references1"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<h3>Normative references</h3> -<table width="99%" border="0"> -<tr><td class="author-text" valign="top"><b><a name="OEspec">[1]</a></b></td> -<td class="author-text"><a href="mailto:hugh@mimosa.com">Redelmeier, D.</a> and <a href="mailto:henry@spsystems.net">H. Spencer</a>, "Opportunistic Encryption", paper http://www.freeswan.org/freeswan_trees/freeswan-1.91/doc/opportunism.spec, May 2001.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC0791">[2]</a></b></td> -<td class="author-text">Defense Advanced Research Projects Agency (DARPA), Information Processing Techniques Office and University of Southern California (USC)/Information Sciences Institute, "<a href="ftp://ftp.isi.edu/in-notes/rfc791.txt">Internet Protocol</a>", STD 5, RFC 791, September 1981.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC1009">[3]</a></b></td> -<td class="author-text"><a href="mailto:">Braden, R.</a> and <a href="mailto:">J. Postel</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1009.txt">Requirements for Internet gateways</a>", RFC 1009, June 1987.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC1984">[4]</a></b></td> -<td class="author-text">IAB, IESG, <a href="mailto:brian@dxcoms.cern.ch">Carpenter, B.</a> and <a href="mailto:fred@cisco.com">F. Baker</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1984.txt">IAB and IESG Statement on Cryptographic Technology and the Internet</a>", RFC 1984, August 1996.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2119">[5]</a></b></td> -<td class="author-text"><a href="mailto:-">Bradner, S.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2119.txt">Key words for use in RFCs to Indicate Requirement Levels</a>", BCP 14, RFC 2119, March 1997.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2367">[6]</a></b></td> -<td class="author-text"><a href="mailto:danmcd@eng.sun.com">McDonald, D.</a>, <a href="mailto:cmetz@inner.net">Metz, C.</a> and <a href="mailto:phan@itd.nrl.navy.mil">B. Phan</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2367.txt">PF_KEY Key Management API, Version 2</a>", RFC 2367, July 1998.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2401">[7]</a></b></td> -<td class="author-text"><a href="mailto:kent@bbn.com">Kent, S.</a> and <a href="mailto:rja@corp.home.net">R. Atkinson</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2401.txt">Security Architecture for the Internet Protocol</a>", RFC 2401, November 1998.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2407">[8]</a></b></td> -<td class="author-text"><a href="mailto:ddp@network-alchemy.com">Piper, D.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2407.txt">The Internet IP Security Domain of Interpretation for ISAKMP</a>", RFC 2407, November 1998.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2408">[9]</a></b></td> -<td class="author-text"><a href="mailto:wdm@tycho.ncsc.mil">Maughan, D.</a>, <a href="mailto:mss@tycho.ncsc.mil">Schneider, M.</a> and <a href="er@raba.com">M. Schertler</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2408.txt">Internet Security Association and Key Management Protocol (ISAKMP)</a>", RFC 2408, November 1998.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2409">[10]</a></b></td> -<td class="author-text"><a href="mailto:dharkins@cisco.com">Harkins, D.</a> and <a href="mailto:carrel@ipsec.org">D. Carrel</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2409.txt">The Internet Key Exchange (IKE)</a>", RFC 2409, November 1998.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC3526">[11]</a></b></td> -<td class="author-text"><a href="mailto:kivinen@ssh.fi">Kivinen, T.</a> and <a href="mailto:mrskojo@cc.helsinki.fi">M. Kojo</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc3526.txt">More MODP Diffie-Hellman groups for IKE</a>", RFC 3526, March 2003.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC1034">[12]</a></b></td> -<td class="author-text">Mockapetris, P., "<a href="ftp://ftp.isi.edu/in-notes/rfc1034.txt">Domain names - concepts and facilities</a>", STD 13, RFC 1034, November 1987.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC1035">[13]</a></b></td> -<td class="author-text"><a href="mailto:">Mockapetris, P.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1035.txt">Domain names - implementation and specification</a>", STD 13, RFC 1035, November 1987.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2671">[14]</a></b></td> -<td class="author-text"><a href="mailto:vixie@isc.org">Vixie, P.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2671.txt">Extension Mechanisms for DNS (EDNS0)</a>", RFC 2671, August 1999.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC1464">[15]</a></b></td> -<td class="author-text"><a href="mailto:rosenbaum@lkg.dec.com">Rosenbaum, R.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1464.txt">Using the Domain Name System To Store Arbitrary String Attributes</a>", RFC 1464, May 1993.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2535">[16]</a></b></td> -<td class="author-text"><a href="mailto:dee3@us.ibm.com">Eastlake, D.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2535.txt">Domain Name System Security Extensions</a>", RFC 2535, March 1999.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC3110">[17]</a></b></td> -<td class="author-text">Eastlake, D., "<a href="ftp://ftp.isi.edu/in-notes/rfc3110.txt">RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)</a>", RFC 3110, May 2001.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2538">[18]</a></b></td> -<td class="author-text"><a href="mailto:dee3@us.ibm.com">Eastlake, D.</a> and <a href="mailto:ogud@tislabs.com">O. Gudmundsson</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2538.txt">Storing Certificates in the Domain Name System (DNS)</a>", RFC 2538, March 1999.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2748">[19]</a></b></td> -<td class="author-text"><a href="mailto:David.Durham@intel.com">Durham, D.</a>, <a href="mailto:jboyle@Level3.net">Boyle, J.</a>, <a href="mailto:ronc@cisco.com">Cohen, R.</a>, <a href="mailto:herzog@iphighway.com">Herzog, S.</a>, <a href="mailto:rajan@research.att.com">Rajan, R.</a> and <a href="mailto:asastry@cisco.com">A. Sastry</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2748.txt">The COPS (Common Open Policy Service) Protocol</a>", RFC 2748, January 2000.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2663">[20]</a></b></td> -<td class="author-text"><a href="mailto:srisuresh@lucent.com">Srisuresh, P.</a> and <a href="mailto:holdrege@lucent.com">M. Holdrege</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2663.txt">IP Network Address Translator (NAT) Terminology and Considerations</a>", RFC 2663, August 1999.</td></tr> -</table> - -<a name="rfc.authors"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<h3>Authors' Addresses</h3> -<table width="99%" border="0" cellpadding="0" cellspacing="0"> -<tr><td class="author-text"> </td> -<td class="author-text">Michael C. Richardson</td></tr> -<tr><td class="author-text"> </td> -<td class="author-text">Sandelman Software Works</td></tr> -<tr><td class="author-text"> </td> -<td class="author-text">470 Dawson Avenue</td></tr> -<tr><td class="author-text"> </td> -<td class="author-text">Ottawa, ON K1Z 5V7</td></tr> -<tr><td class="author-text"> </td> -<td class="author-text">CA</td></tr> -<tr><td class="author" align="right">EMail: </td> -<td class="author-text"><a href="mailto:mcr@sandelman.ottawa.on.ca">mcr@sandelman.ottawa.on.ca</a></td></tr> -<tr><td class="author" align="right">URI: </td> -<td class="author-text"><a href="http://www.sandelman.ottawa.on.ca/">http://www.sandelman.ottawa.on.ca/</a></td></tr> -<tr cellpadding="3"><td> </td><td> </td></tr> -<tr><td class="author-text"> </td> -<td class="author-text">D. Hugh Redelmeier</td></tr> -<tr><td class="author-text"> </td> -<td class="author-text">Mimosa</td></tr> -<tr><td class="author-text"> </td> -<td class="author-text">Toronto, ON</td></tr> -<tr><td class="author-text"> </td> -<td class="author-text">CA</td></tr> -<tr><td class="author" align="right">EMail: </td> -<td class="author-text"><a href="mailto:hugh@mimosa.com">hugh@mimosa.com</a></td></tr> -</table> -<a name="rfc.copyright"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<h3>Full Copyright Statement</h3> -<p class='copyright'> -Copyright (C) The Internet Society (2003). All Rights Reserved.</p> -<p class='copyright'> -This document and translations of it may be copied and furnished to -others, and derivative works that comment on or otherwise explain it -or assist in its implementation may be prepared, copied, published and -distributed, in whole or in part, without restriction of any kind, -provided that the above copyright notice and this paragraph are -included on all such copies and derivative works. However, this -document itself may not be modified in any way, such as by removing -the copyright notice or references to the Internet Society or other -Internet organizations, except as needed for the purpose of -developing Internet standards in which case the procedures for -copyrights defined in the Internet Standards process must be -followed, or as required to translate it into languages other than -English.</p> -<p class='copyright'> -The limited permissions granted above are perpetual and will not be -revoked by the Internet Society or its successors or assigns.</p> -<p class='copyright'> -This document and the information contained herein is provided on an -"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING -TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING -BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION -HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF -MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p> -<h3>Acknowledgement</h3> -<p class='copyright'> -Funding for the RFC Editor function is currently provided by the -Internet Society.</p> -</font></body></html> diff --git a/doc/src/draft-richardson-ipsec-opportunistic.xml b/doc/src/draft-richardson-ipsec-opportunistic.xml deleted file mode 100644 index d587df693..000000000 --- a/doc/src/draft-richardson-ipsec-opportunistic.xml +++ /dev/null @@ -1,2519 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE rfc SYSTEM "rfc2629.dtd"> -<?rfc toc="yes"?> -<?rfc tocdepth='2' ?> - -<rfc ipr="full2026" docName="draft-richardson-ipsec-opportunistic-12.txt"> - -<front> - <area>Security</area> - <workgroup>Independent submission</workgroup> - <title abbrev="opportunistic"> - Opportunistic Encryption using The Internet Key Exchange (IKE) - </title> - - <author initials="M." surname="Richardson" fullname="Michael C. Richardson"> - <organization abbrev="SSW">Sandelman Software Works</organization> - <address> - <postal> - <street>470 Dawson Avenue</street> - <city>Ottawa</city> - <region>ON</region> - <code>K1Z 5V7</code> - <country>CA</country> - </postal> - <email>mcr@sandelman.ottawa.on.ca</email> - <uri>http://www.sandelman.ottawa.on.ca/</uri> - </address> - </author> - - <author initials="D.H." surname="Redelmeier" - fullname="D. Hugh Redelmeier"> - <organization abbrev="Mimosa">Mimosa</organization> - <address> - <postal> - <city>Toronto</city> - <region>ON</region> - <country>CA</country> - </postal> - <email>hugh@mimosa.com</email> - </address> - </author> - - <date month="June" year="2003"></date> - -<abstract> - <t> -This document describes opportunistic encryption (OE) using the Internet Key -Exchange (IKE) and IPsec. -Each system administrator adds new -resource records to his or her Domain Name System (DNS) to support -opportunistic encryption. The objective is to allow encryption for secure communication without -any pre-arrangement specific to the pair of systems involved. - </t> - <t> -DNS is used to distribute the public keys of each -system involved. This is resistant to passive attacks. The use of DNS -Security (DNSSEC) secures this system against active attackers as well. - </t> - <t> -As a result, the administrative overhead is reduced -from the square of the number of systems to a linear dependence, and it becomes -possible to make secure communication the default even -when the partner is not known in advance. - </t> - <t> -This document is offered up as an Informational RFC. - </t> -</abstract> - -</front> - -<middle> - -<section title="Introduction"> - -<section title="Motivation"> - -<t> -The objective of opportunistic encryption is to allow encryption without -any pre-arrangement specific to the pair of systems involved. Each -system administrator adds -public key information to DNS records to support opportunistic -encryption and then enables this feature in the nodes' IPsec stack. -Once this is done, any two such nodes can communicate securely. -</t> - -<t> -This document describes opportunistic encryption as designed and -implemented by the Linux FreeS/WAN project in revisions up and including 2.00. -Note that 2.01 and beyond implements RFC3445, in a backward compatible way. -For project information, see http://www.freeswan.org. -</t> - - <t> -The Internet Architecture Board (IAB) and Internet Engineering -Steering Group (IESG) have taken a strong stand that the Internet -should use powerful encryption to provide security and -privacy <xref target="RFC1984" />. -The Linux FreeS/WAN project attempts to provide a practical means to implement this policy. - </t> - - <t> -The project uses the IPsec, ISAKMP/IKE, DNS and DNSSEC -protocols because they are -standardized, widely available and can often be deployed very easily -without changing hardware or software or retraining users. - </t> - - <t> -The extensions to support opportunistic encryption are simple. No -changes to any on-the-wire formats are needed. The only changes are to -the policy decision making system. This means that opportunistic -encryption can be implemented with very minimal changes to an existing -IPsec implementation. - </t> - - <t> -Opportunistic encryption creates a "fax effect". The proliferation -of the fax machine was possible because it did not require that everyone -buy one overnight. Instead, as each person installed one, the value -of having one increased - as there were more people that could receive faxes. -Once opportunistic encryption is installed it -automatically recognizes -other boxes using opportunistic encryption, without any further configuration -by the network -administrator. So, as opportunistic encryption software is installed on more -boxes, its value -as a tool increases. -</t> - - <t> -This document describes the infrastructure to permit deployment of -Opportunistic Encryption. -</t> - - <t> -The term S/WAN is a trademark of RSA Data Systems, and is used with permission -by this project. - </t> - -</section> - -<section title="Types of network traffic"> - <t> - To aid in understanding the relationship between security processing and IPsec - we divide network traffic into four categories: - <list style="hanging"> - <t hangText="* Deny:"> networks to which traffic is always forbidden.</t> - <t hangText="* Permit:"> networks to which traffic in the clear is permitted.</t> - <t hangText="* Opportunistic tunnel:"> networks to which traffic is encrypted if possible, but otherwise is in the clear - or fails depending on the default policy in place. - </t> - <t hangText="* Configured tunnel:"> networks to which traffic -must be encrypted, and traffic in the clear is never permitted. -A Virtual Private Network (VPN) is a form of configured tunnel. -</t> - </list> - </t> - -<t> -Traditional firewall devices handle the first two categories. -No authentication is required. -The permit policy is currently the default on the Internet. -</t> - -<t> -This document describes the third category - opportunistic tunnel, which is -proposed as the new default for the Internet. -</t> - -<t> - Category four, encrypt traffic or drop it, requires authentication of the - end points. As the number of end points is typically bounded and is typically - under a single authority, arranging for distribution of - authentication material, while difficult, does not require any new - technology. The mechanism described here provides an additional way to - distribute the authentication materials, that of a public key method that does not - require deployment of an X.509 based infrastructure. -</t> -<t> -Current Virtual Private Networks can often be replaced by an "OE paranoid" -policy as described herein. -</t> -</section> - -<section title="Peer authentication in opportunistic encryption"> - - <t> - Opportunistic encryption creates tunnels between nodes that - are essentially strangers. This is done without any prior bilateral - arrangement. - There is, therefore, the difficult question of how one knows to whom one is - talking. - </t> - - <t> - One possible answer is that since no useful - authentication can be done, none should be tried. This mode of operation is - named "anonymous encryption". An active man-in-the-middle attack can be - used to thwart the privacy of this type of communication. - Without peer authentication, there is no way to prevent this kind of attack. - </t> - - <t> -Although a useful mode, anonymous encryption is not the goal of this -project. Simpler methods are available that can achieve anonymous -encryption only, but authentication of the peer is a desireable goal. -The latter is achieved through key distribution in DNS, leveraging upon -the authentication of the DNS in DNSSEC. -</t> - - <t> - Peers are, therefore, authenticated with DNSSEC when available. Local policy -determines how much trust to extend when DNSSEC is not available. - </t> - - <t> - However, an essential premise of building private connections with - strangers is that datagrams received through opportunistic tunnels - are no more special than datagrams that arrive in the clear. - Unlike in a VPN, these datagrams should not be given any special - exceptions when it comes to auditing, further authentication or - firewalling. - </t> - - <t> - When initiating outbound opportunistic encryption, local - configuration determines what happens if tunnel setup fails. It may be that - the packet goes out in the clear, or it may be dropped. - </t> - - </section> - -<section title="Use of RFC2119 terms"> -<t> - The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, - SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL, when they appear in this - document, are to be interpreted as described in <xref target="RFC2119" /> -</t> -</section> - -</section> - -<section title="Overview"> - - <section title="Reference diagram"> - - <figure anchor="networkdiagram" title="Reference Network Diagram"> - <preamble>The following network diagram is used in the rest of - this document as the canonical diagram:</preamble> - <artwork> - [Q] [R] - . . AS2 - [A]----+----[SG-A].......+....+.......[SG-B]-------[B] - | ...... - AS1 | ..PI.. - | ...... - [D]----+----[SG-D].......+....+.......[C] AS3 - - - </artwork> - <postamble></postamble> - - </figure> - - <t> - In this diagram, there are four end-nodes: A, B, C and D. - There are three security gateways, SG-A, SG-B, SG-D. A, D, SG-A and - SG-D are part - of the same administrative authority, AS1. SG-A and SG-D are on two - different exit - paths from organization 1. SG-B/B is an independent organization, AS2. - Nodes Q and R are nodes on the Internet. PI is the Public - Internet ("The Wild"). - </t> - - </section> - - <section title="Terminology"> - - <t> - The following terminology is used in this document: - </t> - - <list style="hanging"> - <t hangText="Security gateway (or simply gateway):"> a system that performs IPsec tunnel - mode encapsulation/decapsulation. [SG-x] in the diagram.</t> - <t hangText="Alice:"> node [A] in the diagram. When an IP address is needed, this is 192.1.0.65.</t> - <t hangText="Bob:"> node [B] in the diagram. When an IP address is needed, this is 192.2.0.66.</t> - <t hangText="Carol:"> node [C] in the diagram. When an IP address is needed, this is 192.1.1.67.</t> - <t hangText="Dave:"> node [D] in the diagram. When an IP address is needed, this is 192.3.0.68.</t> - <t hangText="SG-A:"> Alice's security gateway. Internally it is 192.1.0.1, externally it is 192.1.1.4.</t> - <t hangText="SG-B:"> Bob's security gateway. Internally it is 192.2.0.1, externally it is 192.1.1.5.</t> - <t hangText="SG-D:"> Dave's security gateway. Also Alice's backup security gateway. Internally it is 192.3.0.1, externally it is 192.1.1.6.</t> - <t hangText="."> A period represents an untrusted network of unknown - type.</t> - <t hangText="Configured tunnel:"> a tunnel that - is directly and deliberately hand configured on participating gateways. - Configured tunnels are typically given a higher level of - trust than opportunistic tunnels.</t> - - <t hangText="Road warrior tunnel:"> a configured tunnel connecting one - node with a fixed IP address and one node with a variable IP address. - A road warrior (RW) connection must be initiated by the - variable node, since the fixed node cannot know the - current address for the road warrior. </t> - - <t hangText="Anonymous encryption:"> - the process of encrypting a session without any knowledge of who the - other parties are. No authentication of identities is done.</t> - - <t hangText="Opportunistic encryption:"> - the process of encrypting a session with authenticated knowledge of - who the other party is.</t> - - <t hangText="Lifetime:"> - the period in seconds (bytes or datagrams) for which a security - association will remain alive before needing to be re-keyed.</t> - - <t hangText="Lifespan:"> - the effective time for which a security association remains useful. A - security association with a lifespan shorter than its lifetime would - be removed when no longer needed. A security association with a - lifespan longer than its lifetime would need to be re-keyed one or - more times.</t> - - <t hangText="Phase 1 SA:"> an ISAKMP/IKE security association sometimes - referred to as a keying channel.</t> - - <t hangText="Phase 2 SA:"> an IPsec security association.</t> - - <t hangText="Tunnel:"> another term for a set of phase 2 SA (one in each direction).</t> - - <t hangText="NAT:"> Network Address Translation - (see <xref target="RFC2663" />).</t> - - <t hangText="NAPT:"> Network Address and Port Translation - (see <xref target="RFC2663" />).</t> - - <t hangText="AS:"> an autonomous system </t> - - <t hangText="FQDN:"> Fully-Qualified Domain Name </t> - - <t hangText="Default-free zone:"> - a set of routers that maintain a complete set of routes to - all currently reachable destinations. Having such a list, these routers - never make use of a default route. A datagram with a destination address - not matching any route will be dropped by such a router. - </t> - - </list> - </section> - -<section title="Model of operation"> - -<t> -The opportunistic encryption security gateway (OE gateway) is a regular -gateway node as described in <xref target="RFC0791" /> section 2.4 and -<xref target="RFC1009" /> with the additional capabilities described here and -in <xref target="RFC2401" />. -The algorithm described here provides a way to determine, for each datagram, -whether or not to encrypt and tunnel the datagram. Two important things -that must be determined are whether or not to encrypt and tunnel and, if -so, the destination address or name of the tunnel end point which should be used. -</t> - -<section title="Tunnel authorization"> -<t> -The OE gateway determines whether or not to create a tunnel based on -the destination address of each packet. Upon receiving a packet with a destination -address not recently seen, the OE gateway performs a lookup in DNS for an -authorization resource record (see <xref target="TXT"/>). The record is located using -the IP address to perform a search in the in-addr.arpa (IPv4) or ip6.arpa -(IPv6) maps. If an authorization record is found, the OE gateway -interprets this as a request for a tunnel to be formed. -</t> -</section> - -<section title="Tunnel end-point discovery"> - -<t> -The authorization resource record also provides the address or name of the tunnel -end point which should be used. -</t> -<t> -The record may also provide the public RSA key of the tunnel end point -itself. This is provided for efficiency only. If the public RSA key is not -present, the OE gateway performs a second lookup to find a KEY -resource record for the end point address or name. -</t> -<t> -Origin and integrity protection of the resource records is provided by -DNSSEC (<xref target="RFC2535"/>). <xref target="nodnssec"/> -documents an optional restriction on the tunnel end point if DNSSEC signatures -are not available for the relevant records. -</t> - -</section> - -<section title="Caching of authorization results"> -<t> -The OE gateway maintains a cache, in the forwarding plane, of -source/destination pairs for which opportunistic encryption has been -attempted. This cache maintains a record of whether or not OE was -successful so that subsequent datagrams can be forwarded properly -without additional delay. -</t> - -<t> -Successful negotiation of OE instantiates a new security association. -Failure to negotiate OE results in creation of a -forwarding policy entry either to drop or transmit in the clear future -datagrams. This negative cache is necessary to avoid the possibly lengthy process of repeatedly looking -up the same information. -</t> - -<t> -The cache is timed out periodically, as described in <xref target="teardown" />. -This removes entries that are no longer -being used and permits the discovery of changes in authorization policy. -</t> -</section> - -</section> <!-- "Model of operation" --> - -</section> <!-- "Overview" --> - -<section title="Protocol Specification"> - -<t> -The OE gateway is modeled to have a forwarding plane and a control -plane. A control channel, such as PF_KEY, connects the two planes. -(See <xref target="RFC2367" />.) -The forwarding plane performs per datagram operations. The control plane -contains a keying daemon, such as ISAKMP/IKE, and performs all -authorization, peer authentication and key derivation functions. -</t> - -<section title="Forwarding plane state machine"> - -<t> -Let the OE gateway maintain a collection of objects -- a superset of the -security policy database (SPD) specified in <xref target="RFC2401" />. For -each combination of source and destination address, an SPD -object exists in one of five following states. -Prior to forwarding each datagram, the responder uses the source and -destination addresses to pick an entry from the SPD. -The SPD then determines if and how the packet is forwarded. -</t> - -<!-- from file forwardingstate.txt --> -<artwork><![CDATA[ - .--------------. - | non-existant | - | policy | - `--------------' - | - | PF_ACQUIRE - | - |<---------. - V | new packet - .--------------. | (maybe resend PF_ACQUIRE) - | hold policy |--' - | |--. - `--------------' \ pass - | | \ msg .---------. - | | \ V | forward - | | .-------------. | packet - create | | | pass policy |--' - IPsec | | `-------------' - SA | | - | \ - | \ - V \ deny - .---------. \ msg - | encrypt | \ - | policy | \ ,---------. - `---------' \ | | discard - \ V | packet - .-------------. | - | deny policy |--' - '-------------' -]]></artwork> - - -<section title="Non-existent policy"> -<t> -If the gateway does not find an entry, then this policy applies. -The gateway creates an entry with an initial state of "hold policy" and requests -keying material from the keying daemon. The gateway does not forward the datagram, -rather it SHOULD attach the datagram to the SPD entry as the "first" datagram and retain it -for eventual transmission in a new state. - -</t> -</section> - -<section title="Hold policy"> -<t> -The gateway requests keying material. If the interface to the keying -system is lossy (PF_KEY, for instance, can be), the implementation -SHOULD include a mechanism to retransmit the -keying request at a rate limited to less than 1 request per second. -The gateway does not forward the datagram. The gateway SHOULD attach the -datagram to the SPD entry as the "last" datagram where it is retained -for eventual transmission. -If there is a datagram already so stored, then that already stored datagram is discarded. -</t> -<t> -The rational behind saving the the "first" and "last" datagrams are as follows: -The "first" datagram is probably a TCP SYN packet. Once there is keying -established, the gateway will release this datagram, avoiding the need to -for the end-point to retransmit the datagram. In the case where the connection -was not a TCP connection, buyt was instead a streaming protocol or a DNS request, -the "last" datagram that was retained is likely the most recent data. The difference -between "first" and "last" may also help the end-points determine -which data awas dropped while negotiation took place. -</t> -</section> - -<section title="Pass-through policy"> -<t> -The gateway forwards the datagram using the normal forwarding table. -The gateway enters this state only by command from the keying daemon, -and upon entering this state, also forwards the "first" and "last" datagrams. -</t> -</section> - -<section title="Deny policy"> -<t> -The gateway discards the datagram. The gateway enters this state only by -command -from the keying daemon, and upon entering this state, discards the "first" -and "last" datagrams. -An implementation MAY provide the administator with a control to determine -if further datagrams cause ICMP messages -to be generated (i.e. ICMP Destination Unreachable, Communication -Administratively Prohibited. type=3, code=13). -</t> -</section> - -<section title="Encrypt policy"> -<t> -The gateway encrypts the datagram using the indicated security association database -(SAD) entry. The gateway enters this state only by command from the keying daemon, and upon entering -this state, releases and forwards the "first" and "last" datagrams using the -new encrypt policy. -</t> -<t> -If the associated SAD entry expires because of byte, packet or time limits, then -the entry returns to the Hold policy, and an expire message is sent to the keying daemon. -</t> -</section> - -<t> -All states may be created directly by the keying daemon while acting as a -gateway. -</t> - -</section> <!-- "Datagram state machine" --> - - -<section anchor="initclasses" title="Keying Daemon -- initiator"> -<t> -Let the keying daemon maintain a collection of objects. Let them be -called "connections" or "conn"s. There are two categories of -connection objects: classes and instances. A class represents an -abstract policy - what could be. An instance represents an actual connection - -what is implemented at the time. -</t> - -<t> -Let there be two further subtypes of connections: keying channels (Phase -1 SAs) and data channels (Phase 2 SAs). Each data channel object may have -a corresponding SPD and SAD entry maintained by the datagram state machine. -</t> - -<t> -For the purposes of opportunistic encryption, there MUST, at least, be -connection classes known as "deny", "always-clear-text", "OE-permissive", and -"OE-paranoid". -The latter two connection classes define a set of source and/or destination -addresses for which opportunistic encryption will be attempted. -The administrator MAY set policy options in a number of additional places. -An implementation MAY create additional connection classes to further refine -these policies. -</t> - -<t> -The simplest system may need only the "OE-permissive" connection, and would -list its own (single) IP address as the source address of this policy and -the wild-card address 0.0.0.0/0 as the destination IPv4 address. That is, the -simplest policy is to try opportunistic encryption with all destinations. -</t> - -<t> -The distinction between permissive and paranoid OE use will become clear -in the state transition differences. In general a permissive OE will, on -failure, install a pass-through policy, while a paranoid OE will, on failure, -install a drop policy. -</t> - -<t> -In this description of the keying machine's state transitions, the states -associated with the keying system itself are omitted because they are best documented in the keying system -(<xref target="RFC2407" />, -<xref target="RFC2408" /> and <xref target="RFC2409" /> for ISAKMP/IKE), -and the details are keying system specific. Opportunistic encryption is not -dependent upon any specific keying protocol, but this document does provide -requirements for those using ISAKMP/IKE to assure that implementations inter-operate. -</t> -<t> -The state transitions that may be involved in communicating with the -forwarding plane are omitted. PF_KEY and similar protocols have their own -set of states required for message sends and completion notifications. -</t> -<t> -Finally, the retransmits and recursive lookups that are normal for DNS are -not included in this description of the state machine. -</t> - -<!-- from file initiatorstate.txt --> -<artwork><![CDATA[ - - | - | PF_ACQUIRE - | - V - .---------------. - | non-existant | - | connection | - `---------------' - | | | - send , | \ -expired pass / | \ send -conn. msg / | \ deny - ^ / | \ msg - | V | do \ -.---------------. | DNS \ .---------------. -| clear-text | | lookup `->| deny |---> expired -| connection | | for | connection | connection -`---------------' | destination `---------------' - ^ ^ | ^ - | | no record | | - | | OE-permissive V | no record - | | .---------------. | OE-paranoid - | `------------| potential OE |---------' - | | connection | ^ - | `---------------' | - | | | - | | got TXT record | DNSSEC failure - | | reply | - | V | wrong - | .---------------. | failure - | | authenticate |---------' - | | & parse TXT RR| ^ - | repeated `---------------' | - | ICMP | | - | failures | initiate IKE to | - | (short-timeout) | responder | - | V | - | phase-2 .---------------. | failure - | failure | pending |---------' - | (normal | OE | ^ - | timeout) | |invalid | phase-2 failure (short-timeout) - | | |<--.SPI | ICMP failures (normal timeout) - | | | | | - | | +=======+ |---' | - | | | IKE | | ^ | - `--------------| | states|---------------' - | +=======+ | | - `---------------' | - | IPsec SA | invalid SPI - | established | - V | rekey time - .--------------. | - | keyed |<---|-------------------------------. - | connection |----' | - `--------------' | - | timer | - | | - V | - .--------------. connection still active | - clear-text----->| expired |------------------------------------' - deny----->| connection | - `--------------' - | dead connected - deleted - V -]]></artwork> - - -<section title="Nonexistent connection"> -<t> -There is no connection instance for a given source/destination address pair. -Upon receipt of a request for keying material for this -source/destination pair, the initiator searches through the connection classes to -determine the most appropriate policy. Upon determining an appropriate -connection class, an instance object is created of that type. -Both of the OE types result in a potential OE connection. -</t> -<t>Failure to find an appropriate connection class results in an -administrator defined default. -</t> -<t> -In each case, when the initiator finds an appropriate class for the new flow, -an instance connection is made of the class which matched. -</t> -</section> - -<section title="Clear-text connection"> -<t> -The non-existent connection makes a transition to this state when an -always-clear-text class is instantiated, or when an OE-permissive -connection fails. During the transition, the initiator creates a pass-through -policy object in the forwarding plane for the appropriate flow. -</t> -<t> -Timing out is the only way to leave this state -(see <xref target="expiring" />). -</t> -</section> - -<section title="Deny connection"> -<t> -The empty connection makes a transition to this state when a -deny class is instantiated, or when an OE-paranoid connection fails. -During the transition, the initiator creates a deny policy object in the forwarding plane -for the appropriate flow. -</t> -<t> -Timing out is the only way to leave this state -(see <xref target="expiring" />). -</t> -</section> - -<section title="Potential OE connection"> -<t> -The empty connection makes a transition to this state when one of either OE class is instantiated. -During the transition to this state, the initiator creates a hold policy object in the -forwarding plane for the appropriate flow. -</t> -<t> -In addition, when making a transition into this state, DNS lookup is done in -the reverse-map for a TXT delegation resource record (see <xref target="TXT" />). -The lookup key is the destination address of the flow. -</t> -<t> -There are three ways to exit this state: -<list style="numbers"> -<t>DNS lookup finds a TXT delegation resource record.</t> -<t>DNS lookup does not find a TXT delegation resource record.</t> -<t>DNS lookup times out.</t> -</list> -</t> - -<t> -Based upon the results of the DNS lookup, the potential OE connection makes a -transition to the pending OE connection state. The conditions for a -successful DNS look are: -<list style="numbers"> -<t>DNS finds an appropriate resource record</t> -<t>It is properly formatted according to <xref target="TXT" /></t> -<t> if DNSSEC is enabled, then the signature has been vouched for.</t> -</list> - -Note that if the initiator does not find the public key -present in the TXT delegation record, then the public key must -be looked up as a sub-state. Only successful completion of all the -DNS lookups is considered a success. -</t> -<t> -If DNS lookup does not find a resource record or DNS times out, then the -initiator considers the receiver not OE capable. If this is an OE-paranoid instance, -then the potential OE connection makes a transition to the deny connection state. -If this is an OE-permissive instance, then the potential OE connection makes a transition to the -clear-text connection state. -</t> -<t> -If the initiator finds a resource record but it is not properly formatted, or -if DNSSEC is -enabled and reports a failure to authenticate, then the potential OE -connection makes a -transition to the deny connection state. This action SHOULD be logged. If the -administrator wishes to override this transition between states, then an -always-clear class can be installed for this flow. An implementation MAY make -this situation a new class. -</t> - -<section anchor="nodnssec" title="Restriction on unauthenticated TXT delegation records"> -<t> -An implementation SHOULD also provide an additional administrative control -on delegation records and DNSSEC. This control would apply to delegation -records (the TXT records in the reverse-map) that are not protected by -DNSSEC. -Records of this type are only permitted to delegate to their own address as -a gateway. When this option is enabled, an active attack on DNS will be -unable to redirect packets to other than the original destination. -<!-- This was asked for by Bill Sommerfeld --> -</t> -</section> -</section> - -<section title="Pending OE connection"> -<t> -The potential OE connection makes a transition to this state when -the initiator determines that all the information required from the DNS lookup is present. -Upon entering this state, the initiator attempts to initiate keying to the gateway -provided. -</t> -<t> -Exit from this state occurs either with a successfully created IPsec SA, or -with a failure of some kind. Successful SA creation results in a transition -to the key connection state. -</t> -<t> -Three failures have caused significant problems. They are clearly not the -only possible failures from keying. -</t> -<t> -Note that if there are multiple gateways available in the TXT delegation -records, then a failure can only be declared after all have been -tried. Further, creation of a phase 1 SA does not constitute success. A set -of phase 2 SAs (a tunnel) is considered success. -</t> -<t> -The first failure occurs when an ICMP port unreachable is consistently received -without any other communication, or when there is silence from the remote -end. This usually means that either the gateway is not alive, or the -keying daemon is not functional. For an OE-permissive connection, the initiator makes a transition -to the clear-text connection but with a low lifespan. For an OE-pessimistic connection, -the initiator makes a transition to the deny connection again with a low lifespan. The -lifespan in both -cases is kept low because the remote gateway may -be in the process of rebooting or be otherwise temporarily unavailable. -</t> -<t> -The length of time to wait for the remote keying daemon to wake up is -a matter of some debate. If there is a routing failure, 5 minutes is usually long -enough for the network to -re-converge. Many systems can reboot in that amount of -time as well. However, 5 minutes is far too long for most users to wait to -hear that they can not connect using OE. Implementations SHOULD make this a -tunable parameter. -</t> -<t> -The second failure occurs after a phase 1 SA has been created, but there is -either no response to the phase 2 proposal, or the initiator receives a -negative notify (the notify must be -authenticated). The remote gateway is not prepared to do OE at this time. -As before, the initiator makes a transition to the clear-text or the deny -connection based upon connection class, but this -time with a normal lifespan. -</t> -<t> -The third failure occurs when there is signature failure while authenticating -the remote gateway. This can occur when there has been a -key roll-over, but DNS has not caught up. In this case again, the initiator makes a -transition to the clear-text or the deny connection based -upon the connection class. However, the lifespan depends upon the remaining -time to live in the DNS. (Note that DNSSEC signed resource records have a different -expiry time than non-signed records.) -<!-- dig @gateway would also work here --> -</t> - -</section> - -<section anchor="keyed" title="Keyed connection"> -<t> -The pending OE connection makes a transition to this state when -session keying material (the phase 2 SAs) is derived. The initiator creates an encrypt -policy in the forwarding plane for this flow. -</t> -<t> -There are three ways to exit this state. The first is by receipt of an -authenticated delete message (via the keying channel) from the peer. This is -normal teardown and results in a transition to the expired connection state. -</t> -<t> -The second exit is by expiry of the forwarding plane keying material. This -starts a re-key operation with a transition back to pending OE -connection. In general, the soft expiry occurs with sufficient time left -to continue to use the keys. A re-key can fail, which may -result in the connection failing to clear-text or deny as -appropriate. In the event of a failure, the forwarding plane -policy does not change until the phase 2 SA (IPsec SA) reaches its -hard expiry. -</t> -<t> -The third exit is in response to a negotiation from a remote -gateway. If the forwarding plane signals the control plane that it has received an -unknown SPI from the remote gateway, or an ICMP is received from the remote gateway -indicating an unknown SPI, the initiator should consider that -the remote gateway has rebooted or restarted. Since these -indications are easily forged, the implementation must -exercise care. The initiator should make a cautious -(rate-limited) attempt to re-key the connection. -</t> -</section> - -<section anchor="expiring" title="Expiring connection"> -<t> -The initiator will periodically place each of the deny, clear-text, and keyed -connections into this -sub-state. See <xref target="teardown" /> for more details of how often this -occurs. -The initiator queries the forwarding plane for last use time of the -appropriate -policy. If the last use time is relatively recent, then the connection -returns to the -previous deny, clear-text or keyed connection state. If not, then the -connection enters -the expired connection state. -</t> -<t> -The DNS query and answer that lead to the expiring connection state are also -examined. The DNS query may become stale. (A negative, i.e. no such record, answer -is valid for the period of time given by the MINIMUM field in an attached SOA -record. See <xref target="RFC1034" /> section 4.3.4.) -If the DNS query is stale, then a new query is made. If the results change, then the connection -makes a transition to a new state as described in potential OE connection state. -</t> -<t> -Note that when considering how stale a connection is, both outgoing SPD and -incoming SAD must be queried as some flows may be unidirectional for some time. -</t> -<t> -Also note that the policy at the forwarding plane is not updated unless there -is a conclusion that there should be a change. -</t> - -</section> -<section title="Expired connection"> -<t> -Entry to this state occurs when no datagrams have been forwarded recently via the -appropriate SPD and SAD objects. The objects in the forwarding plane are -removed (logging any final byte and packet counts if appropriate) and the -connection instance in the keying plane is deleted. -</t> -<t> -The initiator sends an ISAKMP/IKE delete to clean up the phase 2 SAs as described in -<xref target="teardown" />. -</t> -<t> -Whether or not to delete the phase 1 SAs -at this time is left as a local implementation issue. Implementations -that do delete the phase 1 SAs MUST send authenticated delete messages to -indicate that they are doing so. There is an advantage to keeping -the phase 1 SAs until they expire - they may prove useful again in the -near future. -</t> -</section> - -</section> <!-- "Keying state machine - initiator" --> - -<section title="Keying Daemon - responder"> -<t> -The responder has a set of objects identical to those of the initiator. -</t> -<t> -The responder receives an invitation to create a keying channel from an initiator. -</t> - -<!-- from file responderstate.txt --> -<artwork><![CDATA[ - | - | IKE main mode - | phase 1 - V - .-----------------. - | unauthenticated | - | OE peer | - `-----------------' - | - | lookup KEY RR in in-addr.arpa - | (if ID_IPV4_ADDR) - | lookup KEY RR in forward - | (if ID_FQDN) - V - .-----------------. RR not found - | received DNS |---------------> log failure - | reply | - `----+--------+---' - phase 2 | \ misformatted - proposal | `------------------> log failure - V - .----------------. - | authenticated | identical initiator - | OE peer |--------------------> initiator - `----------------' connection found state machine - | - | look for TXT record for initiator - | - V - .---------------. - | authorized |---------------------> log failure - | OE peer | - `---------------' - | - | - V - potential OE - connection in - initiator state - machine - - -$Id: draft-richardson-ipsec-opportunistic.xml,v 1.1 2004/03/15 20:35:24 as Exp $ -]]></artwork> - - -<section title="Unauthenticated OE peer"> -<t> -Upon entering this state, the responder starts a DNS lookup for a KEY record for the -initiator. -The responder looks in the reverse-map for a KEY record for the initiator if the -initiator has offered an ID_IPV4_ADDR, and in the forward map if the -initiator has offered an ID_FQDN type. (See <xref target="RFC2407" /> section -4.6.2.1.) -</t> -<t> -The responder exits this state upon successful receipt of a KEY from DNS, and use of the key -to verify the signature of the initiator. -</t> - -<!-- -<t> -The public key that is retrieved should be stored in stable storage for an -administratively defined period of time, (typically several months if -possible). If a key has previously been stored on disk, then the returned key -should be compared to what has been received, and the key considered valid -only if they match. -</t> ---> - -<t> -Successful authentication of the peer results in a transition to the -authenticated OE Peer state. -</t> -<t> -Note that the unauthenticated OE peer state generally occurs in the middle of the key negotiation -protocol. It is really a form of pseudo-state. -</t> -</section> - -<section title="Authenticated OE Peer"> -<t> -The peer will eventually propose one or more phase 2 SAs. The responder uses the source and -destination address in the proposal to -finish instantiating the connection state -using the connection class table. -The responder MUST search for an identical connection object at this point. -</t> -<t> -If an identical connection is found, then the responder deletes the old instance, -and the new object makes a transition to the pending OE connection state. This means -that new ISAKMP connections with a given peer will always use the latest -instance, which is the correct one if the peer has rebooted in the interim. -</t> -<t> -If an identical connection is not found, then the responder makes the transition according to the -rules given for the initiator. -</t> -<t> -Note that if the initiator is in OE-paranoid mode and the responder is in -either always-clear-text or deny, then no communication is possible according -to policy. An implementation is permitted to create new types of policies -such as "accept OE but do not initiate it". This is a local matter. - </t> -</section> - -</section> <!-- "Keying state machine - responder" --> - -<section anchor="teardown" title="Renewal and teardown"> - <section title="Aging"> -<t> -A potentially unlimited number of tunnels may exist. In practice, only a few -tunnels are used during a period of time. Unused tunnels MUST, therefore, be -torn down. Detecting when tunnels are no longer in use is the subject of this section. -</t> - -<t> -There are two methods for removing tunnels: explicit deletion or expiry. -</t> - -<t> -Explicit deletion requires an IKE delete message. As the deletes -MUST be authenticated, both ends of the tunnel must maintain the -key channel (phase 1 ISAKMP SA). An implementation which refuses to either maintain or -recreate the keying channel SA will be unable to use this method. -</t> - -<t> -The tunnel expiry method simply allows the IKE daemon to -expire normally without attempting to re-key it. -</t> - -<t> -Regardless of which method is used to remove tunnels, the implementation MUST -a method to determine if the tunnel is still in use. The specifics are a -local matter, but the FreeS/WAN project uses the following criteria. These -criteria are currently implemented in the key management daemon, but could -also be implemented at the SPD layer using an idle timer. -</t> - -<t> -Set a short initial (soft) lifespan of 1 minute since many net flows last -only a few seconds. -</t> - -<t> -At the end of the lifespan, check to see if the tunnel was used by -traffic in either direction during the last 30 seconds. If so, assign a -longer tentative lifespan of 20 minutes after which, look again. If the -tunnel is not in use, then close the tunnel. -</t> - -<t> -The expiring state in the key management -system (see <xref target="expiring" />) implements these timeouts. -The timer above may be in the forwarding plane, -but then it must be re-settable. -</t> - -<t> -The tentative lifespan is independent of re-keying; it is just the time when -the tunnel's future is next considered. -(The term lifespan is used here rather than lifetime for this reason.) -Unlike re-keying, this tunnel use check is not costly and should happen -reasonably frequently. -</t> - -<t> -A multi-step back-off algorithm is not considered worth the effort here. -</t> - -<t> -If the security gateway and the client host are the -same and not a Bump-in-the-Stack or Bump-in-the-Wire implementation, tunnel -teardown decisions MAY pay attention to TCP connection status as reported -by the local TCP layer. A still-open TCP connection is almost a guarantee that more traffic is -expected. Closing of the only TCP connection through a tunnel is a -strong hint that no more traffic is expected. -</t> - -</section> <!-- "Aging" --> - -<section title="Teardown and cleanup"> - -<t> -Teardown should always be coordinated between the two ends of the tunnel by -interpreting and sending delete notifications. There is a -detailed sub-state in the expired connection state of the key manager that -relates to retransmits of the delete notifications, but this is considered to -be a keying system detail. -</t> - -<t> -On receiving a delete for the outbound SAs of a tunnel (or some subset of -them), tear down the inbound ones also and notify the remote end with a -delete. If the local system receives a delete for a tunnel which is no longer in -existence, then two delete messages have crossed paths. Ignore the delete. -The operation has already been completed. Do not generate any messages in this -situation. -</t> -<t> -Tunnels are to be considered as bidirectional entities, even though the -low-level protocols don't treat them this way. -</t> - -<t> -When the deletion is initiated locally, rather than as a -response to a received delete, send a delete for (all) the -inbound SAs of a tunnel. If the local system does not receive a responding delete -for the outbound SAs, try re-sending the original -delete. Three tries spaced 10 seconds apart seems a reasonable -level of effort. A failure of the other end to respond after 3 attempts, -indicates that the possibility of further communication is unlikely. Remove the outgoing SAs. -(The remote system may be a mobile node that is no longer present or powered on.) -</t> - -<t> -After re-keying, transmission should switch to using the new -outgoing SAs (ISAKMP or IPsec) immediately, and the old leftover -outgoing SAs should be cleared out promptly (delete should be sent -for the outgoing SAs) rather than waiting for them to expire. This -reduces clutter and minimizes confusion for the operator doing diagnostics. -</t> - -</section> - -</section> - -</section> <!-- "Specification" --> - -<section title="Impacts on IKE"> - - <section title="ISAKMP/IKE protocol"> - <t> - The IKE wire protocol needs no modifications. The major changes are - implementation issues relating to how the proposals are interpreted, and from - whom they may come. - </t> - <t> - As opportunistic encryption is designed to be useful between peers without - prior operator configuration, an IKE daemon must be prepared to negotiate - phase 1 SAs with any node. This may require a large amount of resources to - maintain cookie state, as well as large amounts of entropy for nonces, - cookies and so on. - </t> - <t> - The major changes to support opportunistic encryption are at the IKE daemon - level. These changes relate to handling of key acquisition requests, lookup - of public keys and TXT records, and interactions with firewalls and other - security facilities that may be co-resident on the same gateway. - </t> - </section> - - <section title="Gateway discovery process"> - <t> - In a typical configured tunnel, the address of SG-B is provided - via configuration. Furthermore, the mapping of an SPD entry to a gateway is - typically a 1:1 mapping. When the 0.0.0.0/0 SPD entry technique is used, then - the mapping to a gateway is determined by the reverse DNS records. - </t> - <t> - The need to do a DNS lookup and wait for a reply will typically introduce a - new state and a new event source (DNS replies) to IKE. Although a -synchronous DNS request can be implemented for proof of concept, experience -is that it can cause very high latencies when a queue of queries must -all timeout in series. - </t> - <t> - Use of an asynchronous DNS lookup will also permit overlap of DNS lookups with - some of the protocol steps. - </t> - </section> - - <section title="Self identification"> - <t> - SG-A will have to establish its identity. Use an - IPv4 ID in phase 1. - </t> - <t> There are many situations where the administrator of SG-A may not be - able to control the reverse DNS records for SG-A's public IP address. - Typical situations include dialup connections and most residential-type broadband Internet access - (ADSL, cable-modem) connections. In these situations, a fully qualified domain - name that is under the control of SG-A's administrator may be used - when acting as an initiator only. - The FQDN ID should be used in phase 1. See <xref target="fqdn" /> - for more details and restrictions. - </t> - </section> - - <section title="Public key retrieval process"> - <t> - Upon receipt of a phase 1 SA proposal with either an IPv4 (IPv6) ID or - an FQDN ID, an IKE daemon needs to examine local caches and - configuration files to determine if this is part of a configured tunnel. - If no configured tunnels are found, then the implementation should attempt to retrieve - a KEY record from the reverse DNS in the case of an IPv4/IPv6 ID, or - from the forward DNS in the case of FQDN ID. - </t> - <t> - It is reasonable that if other non-local sources of policy are used - (COPS, LDAP), they be consulted concurrently but some - clear ordering of policy be provided. Note that due to variances in - latency, implementations must wait for positive or negative replies from all sources - of policy before making any decisions. - </t> - </section> - - <section title="Interactions with DNSSEC"> - <t> - The implementation described (1.98) neither uses DNSSEC directly to - explicitly verify the authenticity of zone information, nor uses the NXT - records to provide authentication of the absence of a TXT or KEY - record. Rather, this implementation uses a trusted path to a DNSSEC - capable caching resolver. - </t> - <t> - To distinguish between an authenticated and an unauthenticated DNS - resource record, a stub resolver capable of returning DNSSEC - information MUST be used. - </t> - - </section> - -<!-- - <section title="Interactions with COPS"> - <t> - At this time there is no experience with implementations that interact - with COPS Policy Decision Points (PDP) <xref target="RFC2748" />. It is - suggested that it may be - appropriate for many of - the policy and discovery mechanisms outlined here to be done by a PDP. - In this context, the IKE daemon present in the Policy Enforcement Point - (PEP) may not need any modifications. - </t> - </section> ---> - - <section title="Required proposal types"> - - <section anchor="phase1id" title="Phase 1 parameters"> - <t> - Main mode MUST be used. - </t> - <t> - The initiator MUST offer at least one proposal using some combination - of: 3DES, HMAC-MD5 or HMAC-SHA1, DH group 2 or 5. Group 5 SHOULD be - proposed first. - <xref target="RFC3526" /> - </t> - <t> - The initiator MAY offer additional proposals, but the cipher MUST not - be weaker than 3DES. The initiator SHOULD limit the number of proposals - such that the IKE datagrams do not need to be fragmented. - </t> - <t> - The responder MUST accept one of the proposals. If any configuration - of the responder is required then the responder is not acting in an - opportunistic way. - </t> - <t> - The initiator SHOULD use an ID_IPV4_ADDR (ID_IPV6_ADDR for IPv6) of the external - interface of the initiator for phase 1. (There is an exception, see <xref - target="fqdn" />.) The authentication method MUST be RSA public key signatures. - The RSA key for the initiator SHOULD be placed into a DNS KEY record in - the reverse space of the initiator (i.e. using in-addr.arpa or - ip6.arpa). - </t> - </section> - - <section anchor="phase2id" title="Phase 2 parameters"> - <t> - The initiator MUST propose a tunnel between the ultimate - sender ("Alice" or "A") and ultimate recipient ("Bob" or "B") - using 3DES-CBC - mode, MD5 or SHA1 authentication. Perfect Forward Secrecy MUST be specified. - </t> - <t> - Tunnel mode MUST be used. - </t> - <t> - Identities MUST be ID_IPV4_ADDR_SUBNET with the mask being /32. - </t> - <t> - Authorization for the initiator to act on Alice's behalf is determined by - looking for a TXT record in the reverse-map at Alice's IP address. - </t> - <t> - Compression SHOULD NOT be mandatory. It MAY be offered as an option. - </t> - </section> - </section> - -</section> - -<section title="DNS issues"> - <section anchor="KEY" title="Use of KEY record"> - <t> - In order to establish their own identities, security gateways SHOULD publish - their public keys in their reverse DNS via - DNSSEC's KEY record. - See section 3 of <xref target="RFC2535">RFC 2535</xref>. - </t> - <t> - <preamble>For example:</preamble> - <artwork><![CDATA[ -KEY 0x4200 4 1 AQNJjkKlIk9...nYyUkKK8 -]]></artwork> - - <list style="hanging"> - <t hangText="0x4200:"> The flag bits, indicating that this key is prohibited - for confidentiality use (it authenticates the peer only, a separate - Diffie-Hellman exchange is used for - confidentiality), and that this key is associated with the non-zone entity - whose name is the RR owner name. No other flags are set.</t> - <t hangText="4:">This indicates that this key is for use by IPsec.</t> - <t hangText="1:">An RSA key is present.</t> - <t hangText="AQNJjkKlIk9...nYyUkKK8:">The public key of the host as described in <xref target="RFC3110" />.</t> - </list> - </t> - <t>Use of several KEY records allows for key rollover. The SIG Payload in - IKE phase 1 SHOULD be accepted if the public key given by any KEY RR - validates it. - </t> - </section> - - <section anchor="TXT" title="Use of TXT delegation record"> - <t> -If, for example, machine Alice wishes SG-A to act on her behalf, then -she publishes a TXT record to provide authorization for SG-A to act on -Alice's behalf. Similarly for Bob and SG-B. -</t> - -<t> -These records are located in the reverse DNS (in-addr.arpa or ip6.arpa) for their -respective IP addresses. The reverse DNS SHOULD be secured by DNSSEC. -DNSSEC is required to defend against active attacks. - </t> - <t> - If Alice's address is P.Q.R.S, then she can authorize another node to - act on her behalf by publishing records at: - <artwork><![CDATA[ -S.R.Q.P.in-addr.arpa - ]]></artwork> - </t> - - <t> - The contents of the resource record are expected to be a string that - uses the following syntax, as suggested in <xref target="RFC1464">RFC1464</xref>. - (Note that the reply to query may include other TXT resource - records used by other applications.) - - <figure anchor="txtformat" title="Format of reverse delegation record"> - <artwork><![CDATA[ -X-IPsec-Server(P)=A.B.C.D KEY - ]]></artwork> - </figure> - </t> - - where the record is formed by the following fields: - - <list style="hanging"> - <t hangText="P:"> Specifies a precedence for this record. This is - similar to MX record preferences. Lower numbers have stronger - preference. - </t> - - <t hangText="A.B.C.D:"> Specifies the IP address of the Security Gateway - for this client machine. - </t> - - <t hangText="KEY:"> Is the encoded RSA Public key of the Security - Gateway. The key is provided here to avoid a second DNS lookup. If this - field is absent, then a KEY resource record should be looked up in the - reverse-map of A.B.C.D. The key is transmitted in base64 format. - </t> - </list> - - <t> - The fields of the record MUST be separated by whitespace. This - MAY be: space, tab, newline, or carriage return. A space is preferred. - </t> - - <t> - In the case where Alice is located at a public address behind a - security gateway that has no fixed address (or no control over its - reverse-map), then Alice may delegate to a public key by domain name. - - <figure anchor="txtfqdnformat" - title="Format of reverse delegation record (FQDN version)"> - <artwork><![CDATA[ -X-IPsec-Server(P)=@FQDN KEY - ]]></artwork> - </figure> - </t> - - <list style="hanging"> - <t hangText="P:"> Is as above. - </t> - - <t hangText="FQDN:"> Specifies the FQDN that the Security Gateway - will identify itself with. - </t> - - <t hangText="KEY:"> Is the encoded RSA Public key of the Security - Gateway. </t> - </list> - - <t> - If there is more than one such TXT record with strongest (lowest - numbered) precedence, one Security Gateway is picked arbitrarily from - those specified in the strongest-preference records. - </t> - - <section title="Long TXT records"> - <t> - When packed into transport format, TXT records which are longer than 255 - characters are divided into smaller <character-strings>. - (See <xref target="RFC1035" /> section 3.3 and 3.3.14.) These MUST - be reassembled into a single string for processing. - Whitespace characters in the base64 encoding are to be ignored. - </t> - </section> - - <section title="Choice of TXT record"> - <t> - It has been suggested to use the KEY, OPT, CERT, or KX records - instead of a TXT record. None is satisfactory. - </t> - <t> The KEY RR has a protocol field which could be used to indicate a new protocol, -and an algorithm field which could be used to - indicate different contents in the key data. However, the KEY record - is clearly not intended for storing what are really authorizations, - it is just for identities. Other uses have been discouraged. - </t> - <t> OPT resource records, as defined in <xref target="RFC2671" /> are not - intended to be used for storage of information. They are not to be loaded, - cached or forwarded. They are, therefore, inappropriate for use here. - </t> - <t> - CERT records <xref target="RFC2538" /> can encode almost any set of - information. A custom type code could be used permitting any suitable - encoding to be stored, not just X.509. According to - the RFC, the certificate RRs are to be signed internally which may add undesirable -and unnecessary bulk. Larger DNS records may require TCP instead of UDP transfers. - </t> - <t> - At the time of protocol design, the CERT RR was not widely deployed and - could not be counted upon. Use of CERT records will be investigated, - and may be proposed in a future revision of this document. - </t> - <t> - KX records are ideally suited for use instead of TXT records, but had not been deployed at - the time of implementation. -<!-- Jakob Schlyter <j@crt.se> confirmed --> - </t> - </section> - </section> - - <section anchor="fqdn" title="Use of FQDN IDs"> - <t> - Unfortunately, not every administrator has control over the contents - of the reverse-map. Where the initiator (SG-A) has no suitable reverse-map, the - authorization record present in the reverse-map of Alice may refer to a - FQDN instead of an IP address. - </t> - <t> - In this case, the client's TXT record gives the fully qualified domain - name (FQDN) in place of its security gateway's IP address. - The initiator should use the ID_FQDN ID-payload in phase 1. - A forward lookup for a KEY record on the FQDN must yield the - initiator's public key. - </t> - <t> - This method can also be used when the external address of SG-A is - dynamic. - </t> - <t> - If SG-A is acting on behalf of Alice, then Alice must still delegate - authority for SG-A to do so in her reverse-map. When Alice and SG-A - are one and the same (i.e. Alice is acting as an end-node) then there - is no need for this when initiating only. </t> - <t>However, Alice must still delegate to herself if she wishes others to - initiate OE to her. See <xref target="txtfqdnformat" />. - </t> - < - </section> - -<section title="Key roll-over"> -<t> -Good cryptographic hygiene says that one should replace public/private key pairs -periodically. Some administrators may wish to do this as often as daily. Typical DNS -propagation delays are determined by the SOA Resource Record MINIMUM -parameter, which controls how long DNS replies may be cached. For reasonable -operation of DNS servers, administrators usually want this value to be at least several -hours, sometimes as a long as a day. This presents a problem - a new key MUST -not be used prior to it propagating through DNS. -</t> -<t> -This problem is dealt with by having the Security Gateway generate a new -public/private key pair at least MINIMUM seconds in advance of using it. It -then adds this key to the DNS (both as a second KEY record and in additional TXT -delegation records) at key generation time. Note: only one key is allowed in -each TXT record. -</t> -<t> -When authenticating, all gateways MUST have available all public keys -that are found in DNS for this entity. This permits the authenticating end -to check both the key for "today" and the key for "tomorrow". Note that it is -the end which is creating the signature (possesses the private key) that -determines which key is to be used. -</t> - - </section> -</section> - - -<section title="Network address translation interaction"> - <t> - There are no fundamentally new issues for implementing opportunistic encryption - in the presence of network address translation. Rather there are - only the regular IPsec issues with NAT traversal. - </t> - <t> - There are several situations to consider for NAT. - </t> - <section title="Co-located NAT/NAPT"> - <t> - If a security gateway is also performing network address translation on - behalf of an end-system, then the packet should be translated prior to - being subjected to opportunistic encryption. This is in contrast to - typically configured tunnels which often exist to bridge islands of - private network address space. The security gateway will use the translated source - address for phase 2, and so the responding security gateway will look up that address to - confirm SG-A's authorization. - </t> - <t> In the case of NAT (1:1), the address space into which the - translation is done MUST be globally unique, and control over the - reverse-map is assumed. - Placing of TXT records is possible. - </t> - <t> In the case of NAPT (m:1), the address will be the security - gateway itself. The ability to get - KEY and TXT records in place will again depend upon whether or not - there is administrative control over the reverse-map. This is - identical to situations involving a single host acting on behalf of - itself. - - FQDN style can be used to get around a lack of a reverse-map for - initiators only. - </t> - </section> - - <section title="Security Gateway behind NAT/NAPT"> - <t> - If there is a NAT or NAPT between the security gateways, then normal IPsec - NAT traversal problems occur. In addition to the transport problem - which may be solved by other mechanisms, there is the issue of - what phase 1 and phase 2 IDs to use. While FQDN could - be used during phase 1 for the security gateway, there is no appropriate ID for phase 2. - Due to the NAT, the end systems live in different IP address spaces. - </t> - </section> - - <section title="End System is behind a NAT/NAPT"> - <t> - If the end system is behind a NAT (perhaps SG-B), then there is, in fact, no way for - another end system to address a packet to this end system. - Not only is opportunistic encryption - impossible, but it is also impossible for any communication to - be initiate to the end system. It may be possible for this end - system to initiate in such communication. This creates an asymmetry, but this is common for - NAPT. - </t> - </section> -</section> - -<section title="Host implementations"> -<t> - When Alice and SG-A are components of the same system, they are - considered to be a host implementation. The packet sequence scenario remains unchanged. -</t> -<t> - Components marked Alice are the upper layers (TCP, UDP, the - application), and SG-A is the IP layer. -</t> -<t> - Note that tunnel mode is still required. -</t> -<t> - As Alice and SG-A are acting on behalf of themselves, no TXT based delegation - record is necessary for Alice to initiate. She can rely on FQDN in a - forward map. This is particularly attractive to mobile nodes such as - notebook computers at conferences. - To respond, Alice/SG-A will still need an entry in Alice's reverse-map. -</t> -</section> - -<section title="Multi-homing"> -<t> -If there are multiple paths between Alice and Bob (as illustrated in -the diagram with SG-D), then additional DNS records are required to establish -authorization. -</t> -<t> -In <xref target="networkdiagram" />, Alice has two ways to -exit her network: SG-A and SG-D. Previously SG-D has been ignored. Postulate -that there are routers between Alice and her set of security gateways -(denoted by the + signs and the marking of an autonomous system number for -Alice's network). Datagrams may, therefore, travel to either SG-A or SG-D en -route to Bob. -</t> -<t> -As long as all network connections are in good order, it does not matter how -datagrams exit Alice's network. When they reach either security gateway, the -security gateway will find the TXT delegation record in Bob's reverse-map, -and establish an SA with SG-B. -</t> -<t> -SG-B has no problem establishing that either of SG-A or SG-D may speak for -Alice, because Alice has published two equally weighted TXT delegation records: - <figure anchor="txtmultiexample" - title="Multiple gateway delegation example for Alice"> - <artwork><![CDATA[ -X-IPsec-Server(10)=192.1.1.5 AQMM...3s1Q== -X-IPsec-Server(10)=192.1.1.6 AAJN...j8r9== - ]]></artwork> - </figure> -</t> -<t> -Alice's routers can now do any kind of load sharing needed. Both SG-A and SG-D send datagrams addressed to Bob through -their tunnel to SG-B. -</t> -<t> -Alice's use of non-equal weight delegation records to show preference of one gateway over another, has relevance only when SG-B -is initiating to Alice. -</t> -<t> -If the precedences are the same, then SG-B has a more difficult time. It -must decide which of the two tunnels to use. SG-B has no information about -which link is less loaded, nor which security gateway has more cryptographic -resources available. SG-B, in fact, has no knowledge of whether both gateways -are even reachable. -</t> -<t> -The Public Internet's default-free zone may well know a good route to Alice, -but the datagrams that SG-B creates must be addressed to either SG-A or SG-D; -they can not be addressed to Alice directly. -</t> -<t> -SG-B may make a number of choices: -<list style="numbers"> -<t>It can ignore the problem and round robin among the tunnels. This - causes losses during times when one or the other security gateway is - unreachable. If this worries Alice, she can change the weights in her - TXT delegation records.</t> - -<t>It can send to the gateway from which it most recently received datagrams. - This assumes that routing and reachability are symmetrical.</t> - -<t>It can listen to BGP information from the Internet to decide which - system is currently up. This is clearly much more complicated, but if SG-B is already participating - in the BGP peering system to announce Bob, the results data may already - be available to it. </t> - -<t>It can refuse to negotiate the second tunnel. (It is unclear whether or -not this is even an option.)</t> - -<t>It can silently replace the outgoing portion of the first tunnel with the -second one while still retaining the incoming portions of both. SG-B can, -thus, accept datagrams from either SG-A or SG-D, but -send only to the gateway that most recently re-keyed with it.</t> -</list> -</t> - -<t> -Local policy determines which choice SG-B makes. Note that even if SG-B has perfect -knowledge about the reachability of SG-A and SG-D, Alice may not be reachable -from either of these security gateways because of internal reachability -issues. -</t> - -<t> -FreeS/WAN implements option 5. Implementing a different option is -being considered. The multi-homing aspects of OE are not well developed and may -be the subject of a future document. -</t> - -</section> - -<section title="Failure modes"> - <section title="DNS failures"> - <t> - If a DNS server fails to respond, local policy decides - whether or not to permit communication in the clear as embodied in - the connection classes in <xref target="initclasses" />. - It is easy to mount a denial of service attack on the DNS server - responsible for a particular network's reverse-map. - Such an attack may cause all communication with that network to go in - the clear if the policy is permissive, or fail completely - if the policy is paranoid. Please note that this is an active attack. - </t> - <t> - There are still many networks - that do not have properly configured reverse-maps. Further, if the policy is not to communicate, - the above denial of service attack isolates the target network. Therefore, the decision of whether -or not to permit communication in the clear MUST be a matter of local policy. - </t> - </section> - - <section title="DNS configured, IKE failures"> - <t> - DNS records claim that opportunistic encryption should - occur, but the target gateway either does not respond on port 500, or - refuses the proposal. This may be because of a crash or reboot, a - faulty configuration, or a firewall filtering port 500. - </t> - <t> - The receipt of ICMP port, host or network unreachable - messages indicates a potential problem, but MUST NOT cause communication - to fail - immediately. ICMP messages are easily forged by attackers. If such a - forgery caused immediate failure, then an active attacker could easily - prevent any - encryption from ever occurring, possibly preventing all communication. - </t> - <t> - In these situations a clear log should be produced - and local policy should dictate if communication is then - permitted in the clear. - </t> - </section> - - <section title="System reboots"> -<t> -Tunnels sometimes go down because the remote end crashes, -disconnects, or has a network link break. In general there is no -notification of this. Even in the event of a crash and successful reboot, -other SGs don't hear about it unless the rebooted SG has specific -reason to talk to them immediately. Over-quick response to temporary -network outages is undesirable. Note that a tunnel can be torn -down and then re-established without any effect visible to the user -except a pause in traffic. On the other hand, if one end reboots, -the other end can't get datagrams to it at all (except via -IKE) until the situation is noticed. So a bias toward quick -response is appropriate even at the cost of occasional -false alarms. -</t> - -<t> -A mechanism for recovery after reboot is a topic of current research and is not specified in this -document. -</t> - -<t> -A deliberate shutdown should include an attempt, using deletes, to notify all other SGs -currently connected by phase 1 SAs that communication is -about to fail. Again, a remote SG will assume this is a teardown. Attempts by the -remote SGs to negotiate new tunnels as replacements should be ignored. When possible, -SGs should attempt to preserve information about currently-connected SGs in non-volatile storage, so -that after a crash, an Initial-Contact can be sent to previous partners to -indicate loss of all previously established connections. -</t> - - </section> -</section> - -<!-- -<section title="Performance experiences"> - - Claudia> Is it useful to point out (or to clarify for our own discussion) any of the - Claudia> following: - - Claudia> * how much time this is likely to take on typical current hardware? - Claudia> * what steps are likely to be time consuming - Claudia> * how any added time could affect a typical transaction, such as hitting - Claudia> a web site - Claudia> * any ways to minimize such time delays - - <section title="Introduced latency"> - </section> - - <section title="Cryptographic performance"> - </section> - - <section title="Phase 1 SA performance"> - </section> - -</section> ---> - -<section title="Unresolved issues"> - <section title="Control of reverse DNS"> - <t> - The method of obtaining information by reverse DNS lookup causes - problems for people who cannot control their reverse DNS - bindings. This is an unresolved problem in this version, and is out - of scope. - </t> - </section> -</section> - -<section title="Examples"> - -<section title="Clear-text usage (permit policy)"> - -<t> -Two example scenarios follow. In the first example GW-A -(Gateway A) and GW-B (Gateway B) have always-clear-text policies, and in the second example they have an OE -policy. The clear-text policy serves as a reference for what occurs in -TCP/IP in the absence of Opportunistic Encryption. - -<t> -Alice wants to communicate with Bob. Perhaps she wants to retrieve a -web page from Bob's web server. In the absence of opportunistic -encryptors, the following events occur: -</t> - - <figure anchor="regulartiming" title="Timing of regular transaction"> - <artwork><![CDATA[ - Alice SG-A DNS SG-B Bob - Human or application - 'clicks' with a name. - (1) - - ------(2)--------------> - Application looks up - name in DNS to get - IP address. - - <-----(3)--------------- - Resolver returns "A" RR - to application with IP - address. - - (4) - Application starts a TCP session - or UDP session and OS sends - first datagram - - ----(5)-----> - Datagram is seen at first gateway - from Alice (SG-A). - - ----------(6)------> - Datagram traverses - network. - - ------(7)-----> - Datagram arrives - at Bob, is provided - to TCP. - - <------(8)------ - A reply is sent. - - <----------(9)------ - Datagram traverses - network. - <----(10)----- - Alice receives - answer. - - (11)-----------> - A second exchange - occurs. - ----------(12)-----> - --------------> - <--------------- - <------------------- - <------------- - ]]></artwork> -</figure> - -</t> -</section> - -<section title="Opportunistic encryption"> - -<t> -In the presence of properly configured opportunistic encryptors, the -event list is extended. Only changes are annotated. -</t> - -<t>The following symbols are used in the time-sequence diagram</t> - -<t> -<list style="hanging"> - <t hangText="-"> A single dash represents clear-text datagrams.</t> - <t hangText="="> An equals sign represents phase 2 (IPsec) cipher-text - datagrams.</t> - <t hangText="~"> A single tilde represents clear-text phase 1 datagrams.</t> - <t hangText="#"> A hash sign represents phase 1 (IKE) cipher-text - datagrams.</t> -</list> -</t> - -<t> -<figure anchor="opportunistictiming" title="Timing of opportunistic encryption transaction"> - <artwork><![CDATA[ - Alice SG-A DNS SG-B Bob - (1) - ------(2)--------------> - <-----(3)--------------- - (4)----(5)----->+ - SG-A sees datagram - to new target and - saves it as "first" - - ----(5B)-> - SG-A asks DNS - for TXT RR. - - <---(5C)-- - DNS returns TXT RR. - - ~~~~~~~~~~~~~(5D)~~~> - initial IKE main mode - packet is sent. - - <~~~~~~~~~~~~(5E1)~~~ - ~~~~~~~~~~~~~(5E2)~~> - <~~~~~~~~~~~~(5E3)~~~ - IKE phase 1 - privacy. - - #############(5E4)##> - SG-A sends ID to SG-B - <----(5F1)-- - SG-B asks DNS - for SG-A's public - KEY - -----(5F2)-> - DNS provides KEY RR. - SG-B authenticates SG-A - - <############(5E5)### - IKE phase 1 - complete - - #############(5G1)##> - IKE phase 2 - Alice<->Bob - tunnel is proposed. - - <----(5H1)-- - SG-B asks DNS for - Alice's TXT record. - -----(5H2)-> - DNS replies with TXT - record. SG-B checks - SG-A's authorization. - - <############(5G2)### - SG-B accepts proposal. - - #############(5G3)##> - SG-A confirms. - - ============(6)====> - SG-A sends "first" - packet in new IPsec - SA. - ------(7)-----> - packet is decrypted - and forward to Bob. - <------(8)------ - <==========(9)====== - return packet also - encrypted. - <-----(10)---- - - (11)-----------> - a second packet - is sent by Alice - ==========(12)=====> - existing tunnel is used - --------------> - <--------------- - <=================== - <------------- - ]]></artwork> -</figure> - -</t> - - <t> - For the purposes of this section, we will describe only the changes that - occur between <xref target="regulartiming" /> and - <xref target="opportunistictiming" />. This corresponds to time points 5, 6, 7, 9 and 10 on the list above. - </t> - -<list style="symbols"> - <t> - At point (5), SG-A intercepts the datagram because this source/destination pair lacks a policy -(the non-existent policy state). SG-A creates a hold policy, and buffers the datagram. SG-A requests keys from the keying daemon. - </t> - - <t> - SG-A's IKE daemon, having looked up the source/destination pair in the connection - class list, creates a new Potential OE connection instance. SG-A starts DNS - queries. - </t> - </section> - - <section title="(5C) DNS returns TXT record(s)"> - - <t> - DNS returns properly formed TXT delegation records, and SG-A's IKE daemon - causes this instance to make a transition from Potential OE connection to Pending OE - connection. - </t> - - <t> - Using the example above, the returned record might contain: - - <figure anchor="txtexample" - title="Example of reverse delegation record for Bob"> - <artwork><![CDATA[ -X-IPsec-Server(10)=192.1.1.5 AQMM...3s1Q== - ]]></artwork> - </figure> - with SG-B's IP address and public key listed. - </t> - - </section> - - <section title="(5D) Initial IKE main mode packet goes out"> - <t>Upon entering Pending OE connection, SG-A sends the initial ISAKMP - message with proposals. See <xref target="phase1id" />. - </t> - </section> - - <section title="(5E1) Message 2 of phase 1 exchange"> - <t> - SG-B receives the message. A new connection instance is created in the - unauthenticated OE peer state. - </t> - </section> - - <section title="(5E2) Message 3 of phase 1 exchange"> - <t> - SG-A sends a Diffie-Hellman exponent. This is an internal state of the - keying daemon. - </t> - </section> - - <section title="(5E3) Message 4 of phase 1 exchange"> - <t> - SG-B responds with a Diffie-Hellman exponent. This is an internal state of the - keying protocol. - </t> - </section> - - <section title="(5E4) Message 5 of phase 1 exchange"> - <t> - SG-A uses the phase 1 SA to send its identity under encryption. - The choice of identity is discussed in <xref target="phase1id" />. - This is an internal state of the keying protocol. - </t> - </section> - - <section title="(5F1) Responder lookup of initiator key"> - <t> - SG-B asks DNS for the public key of the initiator. - DNS looks for a KEY record by IP address in the reverse-map. - That is, a KEY resource record is queried for 4.1.1.192.in-addr.arpa - (recall that SG-A's external address is 192.1.1.4). - SG-B uses the resulting public key to authenticate the initiator. See <xref - target="KEY" /> for further details. - </t> - </section> - -<section title="(5F2) DNS replies with public key of initiator"> -<t> -Upon successfully authenticating the peer, the connection instance makes a -transition to authenticated OE peer on SG-B. -</t> -<t> -The format of the TXT record returned is described in -<xref target="TXT" />. -</t> -</section> - - <section title="(5E5) Responder replies with ID and authentication"> - <t> - SG-B sends its ID along with authentication material. This is an internal - state for the keying protocol. - </t> - </section> - - <section title="(5G) IKE phase 2"> - <section title="(5G1) Initiator proposes tunnel"> - <t> - Having established mutually agreeable authentications (via KEY) and - authorizations (via TXT), SG-A proposes to create an IPsec tunnel for - datagrams transiting from Alice to Bob. This tunnel is established only for - the Alice/Bob combination, not for any subnets that may be behind SG-A and SG-B. - </t> - </section> - - <section title="(5H1) Responder determines initiator's authority"> - <t> - While the identity of SG-A has been established, its authority to - speak for Alice has not yet been confirmed. SG-B does a reverse - lookup on Alice's address for a TXT record. - </t> - <t>Upon receiving this specific proposal, SG-B's connection instance - makes a transition into the potential OE connection state. SG-B may already have an - instance, and the check is made as described above.</t> - </section> - - <section title="(5H2) DNS replies with TXT record(s)"> - <t> - The returned key and IP address should match that of SG-A. - </t> - </section> - - <section title="(5G2) Responder agrees to proposal"> - <t> - Should additional communication occur between, for instance, Dave and Bob using - SG-A and SG-B, a new tunnel (phase 2 SA) would be established. The phase 1 SA - may be reusable. - </t> - <t>SG-A, having successfully keyed the tunnel, now makes a transition from - Pending OE connection to Keyed OE connection. - </t> - <t>The responder MUST setup the inbound IPsec SAs before sending its reply.</t> - </section> - - <section title="(5G3) Final acknowledgment from initiator"> - <t> - The initiator agrees with the responder's choice and sets up the tunnel. - The initiator sets up the inbound and outbound IPsec SAs. - </t> - <t> - The proper authorization returned with keys prompts SG-B to make a transition - to the keyed OE connection state. - </t> - <t>Upon receipt of this message, the responder may now setup the outbound - IPsec SAs.</t> - </section> - </section> - - <section title="(6) IPsec succeeds, and sets up tunnel for communication between Alice and Bob"> - <t> - SG-A sends the datagram saved at step (5) through the newly created - tunnel to SG-B, where it gets decrypted and forwarded. - Bob receives it at (7) and replies at (8). - </t> - </section> - - <section title="(9) SG-B already has tunnel up with G1 and uses it"> - <t> - At (9), SG-B has already established an SPD entry mapping Bob->Alice via a - tunnel, so this tunnel is simply applied. The datagram is encrypted to SG-A, - decrypted by SG-A and passed to Alice at (10). - </t> - - </section> -</section> <!-- OE example --> - -</section> <!-- Examples --> - -<section anchor="securityconsiderations" title="Security considerations"> - - <section title="Configured vs opportunistic tunnels"> -<t> - Configured tunnels are those which are setup using bilateral mechanisms: exchanging -public keys (raw RSA, DSA, PKIX), pre-shared secrets, or by referencing keys that -are in known places (distinguished name from LDAP, DNS). These keys are then used to -configure a specific tunnel. -</t> -<t> -A pre-configured tunnel may be on all the time, or may be keyed only when needed. -The end points of the tunnel are not necessarily static: many mobile -applications (road warrior) are considered to be configured tunnels. -</t> -<t> -The primary characteristic is that configured tunnels are assigned specific -security properties. They may be trusted in different ways relating to exceptions to -firewall rules, exceptions to NAT processing, and to bandwidth or other quality of service restrictions. -</t> -<t> -Opportunistic tunnels are not inherently trusted in any strong way. They are -created without prior arrangement. As the two parties are strangers, there -MUST be no confusion of datagrams that arrive from opportunistic peers and -those that arrive from configured tunnels. A security gateway MUST take care -that an opportunistic peer can not impersonate a configured peer. -</t> -<t> -Ingress filtering MUST be used to make sure that only datagrams authorized by -negotiation (and the concomitant authentication and authorization) are -accepted from a tunnel. This is to prevent one peer from impersonating another. -</t> -<t> -An implementation suggestion is to treat opportunistic tunnel -datagrams as if they arrive on a logical interface distinct from other -configured tunnels. As the number of opportunistic tunnels that may be -created automatically on a system is potentially very high, careful attention -to scaling should be taken into account. -</t> -<t> -As with any IKE negotiation, opportunistic encryption cannot be secure -without authentication. Opportunistic encryption relies on DNS for its -authentication information and, therefore, cannot be fully secure without -a secure DNS. Without secure DNS, opportunistic encryption can protect against passive -eavesdropping but not against active man-in-the-middle attacks. -</t> - </section> - - <section title="Firewalls versus Opportunistic Tunnels"> -<t> - Typical usage of per datagram access control lists is to implement various -kinds of security gateways. These are typically called "firewalls". -</t> -<t> - Typical usage of a virtual private network (VPN) within a firewall is to -bypass all or part of the access controls between two networks. Additional -trust (as outlined in the previous section) is given to datagrams that arrive -in the VPN. -</t> -<t> - Datagrams that arrive via opportunistically configured tunnels MUST not be -trusted. Any security policy that would apply to a datagram arriving in the -clear SHOULD also be applied to datagrams arriving opportunistically. -</t> - </section> - - <section title="Denial of service"> -<t> - There are several different forms of denial of service that an implementor - should concern themselves with. Most of these problems are shared with - security gateways that have large numbers of mobile peers (road warriors). -</t> -<t> - The design of ISAKMP/IKE, and its use of cookies, defend against many kinds - of denial of service. Opportunism changes the assumption that if the phase 1 (ISAKMP) - SA is authenticated, that it was worthwhile creating. Because the gateway will communicate with any machine, it is - possible to form phase 1 SAs with any machine on the Internet. -</t> - -</section> -</section> - -<section title="IANA Considerations"> -<t> - There are no known numbers which IANA will need to manage. -</t> -</section> - -<section title="Acknowledgments"> -<t> - Substantive portions of this document are based upon previous work by - Henry Spencer. -</t> -<t> - Thanks to Tero Kivinen, Sandy Harris, Wes Hardarker, Robert Moskowitz, - Jakob Schlyter, Bill Sommerfeld, John Gilmore and John Denker for their - comments and constructive criticism. -</t> -<t> - Sandra Hoffman and Bill Dickie did the detailed proof reading and editing. -</t> -</section> - -</middle> - -<back> -<references title="Normative references"> -<?rfc include="reference.OEspec" ?> -<!-- renumber according to reference order --> -<?rfc include="reference.RFC.0791" ?> -<?rfc include="reference.RFC.1009" ?> -<?rfc include="reference.RFC.1984" ?> -<?rfc include="reference.RFC.2119" ?> -<!-- IPsec --> -<?rfc include="reference.RFC.2367" ?> -<?rfc include="reference.RFC.2401" ?> -<?rfc include="reference.RFC.2407" ?> -<?rfc include="reference.RFC.2408" ?> -<?rfc include="reference.RFC.2409" ?> -<!-- MODPGROUPS --> -<?rfc include="reference.RFC.3526" ?> -<!-- DNSSEC --> -<?rfc include="reference.RFC.1034" ?> -<?rfc include="reference.RFC.1035" ?> -<?rfc include="reference.RFC.2671" ?> -<?rfc include="reference.RFC.1464" ?> -<?rfc include="reference.RFC.2535" ?> -<?rfc include="reference.RFC.3110" ?> -<?rfc include="reference.RFC.2538" ?> -<!-- COPS --> -<?rfc include="reference.RFC.2748" ?> -<!-- NAT --> -<?rfc include="reference.RFC.2663" ?> -</references> -<!-- <references title="Non-normative references"> --> -<!-- ESPUDP --> -<!-- <?rfc include="reference.ESPUDP" ?> --> -<!-- </references> --> -</back> -</rfc> -<!-- - $Id: draft-richardson-ipsec-opportunistic.xml,v 1.1 2004/03/15 20:35:24 as Exp $ - - $Log: draft-richardson-ipsec-opportunistic.xml,v $ - Revision 1.1 2004/03/15 20:35:24 as - added files from freeswan-2.04-x509-1.5.3 - - Revision 1.33 2003/06/30 03:19:59 mcr - timing-diagram with inline explanation. - - Revision 1.32 2003/06/30 01:57:44 mcr - initial edits per-Bob Braden. - - Revision 1.31 2003/05/26 19:31:23 mcr - updates to drafts - IPSEC RR - SC versions, and RFC3526 - reference in OE draft. - - Revision 1.30 2003/05/21 15:42:34 mcr - updates due to publication of RFC 3526. - - Revision 1.29 2003/01/17 16:22:55 mcr - rev 11 of OE draft. - - Revision 1.28 2002/07/25 19:27:31 mcr - added DHR's minor edits. - - Revision 1.27 2002/07/21 16:26:26 mcr - slides from presentation at OLS - draft-10 of OE draft. - - Revision 1.26 2002/07/16 03:46:53 mcr - second edits from Sandra. - - Revision 1.25 2002/07/16 03:36:14 mcr - removed HS from authors list - updated reference inclusion to use <?rfc-include directive. - Revision 1.24 2002/07/11 02:08:21 mcr - updated XML file from Sandra - - Revision 1.23 2002/06/06 17:18:53 mcr - spellcheck. - - Revision 1.22 2002/06/06 17:14:19 mcr - results of hand-editing session from May 28th. - This is FINAL OE draft. - - Revision 1.21 2002/06/06 02:25:44 mcr - results of hand-editing session from May 28th. - This is FINAL OE draft. - - Revision 1.20 2002/05/24 03:28:37 mcr - changes as requested by RFC editor. - - Revision 1.19 2002/04/09 16:01:05 mcr - comments from PHB. - - Revision 1.18 2002/04/08 02:14:34 mcr - RGBs changes to rev6. - - Revision 1.17 2002/03/12 21:23:55 mcr - adjusted definition of default-free zone. - moved text on key rollover from format description to new - section. - - Revision 1.16 2002/02/22 01:23:21 mcr - revisions from MCR (2002/2/18) and net. - - Revision 1.15 2002/02/21 20:44:12 mcr - extensive from DHR. - - Revision 1.14 2002/02/10 16:20:39 mcr - -05 draft. Many revisions to do "OE system in world of OE systems" - view of the universe. - - Revision 1.13 2001/12/20 04:35:22 mcr - fixed reference to rfc1984. - - Revision 1.12 2001/12/20 03:35:19 mcr - comments from Henry, Tero, and Sandy. - - Revision 1.11 2001/12/19 07:26:22 mcr - added comment about KX records. - - Revision 1.10 2001/11/09 04:28:10 mcr - fixed some typos with XML, and one s/SG-B/SG-D/. - - Revision 1.9 2001/11/09 04:07:13 mcr - expanded section 10: multihoming, with an example. - - Revision 1.8 2001/11/09 02:16:51 mcr - added lifetime/lifespan definitions. - moved example from 5B to 5C. - added reference to phase 1 IDs to 5D. - cleared up text in aging section. - added text about delegation of DNSSEC activity to a DNS server. - spelt out DH group names. - added text about ignoring TXT records unless DNSSEC is deployed (somerfeld) - added example of TXT delegation using FQDN. - clarified some text in NAT interaction section. - clarified absense of TXT record need for host implementation - - Revision 1.7 2001/11/08 23:09:37 mcr - changed revision of draft to 03. - - Revision 1.6 2001/11/08 19:37:14 mcr - fixed some formatting of Aging section. - - Revision 1.5 2001/11/08 19:19:30 mcr - fixed address for DHR, updated address for MCR, - added reference to original HS/DHR OE specification paper. - - Revision 1.4 2001/11/08 19:08:24 mcr - section 10, "Renewal and Teardown" added moved between 4/5, and - slightly rewritten. - - Revision 1.3 2001/11/08 18:56:34 mcr - sections 4.2, 5.6, 5.7.1 and 6.2 edited as per HS. - section 10, "Renewal and Teardown" added. - section 11, "Failure modes" completed. - - Revision 1.2 2001/11/05 20:31:31 mcr - added section from OE spec on aging and teardown. - - Revision 1.1 2001/11/05 04:27:58 mcr - OE draft added to documentation. - - Revision 1.12 2001/10/10 01:12:31 mcr - removed impact on DNS servers section. - removed nested comments. - adjusted data of issue - - Revision 1.11 2001/09/17 02:55:50 mcr - outline is now stable. - - Revision 1.5 2001/08/19 02:53:32 mcr - version 00d formatted. - - Revision 1.10 2001/08/19 02:34:04 mcr - version 00d formatted. - - Revision 1.9 2001/08/19 02:21:54 mcr - version 00d - - Revision 1.8 2001/07/20 19:07:06 mcr - commented out section 1.1 - - Revision 1.7 2001/07/20 14:14:22 mcr - HS and HD comments. - - Revision 1.6 2001/07/19 00:56:50 mcr - version 00b. - - Revision 1.5 2001/07/12 23:57:07 mcr - OE ID, 00. - - -!> diff --git a/doc/src/draft-richardson-ipsec-rr.html b/doc/src/draft-richardson-ipsec-rr.html deleted file mode 100644 index 08473104f..000000000 --- a/doc/src/draft-richardson-ipsec-rr.html +++ /dev/null @@ -1,659 +0,0 @@ -<html><head><title>A method for storing IPsec keying material in DNS.</title> -<STYLE type='text/css'> - .title { color: #990000; font-size: 22px; line-height: 22px; font-weight: bold; text-align: right; - font-family: helvetica, arial, sans-serif } - .filename { color: #666666; font-size: 18px; line-height: 28px; font-weight: bold; text-align: right; - font-family: helvetica, arial, sans-serif } - p.copyright { color: #000000; font-size: 10px; - font-family: verdana, charcoal, helvetica, arial, sans-serif } - p { margin-left: 2em; margin-right: 2em; } - li { margin-left: 3em; } - ol { margin-left: 2em; margin-right: 2em; } - ul.text { margin-left: 2em; margin-right: 2em; } - pre { margin-left: 3em; color: #333333 } - ul.toc { color: #000000; line-height: 16px; - font-family: verdana, charcoal, helvetica, arial, sans-serif } - H3 { color: #333333; font-size: 16px; line-height: 16px; font-family: helvetica, arial, sans-serif } - H4 { color: #000000; font-size: 14px; font-family: helvetica, arial, sans-serif } - TD.header { color: #ffffff; font-size: 10px; font-family: arial, helvetica, san-serif; valign: top } - TD.author-text { color: #000000; font-size: 10px; - font-family: verdana, charcoal, helvetica, arial, sans-serif } - TD.author { color: #000000; font-weight: bold; margin-left: 4em; font-size: 10px; font-family: verdana, charcoal, helvetica, arial, sans-serif } - A:link { color: #990000; font-weight: bold; - font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif } - A:visited { color: #333333; font-weight: bold; - font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif } - A:name { color: #333333; font-weight: bold; - font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif } - .link2 { color:#ffffff; font-weight: bold; text-decoration: none; - font-family: monaco, charcoal, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif; - font-size: 9px } - .RFC { color:#666666; font-weight: bold; text-decoration: none; - font-family: monaco, charcoal, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif; - font-size: 9px } - .hotText { color:#ffffff; font-weight: normal; text-decoration: none; - font-family: charcoal, monaco, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif; - font-size: 9px } -</style> -</head> -<body bgcolor="#ffffff" text="#000000" alink="#000000" vlink="#666666" link="#990000"> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<table width="66%" border="0" cellpadding="0" cellspacing="0"><tr><td><table width="100%" border="0" cellpadding="2" cellspacing="1"> -<tr valign="top"><td width="33%" bgcolor="#666666" class="header">IPSECKEY WG</td><td width="33%" bgcolor="#666666" class="header">M. Richardson</td></tr> -<tr valign="top"><td width="33%" bgcolor="#666666" class="header">Internet-Draft</td><td width="33%" bgcolor="#666666" class="header">SSW</td></tr> -<tr valign="top"><td width="33%" bgcolor="#666666" class="header">Expires: March 4, 2004</td><td width="33%" bgcolor="#666666" class="header">September 4, 2003</td></tr> -</table></td></tr></table> -<div align="right"><font face="monaco, MS Sans Serif" color="#990000" size="+3"><b><br><span class="title">A method for storing IPsec keying material in DNS.</span></b></font></div> -<div align="right"><font face="monaco, MS Sans Serif" color="#666666" size="+2"><b><span class="filename">draft-ietf-ipseckey-rr-07.txt</span></b></font></div> -<font face="verdana, helvetica, arial, sans-serif" size="2"> - -<h3>Status of this Memo</h3> -<p> -This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026.</p> -<p> -Internet-Drafts are working documents of the Internet Engineering -Task Force (IETF), its areas, and its working groups. -Note that other groups may also distribute working documents as -Internet-Drafts.</p> -<p> -Internet-Drafts are draft documents valid for a maximum of six months -and may be updated, replaced, or obsoleted by other documents at any time. -It is inappropriate to use Internet-Drafts as reference material or to cite -them other than as "work in progress."</p> -<p> -The list of current Internet-Drafts can be accessed at -<a href='http://www.ietf.org/ietf/1id-abstracts.txt'>http://www.ietf.org/ietf/1id-abstracts.txt</a>.</p> -<p> -The list of Internet-Draft Shadow Directories can be accessed at -<a href='http://www.ietf.org/shadow.html'>http://www.ietf.org/shadow.html</a>.</p> -<p> -This Internet-Draft will expire on March 4, 2004.</p> - -<h3>Copyright Notice</h3> -<p> -Copyright (C) The Internet Society (2003). All Rights Reserved.</p> - -<h3>Abstract</h3> - -<p> -This document describes a new resource record for DNS. This record may be -used to store public keys for use in IPsec systems. - -</p> -<p> -This record replaces the functionality of the sub-type #1 of the KEY Resource -Record, which has been obsoleted by RFC3445. - -</p><a name="toc"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<h3>Table of Contents</h3> -<ul compact class="toc"> -<b><a href="#anchor1">1.</a> -Introduction<br></b> -<b><a href="#anchor2">1.1</a> -Overview<br></b> -<b><a href="#anchor3">1.2</a> -Usage Criteria<br></b> -<b><a href="#anchor4">2.</a> -Storage formats<br></b> -<b><a href="#anchor5">2.1</a> -IPSECKEY RDATA format<br></b> -<b><a href="#anchor6">2.2</a> -RDATA format - precedence<br></b> -<b><a href="#algotype">2.3</a> -RDATA format - algorithm type<br></b> -<b><a href="#gatewaytype">2.4</a> -RDATA format - gateway type<br></b> -<b><a href="#anchor7">2.5</a> -RDATA format - gateway<br></b> -<b><a href="#anchor8">2.6</a> -RDATA format - public keys<br></b> -<b><a href="#anchor9">3.</a> -Presentation formats<br></b> -<b><a href="#anchor10">3.1</a> -Representation of IPSECKEY RRs<br></b> -<b><a href="#anchor11">3.2</a> -Examples<br></b> -<b><a href="#anchor12">4.</a> -Security Considerations<br></b> -<b><a href="#anchor13">4.1</a> -Active attacks against unsecured IPSECKEY resource records<br></b> -<b><a href="#anchor14">5.</a> -IANA Considerations<br></b> -<b><a href="#anchor15">6.</a> -Acknowledgments<br></b> -<b><a href="#rfc.references1">§</a> -Normative references<br></b> -<b><a href="#rfc.references2">§</a> -Non-normative references<br></b> -<b><a href="#rfc.authors">§</a> -Author's Address<br></b> -<b><a href="#rfc.copyright">§</a> -Full Copyright Statement<br></b> -</ul> -<br clear="all"> - -<a name="anchor1"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.1"></a><h3>1. Introduction</h3> - -<p> - The type number for the IPSECKEY RR is TBD. - -</p> -<a name="rfc.section.1.1"></a><h4><a name="anchor2">1.1</a> Overview</h4> - -<p> - The IPSECKEY resource record (RR) is used to publish a public key that is - to be associated with a Domain Name System (DNS) name for use with the - IPsec protocol suite. This can be the public key of a host, - network, or application (in the case of per-port keying). - -</p> -<p> - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL - NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and - "OPTIONAL" in this document are to be interpreted as described in - RFC2119 <a href="#RFC2119">[8]</a>. - -</p> -<a name="rfc.section.1.2"></a><h4><a name="anchor3">1.2</a> Usage Criteria</h4> - -<p> - An IPSECKEY resource record SHOULD be used in combination with DNSSEC -unless some other means of authenticating the IPSECKEY resource record -is available. - -</p> -<p> - It is expected that there will often be multiple IPSECKEY resource - records at the same name. This will be due to the presence - of multiple gateways and the need to rollover keys. - - -</p> -<p> - This resource record is class independent. - -</p> -<a name="anchor4"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.2"></a><h3>2. Storage formats</h3> - -<a name="rfc.section.2.1"></a><h4><a name="anchor5">2.1</a> IPSECKEY RDATA format</h4> - -<p> - The RDATA for an IPSECKEY RR consists of a precedence value, a public key, - algorithm type, and an optional gateway address. - -</p></font><pre> - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | precedence | gateway type | algorithm | gateway | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------+ + - ~ gateway ~ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | / - / public key / - / / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| -</pre><font face="verdana, helvetica, arial, sans-serif" size="2"> - -<a name="rfc.section.2.2"></a><h4><a name="anchor6">2.2</a> RDATA format - precedence</h4> - -<p> -This is an 8-bit precedence for this record. This is interpreted in -the same way as the PREFERENCE field described in section -3.3.9 of RFC1035 <a href="#RFC1035">[2]</a>. - -</p> -<p> -Gateways listed in IPSECKEY records with lower precedence are -to be attempted first. Where there is a tie in precedence, the order -should be non-deterministic. - -</p> -<a name="rfc.section.2.3"></a><h4><a name="algotype">2.3</a> RDATA format - algorithm type</h4> - -<p> -The algorithm type field identifies the public key's cryptographic -algorithm and determines the format of the public key field. - -</p> -<p> -A value of 0 indicates that no key is present. - -</p> -<p> -The following values are defined: - -<blockquote class="text"><dl> -<dt>1</dt> -<dd>A DSA key is present, in the format defined in RFC2536 <a href="#RFC2536">[11]</a> -</dd> -<dt>2</dt> -<dd>A RSA key is present, in the format defined in RFC3110 <a href="#RFC3110">[12]</a> -</dd> -</dl></blockquote><p> -</p> -<a name="rfc.section.2.4"></a><h4><a name="gatewaytype">2.4</a> RDATA format - gateway type</h4> - -<p> -The gateway type field indicates the format of the information that -is stored in the gateway field. - -</p> -<p> -The following values are defined: - -<blockquote class="text"><dl> -<dt>0</dt> -<dd>No gateway is present -</dd> -<dt>1</dt> -<dd>A 4-byte IPv4 address is present -</dd> -<dt>2</dt> -<dd>A 16-byte IPv6 address is present -</dd> -<dt>3</dt> -<dd>A wire-encoded domain name is present. The wire-encoded -format is self-describing, so the length is implicit. The domain name -MUST NOT be compressed. -</dd> -</dl></blockquote><p> -</p> -<a name="rfc.section.2.5"></a><h4><a name="anchor7">2.5</a> RDATA format - gateway</h4> - -<p> -The gateway field indicates a gateway to which an IPsec tunnel may be -created in order to reach the entity named by this resource record. - -</p> -<p> -There are three formats: - -</p> -<p> -A 32-bit IPv4 address is present in the gateway field. The data -portion is an IPv4 address as described in section 3.4.1 of -<a href="#RFC1035">RFC1035</a>[2]. This is a 32-bit number in network byte order. - -</p> -<p>A 128-bit IPv6 address is present in the gateway field. -The data portion is an IPv6 address as described in section 2.2 of -<a href="#RFC1886">RFC1886</a>[7]. This is a 128-bit number in network byte order. - -</p> -<p> -The gateway field is a normal wire-encoded domain name, as described -in section 3.3 of RFC1035 <a href="#RFC1035">[2]</a>. Compression MUST NOT be used. - -</p> -<a name="rfc.section.2.6"></a><h4><a name="anchor8">2.6</a> RDATA format - public keys</h4> - -<p> -Both of the public key types defined in this document (RSA and DSA) -inherit their public key formats from the corresponding KEY RR formats. -Specifically, the public key field contains the algorithm-specific -portion of the KEY RR RDATA, which is all of the KEY RR DATA after the -first four octets. This is the same portion of the KEY RR that must be -specified by documents that define a DNSSEC algorithm. -Those documents also specify a message digest to be used for generation -of SIG RRs; that specification is not relevant for IPSECKEY RR. - -</p> -<p> -Future algorithms, if they are to be used by both DNSSEC (in the KEY -RR) and IPSECKEY, are likely to use the same public key encodings in -both records. Unless otherwise specified, the IPSECKEY public key -field will contain the algorithm-specific portion of the KEY RR RDATA -for the corresponding algorithm. The algorithm must still be -designated for use by IPSECKEY, and an IPSECKEY algorithm type number -(which might be different than the DNSSEC algorithm number) must be -assigned to it. - -</p> -<p>The DSA key format is defined in RFC2536 <a href="#RFC2536">[11]</a> -</p> -<p>The RSA key format is defined in RFC3110 <a href="#RFC3110">[12]</a>, -with the following changes: -</p> -<p> -The earlier definition of RSA/MD5 in RFC2065 limited the exponent and -modulus to 2552 bits in length. RFC3110 extended that limit to 4096 -bits for RSA/SHA1 keys. The IPSECKEY RR imposes no length limit on -RSA public keys, other than the 65535 octet limit imposed by the -two-octet length encoding. This length extension is applicable only -to IPSECKEY and not to KEY RRs. - -</p> -<a name="anchor9"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.3"></a><h3>3. Presentation formats</h3> - -<a name="rfc.section.3.1"></a><h4><a name="anchor10">3.1</a> Representation of IPSECKEY RRs</h4> - -<p> - IPSECKEY RRs may appear in a zone data master file. - The precedence, gateway type and algorithm and gateway fields are REQUIRED. - The base64 encoded public key block is OPTIONAL; if not present, - then the public key field of the resource record MUST be construed - as being zero octets in length. - -</p> -<p> - The algorithm field is an unsigned integer. No mnemonics are defined. - -</p> -<p> - If no gateway is to be indicated, then the gateway type field MUST - be zero, and the gateway field MUST be "." - -</p> -<p> - The Public Key field is represented as a Base64 encoding of the - Public Key. Whitespace is allowed within the Base64 text. For a - definition of Base64 encoding, see -<a href="#RFC1521">RFC1521</a>[3] Section 5.2. - -</p> -<p> - The general presentation for the record as as follows: -</p> -</font><pre> -IN IPSECKEY ( precedence gateway-type algorithm - gateway base64-encoded-public-key ) -</pre><font face="verdana, helvetica, arial, sans-serif" size="2"> -<p> - -</p> -<a name="rfc.section.3.2"></a><h4><a name="anchor11">3.2</a> Examples</h4> - -<p> -An example of a node 192.0.2.38 that will accept IPsec tunnels on its -own behalf. -</p> -</font><pre> -38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 - 192.0.2.38 - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) -</pre><font face="verdana, helvetica, arial, sans-serif" size="2"> -<p> - -</p> -<p> -An example of a node, 192.0.2.38 that has published its key only. -</p> -</font><pre> -38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 0 2 - . - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) -</pre><font face="verdana, helvetica, arial, sans-serif" size="2"> -<p> - -</p> -<p> -An example of a node, 192.0.2.38 that has delegated authority to the node -192.0.2.3. -</p> -</font><pre> -38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 - 192.0.2.3 - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) -</pre><font face="verdana, helvetica, arial, sans-serif" size="2"> -<p> - -</p> -<p> -An example of a node, 192.0.1.38 that has delegated authority to the node -with the identity "mygateway.example.com". -</p> -</font><pre> -38.1.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 3 2 - mygateway.example.com. - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) -</pre><font face="verdana, helvetica, arial, sans-serif" size="2"> -<p> - -</p> -<p> -An example of a node, 2001:0DB8:0200:1:210:f3ff:fe03:4d0 that has -delegated authority to the node 2001:0DB8:c000:0200:2::1 -</p> -</font><pre> -$ORIGIN 1.0.0.0.0.0.2.8.B.D.0.1.0.0.2.ip6.int. -0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0 7200 IN IPSECKEY ( 10 2 2 - 2001:0DB8:0:8002::2000:1 - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) -</pre><font face="verdana, helvetica, arial, sans-serif" size="2"> -<p> - -</p> -<a name="anchor12"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.4"></a><h3>4. Security Considerations</h3> - -<p> - This entire memo pertains to the provision of public keying material - for use by key management protocols such as ISAKMP/IKE (RFC2407) - <a href="#RFC2407">[9]</a>. - -</p> -<p> -The IPSECKEY resource record contains information that SHOULD be -communicated to the end client in an integral fashion - i.e. free from -modification. The form of this channel is up to the consumer of the -data - there must be a trust relationship between the end consumer of this -resource record and the server. This relationship may be end-to-end -DNSSEC validation, a TSIG or SIG(0) channel to another secure source, -a secure local channel on the host, or some combination of the above. - -</p> -<p> -The keying material provided by the IPSECKEY resource record is not -sensitive to passive attacks. The keying material may be freely -disclosed to any party without any impact on the security properties -of the resulting IPsec session: IPsec and IKE provide for defense -against both active and passive attacks. - -</p> -<p> - Any user of this resource record MUST carefully document their trust - model, and why the trust model of DNSSEC is appropriate, if that is - the secure channel used. - -</p> -<a name="rfc.section.4.1"></a><h4><a name="anchor13">4.1</a> Active attacks against unsecured IPSECKEY resource records</h4> - -<p> -This section deals with active attacks against the DNS. These attacks -require that DNS requests and responses be intercepted and changed. -DNSSEC is designed to defend against attacks of this kind. - -</p> -<p> -The first kind of active attack is when the attacker replaces the -keying material with either a key under its control or with garbage. - -</p> -<p> -If the attacker is not able to mount a subsequent -man-in-the-middle attack on the IKE negotiation after replacing the -public key, then this will result in a denial of service, as the -authenticator used by IKE would fail. - -</p> -<p> -If the attacker is able to both to mount active attacks against DNS -and is also in a position to perform a man-in-the-middle attack on IKE and -IPsec negotiations, then the attacker will be in a position to compromise -the resulting IPsec channel. Note that an attacker must be able to -perform active DNS attacks on both sides of the IKE negotiation in -order for this to succeed. - -</p> -<p> -The second kind of active attack is one in which the attacker replaces -the the gateway address to point to a node under the attacker's -control. The attacker can then either replace the public key or remove -it, thus providing an IPSECKEY record of its own to match the -gateway address. - -</p> -<p> -This later form creates a simple man-in-the-middle since the attacker -can then create a second tunnel to the real destination. Note that, as before, -this requires that the attacker also mount an active attack against -the responder. - -</p> -<p> -Note that the man-in-the-middle can not just forward cleartext -packets to the original destination. While the destination may be -willing to speak in the clear, replying to the original sender, -the sender will have already created a policy expecting ciphertext. -Thus, the attacker will need to intercept traffic from both sides. In some -cases, the attacker may be able to accomplish the full intercept by use -of Network Addresss/Port Translation (NAT/NAPT) technology. - -</p> -<p> -Note that the danger here only applies to cases where the gateway -field of the IPSECKEY RR indicates a different entity than the owner -name of the IPSECKEY RR. In cases where the end-to-end integrity of -the IPSECKEY RR is suspect, the end client MUST restrict its use -of the IPSECKEY RR to cases where the RR owner name matches the -content of the gateway field. - -</p> -<a name="anchor14"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.5"></a><h3>5. IANA Considerations</h3> - -<p> -This document updates the IANA Registry for DNS Resource Record Types -by assigning type X to the IPSECKEY record. - -</p> -<p> -This document creates an IANA registry for the algorithm type field. - -</p> -<p> -Values 0, 1 and 2 are defined in <a href="#algotype">RDATA format - algorithm type</a>. Algorithm numbers -3 through 255 can be assigned by IETF Consensus (<a href="#RFC2434">see RFC2434</a>[6]). - -</p> -<p> -This document creates an IANA registry for the gateway type field. - -</p> -<p> -Values 0, 1, 2 and 3 are defined in <a href="#gatewaytype">RDATA format - gateway type</a>. -Algorithm numbers 4 through 255 can be assigned by -Standards Action (<a href="#RFC2434">see RFC2434</a>[6]). - -</p> -<a name="anchor15"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<a name="rfc.section.6"></a><h3>6. Acknowledgments</h3> - -<p> -My thanks to Paul Hoffman, Sam Weiler, Jean-Jacques Puig, Rob Austein, -and Olafur Gurmundsson who reviewed this document carefully. -Additional thanks to Olafur Gurmundsson for a reference implementation. - -</p> -<a name="rfc.references1"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<h3>Normative references</h3> -<table width="99%" border="0"> -<tr><td class="author-text" valign="top"><b><a name="RFC1034">[1]</a></b></td> -<td class="author-text">Mockapetris, P., "<a href="ftp://ftp.isi.edu/in-notes/rfc1034.txt">Domain names - concepts and facilities</a>", STD 13, RFC 1034, November 1987.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC1035">[2]</a></b></td> -<td class="author-text"><a href="mailto:">Mockapetris, P.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1035.txt">Domain names - implementation and specification</a>", STD 13, RFC 1035, November 1987.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC1521">[3]</a></b></td> -<td class="author-text"><a href="mailto:nsb@bellcore.com">Borenstein, N.</a> and <a href="mailto:">N. Freed</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1521.txt">MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Specifying and Describing the Format of Internet Message Bodies</a>", RFC 1521, September 1993.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2026">[4]</a></b></td> -<td class="author-text"><a href="mailto:sob@harvard.edu">Bradner, S.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2026.txt">The Internet Standards Process -- Revision 3</a>", BCP 9, RFC 2026, October 1996.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2065">[5]</a></b></td> -<td class="author-text"><a href="mailto:dee@cybercash.com">Eastlake, D.</a> and <a href="mailto:charlie_kaufman@iris.com">C. Kaufman</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2065.txt">Domain Name System Security Extensions</a>", RFC 2065, January 1997.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2434">[6]</a></b></td> -<td class="author-text"><a href="mailto:narten@raleigh.ibm.com">Narten, T.</a> and <a href="mailto:Harald@Alvestrand.no">H. Alvestrand</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2434.txt">Guidelines for Writing an IANA Considerations Section in RFCs</a>", BCP 26, RFC 2434, October 1998.</td></tr> -</table> - -<a name="rfc.references2"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<h3>Non-normative references</h3> -<table width="99%" border="0"> -<tr><td class="author-text" valign="top"><b><a name="RFC1886">[7]</a></b></td> -<td class="author-text"><a href="mailto:set@thumper.bellcore.com">Thomson, S.</a> and <a href="mailto:Christian.Huitema@MIRSA.INRIA.FR">C. Huitema</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1886.txt">DNS Extensions to support IP version 6</a>", RFC 1886, December 1995.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2119">[8]</a></b></td> -<td class="author-text"><a href="mailto:-">Bradner, S.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2119.txt">Key words for use in RFCs to Indicate Requirement Levels</a>", BCP 14, RFC 2119, March 1997.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2407">[9]</a></b></td> -<td class="author-text"><a href="mailto:ddp@network-alchemy.com">Piper, D.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2407.txt">The Internet IP Security Domain of Interpretation for ISAKMP</a>", RFC 2407, November 1998.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2535">[10]</a></b></td> -<td class="author-text"><a href="mailto:dee3@us.ibm.com">Eastlake, D.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2535.txt">Domain Name System Security Extensions</a>", RFC 2535, March 1999.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC2536">[11]</a></b></td> -<td class="author-text"><a href="mailto:dee3@us.ibm.com">Eastlake, D.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2536.txt">DSA KEYs and SIGs in the Domain Name System (DNS)</a>", RFC 2536, March 1999.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC3110">[12]</a></b></td> -<td class="author-text">Eastlake, D., "<a href="ftp://ftp.isi.edu/in-notes/rfc3110.txt">RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)</a>", RFC 3110, May 2001.</td></tr> -<tr><td class="author-text" valign="top"><b><a name="RFC3445">[13]</a></b></td> -<td class="author-text">Massey, D. and S. Rose, "<a href="ftp://ftp.isi.edu/in-notes/rfc3445.txt">Limiting the Scope of the KEY Resource Record (RR)</a>", RFC 3445, December 2002.</td></tr> -</table> - -<a name="rfc.authors"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<h3>Author's Address</h3> -<table width="99%" border="0" cellpadding="0" cellspacing="0"> -<tr><td class="author-text"> </td> -<td class="author-text">Michael C. Richardson</td></tr> -<tr><td class="author-text"> </td> -<td class="author-text">Sandelman Software Works</td></tr> -<tr><td class="author-text"> </td> -<td class="author-text">470 Dawson Avenue</td></tr> -<tr><td class="author-text"> </td> -<td class="author-text">Ottawa, ON K1Z 5V7</td></tr> -<tr><td class="author-text"> </td> -<td class="author-text">CA</td></tr> -<tr><td class="author" align="right">EMail: </td> -<td class="author-text"><a href="mailto:mcr@sandelman.ottawa.on.ca">mcr@sandelman.ottawa.on.ca</a></td></tr> -<tr><td class="author" align="right">URI: </td> -<td class="author-text"><a href="http://www.sandelman.ottawa.on.ca/">http://www.sandelman.ottawa.on.ca/</a></td></tr> -</table> -<a name="rfc.copyright"><br><hr size="1" shade="0"></a> -<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b> TOC </b></font></a><br></td></tr></table> -<h3>Full Copyright Statement</h3> -<p class='copyright'> -Copyright (C) The Internet Society (2003). All Rights Reserved.</p> -<p class='copyright'> -This document and translations of it may be copied and furnished to -others, and derivative works that comment on or otherwise explain it -or assist in its implementation may be prepared, copied, published and -distributed, in whole or in part, without restriction of any kind, -provided that the above copyright notice and this paragraph are -included on all such copies and derivative works. However, this -document itself may not be modified in any way, such as by removing -the copyright notice or references to the Internet Society or other -Internet organizations, except as needed for the purpose of -developing Internet standards in which case the procedures for -copyrights defined in the Internet Standards process must be -followed, or as required to translate it into languages other than -English.</p> -<p class='copyright'> -The limited permissions granted above are perpetual and will not be -revoked by the Internet Society or its successors or assigns.</p> -<p class='copyright'> -This document and the information contained herein is provided on an -"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING -TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING -BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION -HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF -MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p> -<h3>Acknowledgement</h3> -<p class='copyright'> -Funding for the RFC Editor function is currently provided by the -Internet Society.</p> -</font></body></html> diff --git a/doc/src/draft-richardson-ipsec-rr.xml b/doc/src/draft-richardson-ipsec-rr.xml deleted file mode 100644 index e51b32615..000000000 --- a/doc/src/draft-richardson-ipsec-rr.xml +++ /dev/null @@ -1,560 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE rfc SYSTEM "rfc2629.dtd"> -<?rfc toc="yes"?> - -<rfc ipr="full2026" docName="draft-ietf-ipseckey-rr-07.txt"> - -<front> - <area>Security</area> - <workgroup>IPSECKEY WG</workgroup> - <title abbrev="ipsecrr"> - A method for storing IPsec keying material in DNS. - </title> - - <author initials="M." surname="Richardson" fullname="Michael C. Richardson"> - <organization abbrev="SSW">Sandelman Software Works</organization> - <address> - <postal> - <street>470 Dawson Avenue</street> - <city>Ottawa</city> - <region>ON</region> - <code>K1Z 5V7</code> - <country>CA</country> - </postal> - <email>mcr@sandelman.ottawa.on.ca</email> - <uri>http://www.sandelman.ottawa.on.ca/</uri> - </address> - </author> - - <date month="September" year="2003" /> - -<abstract> - <t> -This document describes a new resource record for DNS. This record may be -used to store public keys for use in IPsec systems. -</t> - -<t> -This record replaces the functionality of the sub-type #1 of the KEY Resource -Record, which has been obsoleted by RFC3445. -</t> -</abstract> - -</front> - -<middle> - -<section title="Introduction"> -<t> - The type number for the IPSECKEY RR is TBD. -</t> - -<section title="Overview"> -<t> - The IPSECKEY resource record (RR) is used to publish a public key that is - to be associated with a Domain Name System (DNS) name for use with the - IPsec protocol suite. This can be the public key of a host, - network, or application (in the case of per-port keying). -</t> - -<t> - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL - NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and - "OPTIONAL" in this document are to be interpreted as described in - RFC2119 <xref target="RFC2119" />. -</t> -</section> - -<section title="Usage Criteria"> -<t> - An IPSECKEY resource record SHOULD be used in combination with DNSSEC -unless some other means of authenticating the IPSECKEY resource record -is available. -</t> - -<t> - It is expected that there will often be multiple IPSECKEY resource - records at the same name. This will be due to the presence - of multiple gateways and the need to rollover keys. - -</t> - -<t> - This resource record is class independent. -</t> -</section> -</section> - -<section title="Storage formats"> - -<section title="IPSECKEY RDATA format"> - -<t> - The RDATA for an IPSECKEY RR consists of a precedence value, a public key, - algorithm type, and an optional gateway address. -</t> - -<artwork><![CDATA[ - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | precedence | gateway type | algorithm | gateway | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------+ + - ~ gateway ~ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | / - / public key / - / / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| -]]></artwork> -</section> - -<section title="RDATA format - precedence"> -<t> -This is an 8-bit precedence for this record. This is interpreted in -the same way as the PREFERENCE field described in section -3.3.9 of RFC1035 <xref target="RFC1035" />. -</t> -<t> -Gateways listed in IPSECKEY records with lower precedence are -to be attempted first. Where there is a tie in precedence, the order -should be non-deterministic. -</t> -</section> - -<section anchor="algotype" title="RDATA format - algorithm type"> -<t> -The algorithm type field identifies the public key's cryptographic -algorithm and determines the format of the public key field. -</t> - -<t> -A value of 0 indicates that no key is present. -</t> - -<t> -The following values are defined: - <list style="hanging"> - <t hangText="1">A DSA key is present, in the format defined in RFC2536 <xref target="RFC2536" /></t> - <t hangText="2">A RSA key is present, in the format defined in RFC3110 <xref target="RFC3110" /></t> - </list> -</t> - -</section> - -<section anchor="gatewaytype" title="RDATA format - gateway type"> -<t> -The gateway type field indicates the format of the information that -is stored in the gateway field. -</t> - -<t> -The following values are defined: - <list style="hanging"> - <t hangText="0">No gateway is present</t> - <t hangText="1">A 4-byte IPv4 address is present</t> - <t hangText="2">A 16-byte IPv6 address is present</t> - <t hangText="3">A wire-encoded domain name is present. The wire-encoded -format is self-describing, so the length is implicit. The domain name -MUST NOT be compressed.</t> - </list> -</t> - -</section> - -<section title="RDATA format - gateway"> -<t> -The gateway field indicates a gateway to which an IPsec tunnel may be -created in order to reach the entity named by this resource record. -</t> -<t> -There are three formats: -</t> - -<t> -A 32-bit IPv4 address is present in the gateway field. The data -portion is an IPv4 address as described in section 3.4.1 of -<xref target="RFC1035">RFC1035</xref>. This is a 32-bit number in network byte order. -</t> - -<t>A 128-bit IPv6 address is present in the gateway field. -The data portion is an IPv6 address as described in section 2.2 of -<xref target="RFC1886">RFC1886</xref>. This is a 128-bit number in network byte order. -</t> - -<t> -The gateway field is a normal wire-encoded domain name, as described -in section 3.3 of RFC1035 <xref target="RFC1035" />. Compression MUST NOT be used. -</t> - -</section> - -<section title="RDATA format - public keys"> -<t> -Both of the public key types defined in this document (RSA and DSA) -inherit their public key formats from the corresponding KEY RR formats. -Specifically, the public key field contains the algorithm-specific -portion of the KEY RR RDATA, which is all of the KEY RR DATA after the -first four octets. This is the same portion of the KEY RR that must be -specified by documents that define a DNSSEC algorithm. -Those documents also specify a message digest to be used for generation -of SIG RRs; that specification is not relevant for IPSECKEY RR. -</t> - -<t> -Future algorithms, if they are to be used by both DNSSEC (in the KEY -RR) and IPSECKEY, are likely to use the same public key encodings in -both records. Unless otherwise specified, the IPSECKEY public key -field will contain the algorithm-specific portion of the KEY RR RDATA -for the corresponding algorithm. The algorithm must still be -designated for use by IPSECKEY, and an IPSECKEY algorithm type number -(which might be different than the DNSSEC algorithm number) must be -assigned to it. -</t> - -<t>The DSA key format is defined in RFC2536 <xref target="RFC2536" /></t>. - -<t>The RSA key format is defined in RFC3110 <xref target="RFC3110" />, -with the following changes:</t> - -<t> -The earlier definition of RSA/MD5 in RFC2065 limited the exponent and -modulus to 2552 bits in length. RFC3110 extended that limit to 4096 -bits for RSA/SHA1 keys. The IPSECKEY RR imposes no length limit on -RSA public keys, other than the 65535 octet limit imposed by the -two-octet length encoding. This length extension is applicable only -to IPSECKEY and not to KEY RRs. -</t> - -</section> - -</section> - - - -<section title="Presentation formats"> - -<section title="Representation of IPSECKEY RRs"> -<t> - IPSECKEY RRs may appear in a zone data master file. - The precedence, gateway type and algorithm and gateway fields are REQUIRED. - The base64 encoded public key block is OPTIONAL; if not present, - then the public key field of the resource record MUST be construed - as being zero octets in length. -</t> -<t> - The algorithm field is an unsigned integer. No mnemonics are defined. -</t> -<t> - If no gateway is to be indicated, then the gateway type field MUST - be zero, and the gateway field MUST be "." -</t> - -<t> - The Public Key field is represented as a Base64 encoding of the - Public Key. Whitespace is allowed within the Base64 text. For a - definition of Base64 encoding, see -<xref target="RFC1521">RFC1521</xref> Section 5.2. -</t> - - -<t> - The general presentation for the record as as follows: -<artwork><![CDATA[ -IN IPSECKEY ( precedence gateway-type algorithm - gateway base64-encoded-public-key ) -]]></artwork> -</t> -</section> - - -<section title="Examples"> -<t> -An example of a node 192.0.2.38 that will accept IPsec tunnels on its -own behalf. -<artwork><![CDATA[ -38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 - 192.0.2.38 - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) -]]></artwork> -</t> - -<t> -An example of a node, 192.0.2.38 that has published its key only. -<artwork><![CDATA[ -38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 0 2 - . - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) -]]></artwork> -</t> - -<t> -An example of a node, 192.0.2.38 that has delegated authority to the node -192.0.2.3. -<artwork><![CDATA[ -38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 - 192.0.2.3 - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) -]]></artwork> -</t> - -<t> -An example of a node, 192.0.1.38 that has delegated authority to the node -with the identity "mygateway.example.com". -<artwork><![CDATA[ -38.1.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 3 2 - mygateway.example.com. - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) -]]></artwork> -</t> - -<t> -An example of a node, 2001:0DB8:0200:1:210:f3ff:fe03:4d0 that has -delegated authority to the node 2001:0DB8:c000:0200:2::1 -<artwork><![CDATA[ -$ORIGIN 1.0.0.0.0.0.2.8.B.D.0.1.0.0.2.ip6.int. -0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0 7200 IN IPSECKEY ( 10 2 2 - 2001:0DB8:0:8002::2000:1 - AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ) -]]></artwork> -</t> - -</section> -</section> - -<section title="Security Considerations"> -<t> - This entire memo pertains to the provision of public keying material - for use by key management protocols such as ISAKMP/IKE (RFC2407) - <xref target="RFC2407" />. -</t> - -<t> -The IPSECKEY resource record contains information that SHOULD be -communicated to the end client in an integral fashion - i.e. free from -modification. The form of this channel is up to the consumer of the -data - there must be a trust relationship between the end consumer of this -resource record and the server. This relationship may be end-to-end -DNSSEC validation, a TSIG or SIG(0) channel to another secure source, -a secure local channel on the host, or some combination of the above. -</t> - -<t> -The keying material provided by the IPSECKEY resource record is not -sensitive to passive attacks. The keying material may be freely -disclosed to any party without any impact on the security properties -of the resulting IPsec session: IPsec and IKE provide for defense -against both active and passive attacks. -</t> - -<t> - Any user of this resource record MUST carefully document their trust - model, and why the trust model of DNSSEC is appropriate, if that is - the secure channel used. -</t> - -<section title="Active attacks against unsecured IPSECKEY resource records"> -<t> -This section deals with active attacks against the DNS. These attacks -require that DNS requests and responses be intercepted and changed. -DNSSEC is designed to defend against attacks of this kind. -</t> - -<t> -The first kind of active attack is when the attacker replaces the -keying material with either a key under its control or with garbage. -</t> - -<t> -If the attacker is not able to mount a subsequent -man-in-the-middle attack on the IKE negotiation after replacing the -public key, then this will result in a denial of service, as the -authenticator used by IKE would fail. -</t> - -<t> -If the attacker is able to both to mount active attacks against DNS -and is also in a position to perform a man-in-the-middle attack on IKE and -IPsec negotiations, then the attacker will be in a position to compromise -the resulting IPsec channel. Note that an attacker must be able to -perform active DNS attacks on both sides of the IKE negotiation in -order for this to succeed. -</t> - -<t> -The second kind of active attack is one in which the attacker replaces -the the gateway address to point to a node under the attacker's -control. The attacker can then either replace the public key or remove -it, thus providing an IPSECKEY record of its own to match the -gateway address. -</t> - -<t> -This later form creates a simple man-in-the-middle since the attacker -can then create a second tunnel to the real destination. Note that, as before, -this requires that the attacker also mount an active attack against -the responder. -</t> - -<t> -Note that the man-in-the-middle can not just forward cleartext -packets to the original destination. While the destination may be -willing to speak in the clear, replying to the original sender, -the sender will have already created a policy expecting ciphertext. -Thus, the attacker will need to intercept traffic from both sides. In some -cases, the attacker may be able to accomplish the full intercept by use -of Network Addresss/Port Translation (NAT/NAPT) technology. -</t> - -<t> -Note that the danger here only applies to cases where the gateway -field of the IPSECKEY RR indicates a different entity than the owner -name of the IPSECKEY RR. In cases where the end-to-end integrity of -the IPSECKEY RR is suspect, the end client MUST restrict its use -of the IPSECKEY RR to cases where the RR owner name matches the -content of the gateway field. -</t> -</section> - -</section> - -<section title="IANA Considerations"> -<t> -This document updates the IANA Registry for DNS Resource Record Types -by assigning type X to the IPSECKEY record. -</t> - -<t> -This document creates an IANA registry for the algorithm type field. -</t> -<t> -Values 0, 1 and 2 are defined in <xref target="algotype" />. Algorithm numbers -3 through 255 can be assigned by IETF Consensus (<xref target="RFC2434">see RFC2434</xref>). -</t> - -<t> -This document creates an IANA registry for the gateway type field. -</t> -<t> -Values 0, 1, 2 and 3 are defined in <xref target="gatewaytype" />. -Algorithm numbers 4 through 255 can be assigned by -Standards Action (<xref target="RFC2434">see RFC2434</xref>). -</t> - - - -</section> - -<section title="Acknowledgments"> -<t> -My thanks to Paul Hoffman, Sam Weiler, Jean-Jacques Puig, Rob Austein, -and Olafur Gurmundsson who reviewed this document carefully. -Additional thanks to Olafur Gurmundsson for a reference implementation. -</t> -</section> - -</middle> - -<back> -<references title="Normative references"> -<!-- DNSSEC --> -<?rfc include="reference.RFC.1034" ?> -<?rfc include="reference.RFC.1035" ?> -<?rfc include="reference.RFC.1521" ?> -<?rfc include="reference.RFC.2026" ?> -<?rfc include="reference.RFC.2065" ?> -<?rfc include="reference.RFC.2434" ?> -</references> - -<references title="Non-normative references"> -<?rfc include="reference.RFC.1886" ?> -<?rfc include="reference.RFC.2119" ?> -<?rfc include="reference.RFC.2407" ?> -<?rfc include="reference.RFC.2535" ?> -<?rfc include="reference.RFC.2536" ?> -<?rfc include="reference.RFC.3110" ?> -<?rfc include="reference.RFC.3445" ?> -</references> -</back> -</rfc> -<!-- - $Id: draft-richardson-ipsec-rr.xml,v 1.1 2004/03/15 20:35:24 as Exp $ - - $Log: draft-richardson-ipsec-rr.xml,v $ - Revision 1.1 2004/03/15 20:35:24 as - added files from freeswan-2.04-x509-1.5.3 - - Revision 1.23 2003/09/04 23:26:09 mcr - more nits. - - Revision 1.22 2003/08/16 15:55:35 mcr - fixed version to -06. - - Revision 1.21 2003/08/16 15:52:32 mcr - Sam's comments on IANA considerations. - - Revision 1.20 2003/07/27 22:57:54 mcr - updated document with new text about a seperate registry - for the algorithm type. - - Revision 1.19 2003/06/30 01:51:50 mcr - minor typo fixes. - - Revision 1.18 2003/06/16 17:45:00 mcr - adjusted date on rev-04. - - Revision 1.17 2003/06/16 17:41:30 mcr - revision -04 - - Revision 1.16 2003/06/16 17:39:20 mcr - adjusted typos, and adjusted IANA considerations. - - Revision 1.15 2003/05/26 19:31:23 mcr - updates to drafts - IPSEC RR - SC versions, and RFC3526 - reference in OE draft. - - Revision 1.14 2003/05/23 13:57:40 mcr - updated draft ##. - - Revision 1.13 2003/05/23 13:54:45 mcr - updated month on draft. - - Revision 1.12 2003/05/21 15:42:49 mcr - new SC section with comments from Rob Austein. - - Revision 1.11 2003/05/20 20:52:22 mcr - new security considerations section. - - Revision 1.10 2003/05/20 19:07:47 mcr - rewrote Security Considerations. - - Revision 1.9 2003/05/20 18:17:09 mcr - nits from Rob Austein. - - Revision 1.8 2003/04/29 00:44:59 mcr - updates according to WG consensus: restored three-way - gateway field type. - - Revision 1.7 2003/03/30 17:00:29 mcr - updates according to community feedback. - - Revision 1.6 2003/03/19 02:20:24 mcr - updated draft based upon comments from working group - - Revision 1.5 2003/02/23 22:39:22 mcr - updates to IPSECKEY draft. - - Revision 1.4 2003/02/21 04:39:04 mcr - updated drafts, and added crosscompile.html - - Revision 1.3 2003/01/17 16:26:34 mcr - updated IPSEC KEY draft with restrictions. - - Revision 1.2 2002/08/26 18:20:54 mcr - updated documents - - Revision 1.1 2002/08/10 20:05:33 mcr - document proposing IPSECKEY Resource Record - - -!> diff --git a/doc/utils/rfc_pg.c b/doc/utils/rfc_pg.c index 448cc1a36..e2484959e 100644 --- a/doc/utils/rfc_pg.c +++ b/doc/utils/rfc_pg.c @@ -1,5 +1,5 @@ /* - * $Header: /var/cvsroot/strongswan/doc/utils/rfc_pg.c,v 1.1 2004/03/15 20:35:24 as Exp $ + * $Header: /root/strongswan/doc/utils/rfc_pg.c,v 1.1 2004/03/15 20:35:24 as Exp $ * * from 2-nroff.template file. * diff --git a/lib/Makefile b/lib/Makefile index fa2b27bef..8f0b6ec24 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -12,7 +12,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:24 as Exp $ +# RCSID $Id: Makefile,v 1.2 2006/10/19 18:12:45 as Exp $ FREESWANSRCDIR=.. include ${FREESWANSRCDIR}/Makefile.inc @@ -37,5 +37,4 @@ cleanall distclean mostlyclean realclean install programs checkprograms check cl @for d in $(SUBDIRS) ; \ do \ (cd $$d && $(MAKE) FREESWANSRCDIR=$(FREESWANSRCDIR)/.. $@ ) || exit 1; \ - done; \ - + done; diff --git a/programs/Makefile b/programs/Makefile index 03c9d582a..dbc03f416 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -12,7 +12,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: Makefile,v 1.8 2006/04/17 11:04:45 as Exp $ +# RCSID $Id: Makefile,v 1.9 2006/08/28 11:12:36 as Exp $ FREESWANSRCDIR=.. include ${FREESWANSRCDIR}/Makefile.inc @@ -42,5 +42,5 @@ cleanall distclean mostlyclean realclean install programs checkprograms check cl @for d in $(SUBDIRS) ; \ do \ (cd $$d && $(MAKE) FREESWANSRCDIR=$(FREESWANSRCDIR)/.. $@ ) || exit 1;\ - done; \ + done; diff --git a/programs/pluto/connections.c b/programs/pluto/connections.c index 8bd3ed49b..1ea6ac5fa 100644 --- a/programs/pluto/connections.c +++ b/programs/pluto/connections.c @@ -11,7 +11,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: connections.c,v 1.44 2006/07/06 19:20:09 as Exp $ + * RCSID $Id: connections.c,v 1.46 2006/10/19 15:40:52 as Exp $ */ #include <string.h> @@ -862,6 +862,7 @@ extract_end(struct end *dst, const whack_end_t *src, const char *which) dst->host_addr = src->host_addr; dst->host_nexthop = src->host_nexthop; dst->host_srcip = src->host_srcip; + dst->has_natip = src->has_natip; dst->client = src->client; dst->protocol = src->protocol; dst->port = src->port; @@ -880,6 +881,7 @@ extract_end(struct end *dst, const whack_end_t *src, const char *which) */ if (addrbytesptr(&dst->host_srcip, NULL) && !isanyaddr(&dst->host_srcip) + && !dst->has_natip && !dst->has_client) { err_t ugh = addrtosubnet(&dst->host_srcip, &dst->client); @@ -2024,7 +2026,8 @@ cannot_oppo(struct connection *c char state_buf2[LOG_WIDTH]; time_t n = now(); - fmt_state(st, n, state_buf, sizeof(state_buf) + fmt_state(FALSE, st, n + , state_buf, sizeof(state_buf) , state_buf2, sizeof(state_buf2)); DBG_log("cannot_oppo, failure SA1: %s", state_buf); DBG_log("cannot_oppo, failure SA2: %s", state_buf2); @@ -3065,7 +3068,7 @@ ISAKMP_SA_established(struct connection *c, so_serial_t serial) /* the connection is now oriented so that we are able to determine * whether we are a mode config server with a virtual IP to send. */ - if (!isanyaddr(&c->spd.that.host_srcip)) + if (!isanyaddr(&c->spd.that.host_srcip) && !c->spd.that.has_natip) c->spd.that.modecfg = TRUE; if (uniqueIDs) diff --git a/programs/pluto/connections.h b/programs/pluto/connections.h index 6dfddbe22..33fbc3fea 100644 --- a/programs/pluto/connections.h +++ b/programs/pluto/connections.h @@ -11,7 +11,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: connections.h,v 1.18 2006/04/22 21:59:20 as Exp $ + * RCSID $Id: connections.h,v 1.19 2006/10/19 15:38:27 as Exp $ */ #ifndef _CONNECTIONS_H @@ -143,6 +143,7 @@ struct end { bool has_client_wildcard; bool has_port_wildcard; bool has_id_wildcards; + bool has_natip; char *updown; u_int16_t host_port; /* host order */ u_int16_t port; /* host order */ diff --git a/programs/pluto/constants.c b/programs/pluto/constants.c index 27e4db1e0..5ca7b65ce 100644 --- a/programs/pluto/constants.c +++ b/programs/pluto/constants.c @@ -11,7 +11,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: constants.c,v 1.21 2006/03/27 07:38:59 as Exp $ + * RCSID $Id: constants.c,v 1.22 2006/10/19 21:07:40 as Exp $ */ /* @@ -188,6 +188,7 @@ static const char *const state_name[] = { "STATE_MODE_CFG_R2", "STATE_MODE_CFG_I1", "STATE_MODE_CFG_I2", + "STATE_MODE_CFG_I3", "STATE_IKE_ROOF" }; @@ -218,9 +219,10 @@ const char *const state_story[] = { "sent ModeCfg reply", /* STATE_MODE_CFG_R0 */ "sent ModeCfg reply", /* STATE_MODE_CFG_R1 */ - "ModeCfg R2", /* STATE_MODE_CFG_R2 */ + "received ModeCfg ack", /* STATE_MODE_CFG_R2 */ "sent ModeCfg request, expecting reply", /* STATE_MODE_CFG_I1 */ "received ModeCfg reply", /* STATE_MODE_CFG_I2 */ + "received ModeCfg set, sent ack", /* STATE_MODE_CFG_I3 */ }; /* kind of struct connection */ @@ -484,6 +486,7 @@ const char *const sa_policy_bit_names[] = { "GROUP", "GROUTED", "UP", + "MODECFGPUSH", NULL }; diff --git a/programs/pluto/constants.h b/programs/pluto/constants.h index b66d002ee..bad162898 100644 --- a/programs/pluto/constants.h +++ b/programs/pluto/constants.h @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: constants.h,v 1.20 2006/02/28 19:13:33 as Exp $ + * RCSID $Id: constants.h,v 1.22 2006/10/19 21:07:40 as Exp $ */ #ifndef _CONSTANTS_H @@ -510,6 +510,7 @@ enum state_kind { STATE_MODE_CFG_I1, /* this is used on the initiator */ STATE_MODE_CFG_I2, + STATE_MODE_CFG_I3, STATE_IKE_ROOF }; @@ -519,17 +520,21 @@ enum state_kind { #define PHASE1_INITIATOR_STATES (LELEM(STATE_MAIN_I1) | LELEM(STATE_MAIN_I2) \ | LELEM(STATE_MAIN_I3) | LELEM(STATE_MAIN_I4)) #define ISAKMP_SA_ESTABLISHED_STATES (LELEM(STATE_MAIN_R3) | LELEM(STATE_MAIN_I4) \ - | LELEM(STATE_MODE_CFG_R1) | LELEM(STATE_MODE_CFG_I2)) + | LELEM(STATE_MODE_CFG_R1) | LELEM(STATE_MODE_CFG_R2) \ + | LELEM(STATE_MODE_CFG_I2) | LELEM(STATE_MODE_CFG_I3)) #define IS_PHASE1(s) ((STATE_MAIN_R0 <= (s) && (s) <= STATE_MAIN_I4) \ - || (STATE_MODE_CFG_R0 <= (s) && (s) <= STATE_MODE_CFG_I2)) + || (STATE_MODE_CFG_R0 <= (s) && (s) <= STATE_MODE_CFG_I3)) #define IS_QUICK(s) (STATE_QUICK_R0 <= (s) && (s) <= STATE_QUICK_R2) #define IS_ISAKMP_ENCRYPTED(s) (STATE_MAIN_I2 <= (s)) -#define IS_ISAKMP_SA_ESTABLISHED(s) ((s) == STATE_MAIN_R3 \ - || (s) == STATE_MAIN_I4 \ +#define IS_ISAKMP_SA_ESTABLISHED(s) ( \ + (s) == STATE_MAIN_R3 \ + || (s) == STATE_MAIN_I4 \ || (s) == STATE_MODE_CFG_R0 \ || (s) == STATE_MODE_CFG_R1 \ - || (s) == STATE_MODE_CFG_I2) + || (s) == STATE_MODE_CFG_R2 \ + || (s) == STATE_MODE_CFG_I2 \ + || (s) == STATE_MODE_CFG_I3) #define IS_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_I2 || (s) == STATE_QUICK_R2) #define IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_R1) @@ -783,11 +788,12 @@ extern const char *prettypolicy(lset_t policy); /* connection policy * Other policies could vary per state object. These live in connection. */ -#define POLICY_DONT_REKEY LELEM(12) /* don't rekey state either Phase */ -#define POLICY_OPPO LELEM(13) /* is this opportunistic? */ -#define POLICY_GROUP LELEM(14) /* is this a group template? */ -#define POLICY_GROUTED LELEM(15) /* do we want this group routed? */ -#define POLICY_UP LELEM(16) /* do we want this up? */ +#define POLICY_DONT_REKEY LELEM(12) /* don't rekey state either Phase */ +#define POLICY_OPPO LELEM(13) /* is this opportunistic? */ +#define POLICY_GROUP LELEM(14) /* is this a group template? */ +#define POLICY_GROUTED LELEM(15) /* do we want this group routed? */ +#define POLICY_UP LELEM(16) /* do we want this up? */ +#define POLICY_MODECFG_PUSH LELEM(17) /* is modecfg pushed by server? */ /* Any IPsec policy? If not, a connection description diff --git a/programs/pluto/demux.c b/programs/pluto/demux.c index db7f1c4a6..3146b3d40 100644 --- a/programs/pluto/demux.c +++ b/programs/pluto/demux.c @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: demux.c,v 1.14 2006/06/22 11:58:25 as Exp $ + * RCSID $Id: demux.c,v 1.16 2006/10/19 21:07:40 as Exp $ */ /* Ordering Constraints on Payloads @@ -481,7 +481,17 @@ static const struct state_microcode state_microcode_table[] = { { STATE_MODE_CFG_I1, STATE_MODE_CFG_I2 , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2 , P(ATTR) | P(HASH), P(VID), PT(HASH) - , EVENT_SA_REPLACE, modecfg_inR1 }, + , EVENT_SA_REPLACE, modecfg_inI1 }, + + { STATE_MODE_CFG_I2, STATE_MODE_CFG_I3 + , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2 + , P(ATTR) | P(HASH), P(VID), PT(HASH) + , EVENT_SA_REPLACE, modecfg_inI2 }, + + { STATE_MODE_CFG_I3, STATE_UNDEFINED + , SMF_ALL_AUTH | SMF_ENCRYPTED + , LEMPTY, LEMPTY, PT(NONE) + , EVENT_NULL, unexpected }, #undef P #undef PT @@ -1441,7 +1451,7 @@ process_packet(struct msg_digest **mdp) { st->st_state = STATE_MAIN_R3; /* ISAKMP is up... */ } - + set_cur_state(st); if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state)) @@ -1471,7 +1481,7 @@ process_packet(struct msg_digest **mdp) } else { - set_cur_state(st); + set_cur_state(st); from_state = st->st_state; } @@ -1563,7 +1573,7 @@ process_packet(struct msg_digest **mdp) else if (st->st_connection->spd.this.modecfg && IS_PHASE1(st->st_state)) { - from_state = STATE_MODE_CFG_R1; + from_state = STATE_MODE_CFG_I2; } else { @@ -2323,38 +2333,39 @@ complete_state_transition(struct msg_digest **mdp, stf_status result) , story, sadetails); } - /* Should we start Mode Config as a client */ + /* Should we start ModeConfig as a client? */ if (st->st_connection->spd.this.modecfg && IS_ISAKMP_SA_ESTABLISHED(st->st_state) + && !(st->st_connection->policy & POLICY_MODECFG_PUSH) && !st->st_modecfg.started) { DBG(DBG_CONTROL, - DBG_log("modecfg client is starting") + DBG_log("starting ModeCfg client in pull mode") ) modecfg_send_request(st); break; } - /* Should we set the peer's IP address regardless? */ -/* if (st->st_connection->spd.that.modecfg + /* Should we start ModeConfig as a server? */ + if (st->st_connection->spd.that.modecfg && IS_ISAKMP_SA_ESTABLISHED(st->st_state) - && !st->st_modecfg.vars_set - && !(st->st_connection->policy & POLICY_MODECFG_PULL)) + && !st->st_modecfg.started + && (st->st_connection->policy & POLICY_MODECFG_PUSH)) { - st->st_state = STATE_MODE_CFG_R1; - set_cur_state(st); - plog("Sending MODE CONFIG set"); - modecfg_start_set(st); + DBG(DBG_CONTROL, + DBG_log("starting ModeCfg server in push mode") + ) + modecfg_send_set(st); break; } -*/ - /* wait for modecfg_set */ + + /* Wait for ModeConfig set from server */ if (st->st_connection->spd.this.modecfg && IS_ISAKMP_SA_ESTABLISHED(st->st_state) && !st->st_modecfg.vars_set) { DBG(DBG_CONTROL, - DBG_log("waiting for modecfg set from server") + DBG_log("waiting for ModeCfg set from server") ) break; } diff --git a/programs/pluto/log.c b/programs/pluto/log.c index 73ffceccd..aef93ff3c 100644 --- a/programs/pluto/log.c +++ b/programs/pluto/log.c @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: log.c,v 1.8 2006/04/29 18:16:02 as Exp $ + * RCSID $Id: log.c,v 1.9 2006/10/17 10:30:54 as Exp $ */ #include <stdio.h> @@ -773,7 +773,7 @@ show_status(bool all, const char *name) whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */ } show_connections_status(all, name); - show_states_status(name); + show_states_status(all, name); #ifdef KLIPS show_shunt_status(); #endif diff --git a/programs/pluto/modecfg.c b/programs/pluto/modecfg.c index 1c22845a5..ec334aaf5 100644 --- a/programs/pluto/modecfg.c +++ b/programs/pluto/modecfg.c @@ -2,6 +2,7 @@ * Copyright (C) 2001-2002 Colubris Networks * Copyright (C) 2003 Sean Mathews - Nu Tech Software Solutions, inc. * Copyright (C) 2003-2004 Xelerance Corporation + * Copyright (C) 2006 Andreas Steffen - Hochschule fuer Technik Rapperswil * * 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 @@ -13,7 +14,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: modecfg.c,v 1.6 2006/04/24 20:44:57 as Exp $ + * RCSID $Id: modecfg.c,v 1.9 2006/10/21 17:11:13 as Exp $ * * This code originally written by Colubris Networks, Inc. * Extraction of patch and porting to 1.99 codebases by Xelerance Corporation @@ -39,23 +40,46 @@ #include "modecfg.h" #include "whack.h" +#define SUPPORTED_ATTR_SET ( LELEM(INTERNAL_IP4_ADDRESS) \ + | LELEM(INTERNAL_IP4_NETMASK) \ + | LELEM(INTERNAL_IP4_DNS) \ + | LELEM(INTERNAL_IP4_NBNS) \ + ) + /* - * Addresses assigned (usually via MODE_CONFIG) to the Initiator + * Addresses assigned (usually via ModeCfg) to the Initiator */ +typedef struct internal_addr internal_addr_t; + struct internal_addr { + lset_t attr_set; ip_address ipaddr; ip_address dns[2]; - ip_address wins[2]; + ip_address wins[2]; }; /* - * Get inside IP address for a connection + * Initialize an internal_addr struct */ static void -get_internal_addresses(struct connection *c, struct internal_addr *ia) +init_internal_addr(internal_addr_t *ia) { - zero(ia); + ia->attr_set = LEMPTY; + anyaddr(AF_INET, &ia->ipaddr); + anyaddr(AF_INET, &ia->dns[0]); + anyaddr(AF_INET, &ia->dns[1]); + anyaddr(AF_INET, &ia->wins[0]); + anyaddr(AF_INET, &ia->wins[1]); +} + +/* + * get internal IP address for a connection + */ +static void +get_internal_addr(struct connection *c, internal_addr_t *ia) +{ + init_internal_addr(ia); if (isanyaddr(&c->spd.that.host_srcip)) { @@ -63,16 +87,78 @@ get_internal_addresses(struct connection *c, struct internal_addr *ia) } else { + char srcip[ADDRTOT_BUF]; + ia->ipaddr = c->spd.that.host_srcip; + + addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip)); + plog("assigning virtual IP source address %s", srcip); + } + + if (!isanyaddr(&ia->ipaddr)) /* We got an IP address, send it */ + { + c->spd.that.client.addr = ia->ipaddr; + c->spd.that.client.maskbits = 32; + c->spd.that.has_client = TRUE; + + ia->attr_set |= LELEM(INTERNAL_IP4_ADDRESS) | LELEM(INTERNAL_IP4_NETMASK); + } + + + if (!isanyaddr(&ia->dns[0])) /* We got DNS addresses, send them */ + ia->attr_set |= LELEM(INTERNAL_IP4_DNS); + + if (!isanyaddr(&ia->wins[0])) /* We got WINS addresses, send them */ + ia->attr_set |= LELEM(INTERNAL_IP4_NBNS); +} + +/* + * Set srcip and client subnet to internal IP address + */ +static bool +set_internal_addr(struct connection *c, internal_addr_t *ia) +{ + if (ia->attr_set & LELEM(INTERNAL_IP4_ADDRESS) + && !isanyaddr(&ia->ipaddr)) + { + if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0 + || isanyaddr(&c->spd.this.host_srcip) + || sameaddr(&c->spd.this.host_srcip, &ia->ipaddr)) + { + char srcip[ADDRTOT_BUF]; + + addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip)); + plog("setting virtual IP source address to %s", srcip); + } + else + { + char old_srcip[ADDRTOT_BUF]; + char new_srcip[ADDRTOT_BUF]; + + addrtot(&c->spd.this.host_srcip, 0, old_srcip, sizeof(old_srcip)); + addrtot(&ia->ipaddr, 0, new_srcip, sizeof(new_srcip)); + plog("replacing virtual IP source address %s by %s" + , old_srcip, new_srcip); + } + + /* setting srcip */ + c->spd.this.host_srcip = ia->ipaddr; + + /* setting client subnet to srcip/32 */ + addrtosubnet(&ia->ipaddr, &c->spd.this.client); + setportof(0, &c->spd.this.client.addr); + c->spd.this.has_client = TRUE; + return TRUE; } + return FALSE; } /* * Compute HASH of Mode Config. */ static size_t -mode_cfg_hash(u_char *dest, const u_char *start, const u_char *roof - , const struct state *st) +modecfg_hash(u_char *dest, const u_char *start, const u_char *roof + , const struct state *st) { struct hmac_ctx ctx; @@ -82,92 +168,51 @@ mode_cfg_hash(u_char *dest, const u_char *start, const u_char *roof hmac_final(dest, &ctx); DBG(DBG_CRYPT, - DBG_log("MODE CFG: HASH computed:"); + DBG_log("ModeCfg HASH computed:"); DBG_dump("", dest, ctx.hmac_digest_size) ) return ctx.hmac_digest_size; } -/* Mode Config Reply - * Generates a reply stream containing Mode Config information (eg: IP, DNS, WINS) +/* + * Generate an IKE message containing ModeCfg information (eg: IP, DNS, WINS) */ -stf_status modecfg_resp(struct state *st - , u_int resp - , pb_stream *rbody - , u_int16_t replytype - , bool hackthat - , u_int16_t ap_id) +static stf_status +modecfg_build_msg(struct state *st, pb_stream *rbody + , u_int16_t msg_type + , internal_addr_t *ia + , u_int16_t ap_id) { - u_char *r_hash_start,*r_hashval; - - /* START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_ATTR); */ + u_char *r_hash_start, *r_hashval; - { - pb_stream hash_pbs; - int np = ISAKMP_NEXT_ATTR; - - if (!out_generic(np, &isakmp_hash_desc, rbody, &hash_pbs)) - return STF_INTERNAL_ERROR; - r_hashval = hash_pbs.cur; /* remember where to plant value */ - if (!out_zero(st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH")) - return STF_INTERNAL_ERROR; - close_output_pbs(&hash_pbs); - r_hash_start = (rbody)->cur; /* hash from after HASH payload */ - } + START_HASH_PAYLOAD(*rbody, ISAKMP_NEXT_ATTR); /* ATTR out */ { - struct isakmp_mode_attr attrh; + struct isakmp_mode_attr attrh; struct isakmp_attribute attr; pb_stream strattr,attrval; int attr_type; - struct internal_addr ia; int dns_idx, wins_idx; bool dont_advance; + lset_t attr_set = ia->attr_set; - attrh.isama_np = ISAKMP_NEXT_NONE; - attrh.isama_type = replytype; - + attrh.isama_np = ISAKMP_NEXT_NONE; + attrh.isama_type = msg_type; attrh.isama_identifier = ap_id; + if (!out_struct(&attrh, &isakmp_attr_desc, rbody, &strattr)) return STF_INTERNAL_ERROR; - get_internal_addresses(st->st_connection, &ia); - - if (!isanyaddr(&ia.dns[0])) /* We got DNS addresses, answer with those */ - resp |= LELEM(INTERNAL_IP4_DNS); - else - resp &= ~LELEM(INTERNAL_IP4_DNS); - - if (!isanyaddr(&ia.wins[0])) /* We got WINS addresses, answer with those */ - resp |= LELEM(INTERNAL_IP4_NBNS); - else - resp &= ~LELEM(INTERNAL_IP4_NBNS); - - if (hackthat) - { - if (memcmp(&st->st_connection->spd.that.client.addr - ,&ia.ipaddr - ,sizeof(ia.ipaddr)) != 0) - { - /* Make the Internal IP address and Netmask - * as that client address - */ - st->st_connection->spd.that.client.addr = ia.ipaddr; - st->st_connection->spd.that.client.maskbits = 32; - st->st_connection->spd.that.has_client = TRUE; - } - } - attr_type = 0; dns_idx = 0; wins_idx = 0; - while (resp != 0) + while (attr_set != 0) { dont_advance = FALSE; - if (resp & 1) + if (attr_set & 1) { const u_char *byte_ptr; u_int len; @@ -179,14 +224,11 @@ stf_status modecfg_resp(struct state *st switch (attr_type) { case INTERNAL_IP4_ADDRESS: + if (!isanyaddr(&ia->ipaddr)) { - char srcip[ADDRTOT_BUF]; - - addrtot(&ia.ipaddr, 0, srcip, sizeof(srcip)); - plog("assigning virtual IP source address %s", srcip); - len = addrbytesptr(&ia.ipaddr, &byte_ptr); - out_raw(byte_ptr,len,&attrval,"IP4_addr"); - } + len = addrbytesptr(&ia->ipaddr, &byte_ptr); + out_raw(byte_ptr, len, &attrval, "IP4_addr"); + } break; case INTERNAL_IP4_NETMASK: { @@ -207,7 +249,7 @@ stf_status modecfg_resp(struct state *st mask = 0; else mask = 0xffffffff * 1; - out_raw(&mask,4,&attrval,"IP4_mask"); + out_raw(&mask, 4, &attrval, "IP4_mask"); } break; case INTERNAL_IP4_SUBNET: @@ -228,22 +270,28 @@ stf_status modecfg_resp(struct state *st m = 0; } len = addrbytesptr(&st->st_connection->spd.this.client.addr, &byte_ptr); - out_raw(byte_ptr,len,&attrval,"IP4_subnet"); - out_raw(mask,sizeof(mask),&attrval,"IP4_submsk"); + out_raw(byte_ptr, len, &attrval, "IP4_subnet"); + out_raw(mask, sizeof(mask), &attrval, "IP4_submsk"); } break; case INTERNAL_IP4_DNS: - len = addrbytesptr(&ia.dns[dns_idx++], &byte_ptr); - out_raw(byte_ptr,len,&attrval,"IP4_dns"); - if (dns_idx < 2 && !isanyaddr(&ia.dns[dns_idx])) + if (!isanyaddr(&ia->dns[dns_idx])) + { + len = addrbytesptr(&ia->dns[dns_idx++], &byte_ptr); + out_raw(byte_ptr, len, &attrval, "IP4_dns"); + } + if (dns_idx < 2 && !isanyaddr(&ia->dns[dns_idx])) { dont_advance = TRUE; } break; case INTERNAL_IP4_NBNS: - len = addrbytesptr(&ia.wins[wins_idx++], &byte_ptr); - out_raw(byte_ptr,len,&attrval,"IP4_wins"); - if (wins_idx < 2 && !isanyaddr(&ia.wins[wins_idx])) + if (!isanyaddr(&ia->wins[wins_idx])) + { + len = addrbytesptr(&ia->wins[wins_idx++], &byte_ptr); + out_raw(byte_ptr, len, &attrval, "IP4_wins"); + } + if (wins_idx < 2 && !isanyaddr(&ia->wins[wins_idx])) { dont_advance = TRUE; } @@ -254,35 +302,39 @@ stf_status modecfg_resp(struct state *st break; } close_output_pbs(&attrval); - } if (!dont_advance) { attr_type++; - resp >>= 1; + attr_set >>= 1; } } close_message(&strattr); } - mode_cfg_hash(r_hashval,r_hash_start,rbody->cur,st); + modecfg_hash(r_hashval, r_hash_start, rbody->cur,st); close_message(rbody); encrypt_message(rbody, st); return STF_OK; } -/* Set MODE_CONFIG data to client. - * Pack IP Addresses, DNS, etc... and ship +/* + * Send ModeCfg message */ -stf_status modecfg_send_set(struct state *st) +static stf_status +modecfg_send_msg(struct state *st, int isama_type, internal_addr_t *ia) { - pb_stream reply,rbody; - char buf[256]; + pb_stream msg; + pb_stream rbody; + char buf[BUF_LEN]; - /* set up reply */ - init_pbs(&reply, buf, sizeof(buf), "ModecfgR1"); + /* set up attr */ + init_pbs(&msg, buf, sizeof(buf), "ModeCfg msg buffer"); + + /* this is the beginning of a new exchange */ + st->st_msgid = generate_msgid(st); + init_phase2_iv(st, &st->st_msgid); - st->st_state = STATE_MODE_CFG_R1; /* HDR out */ { struct isakmp_hdr hdr; @@ -296,503 +348,280 @@ stf_status modecfg_send_set(struct state *st) memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE); hdr.isa_msgid = st->st_msgid; - if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody)) + if (!out_struct(&hdr, &isakmp_hdr_desc, &msg, &rbody)) { return STF_INTERNAL_ERROR; } } -#define MODECFG_SET_ITEM ( LELEM(INTERNAL_IP4_ADDRESS) | LELEM(INTERNAL_IP4_SUBNET) | LELEM(INTERNAL_IP4_NBNS) | LELEM(INTERNAL_IP4_DNS) ) - - modecfg_resp(st, MODECFG_SET_ITEM - , &rbody - , ISAKMP_CFG_SET - , TRUE - , 0/* XXX ID */); -#undef MODECFG_SET_ITEM + /* ATTR out */ + modecfg_build_msg(st, &rbody + , isama_type + , ia + , 0 /* XXX isama_id */ + ); - clonetochunk(st->st_tpacket, reply.start - , pbs_offset(&reply), "ModeCfg set"); + clonetochunk(st->st_tpacket, msg.start, pbs_offset(&msg), "ModeCfg msg"); /* Transmit */ - send_packet(st, "ModeCfg set"); + send_packet(st, "ModeCfg msg"); - /* RETRANSMIT if Main, SA_REPLACE if Aggressive */ - if (st->st_event->ev_type != EVENT_RETRANSMIT - && st->st_event->ev_type != EVENT_NULL) + if (st->st_event->ev_type != EVENT_RETRANSMIT) { delete_event(st); event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st); } - + st->st_modecfg.started = TRUE; return STF_OK; } -/* Set MODE_CONFIG data to client. - * Pack IP Addresses, DNS, etc... and ship - */ -stf_status -modecfg_start_set(struct state *st) -{ - if (st->st_msgid == 0) - { - /* pick a new message id */ - st->st_msgid = generate_msgid(st); - } - st->st_modecfg.vars_set = TRUE; - - return modecfg_send_set(st); -} - /* - * Send modecfg IP address request (IP4 address) + * Send ModeCfg request message from client to server in pull mode */ stf_status modecfg_send_request(struct state *st) { - pb_stream reply; - pb_stream rbody; - char buf[256]; - u_char *r_hash_start,*r_hashval; + internal_addr_t ia; - /* set up reply */ - init_pbs(&reply, buf, sizeof(buf), "modecfg_buf"); + init_internal_addr(&ia); + ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS) + | LELEM(INTERNAL_IP4_NETMASK); plog("sending ModeCfg request"); - - /* this is the beginning of a new exchange */ - st->st_msgid = generate_msgid(st); st->st_state = STATE_MODE_CFG_I1; + return modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia); +} - /* HDR out */ - { - struct isakmp_hdr hdr; - - zero(&hdr); /* default to 0 */ - hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION; - hdr.isa_np = ISAKMP_NEXT_HASH; - hdr.isa_xchg = ISAKMP_XCHG_MODE_CFG; - hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION; - memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE); - memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE); - hdr.isa_msgid = st->st_msgid; - - if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody)) - { - return STF_INTERNAL_ERROR; - } - } - - START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_ATTR); - - /* ATTR out */ - { - struct isakmp_mode_attr attrh; - struct isakmp_attribute attr; - pb_stream strattr; - - attrh.isama_np = ISAKMP_NEXT_NONE; - attrh.isama_type = ISAKMP_CFG_REQUEST; - attrh.isama_identifier = 0; - if (!out_struct(&attrh, &isakmp_attr_desc, &rbody, &strattr)) - return STF_INTERNAL_ERROR; - /* ISAKMP attr out (ipv4) */ - attr.isaat_af_type = INTERNAL_IP4_ADDRESS; - attr.isaat_lv = 0; - out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, NULL); - - /* ISAKMP attr out (netmask) */ - attr.isaat_af_type = INTERNAL_IP4_NETMASK; - attr.isaat_lv = 0; - out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, NULL); - - close_message(&strattr); - } - - mode_cfg_hash(r_hashval,r_hash_start,rbody.cur,st); - - close_message(&rbody); - close_output_pbs(&reply); - - init_phase2_iv(st, &st->st_msgid); - encrypt_message(&rbody, st); - - clonetochunk(st->st_tpacket, reply.start, pbs_offset(&reply) - , "modecfg: req"); - - /* Transmit */ - send_packet(st, "modecfg: req"); +/* + * Send ModeCfg set message from server to client in push mode + */ +stf_status +modecfg_send_set(struct state *st) +{ + internal_addr_t ia; - /* RETRANSMIT if Main, SA_REPLACE if Aggressive */ - if (st->st_event->ev_type != EVENT_RETRANSMIT) - { - delete_event(st); - event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0 * 3, st); - } - st->st_modecfg.started = TRUE; + get_internal_addr(st->st_connection, &ia); - return STF_OK; + plog("sending ModeCfg set"); + st->st_state = STATE_MODE_CFG_R1; + return modecfg_send_msg(st, ISAKMP_CFG_SET, &ia); } /* - * parse a modecfg attribute payload + * Parse a ModeCfg attribute payload */ static stf_status -modecfg_parse_attributes(pb_stream *attrs, u_int *set) +modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia) { struct isakmp_attribute attr; pb_stream strattr; - while (pbs_left(attrs) > sizeof(struct isakmp_attribute)) + while (pbs_left(attrs) >= sizeof(struct isakmp_attribute)) { + u_int16_t attr_type; + u_int16_t attr_len; + if (!in_struct(&attr, &isakmp_modecfg_attribute_desc, attrs, &strattr)) { - int len = (attr.isaat_af_type & 0x8000)? 4 : attr.isaat_lv; - - if (len < 4) - { - plog("Attribute was too short: %d", len); - return STF_FAIL; - } - - attrs->cur += len; + return STF_FAIL; } + attr_type = attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK; + attr_len = attr.isaat_lv; - switch (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ) + switch (attr_type) { case INTERNAL_IP4_ADDRESS: + if (attr_len == 4) + { + initaddr((char *)(strattr.cur), 4, AF_INET, &ia->ipaddr); + } + /* fall through to set attribute flags */ case INTERNAL_IP4_NETMASK: case INTERNAL_IP4_DNS: case INTERNAL_IP4_SUBNET: case INTERNAL_IP4_NBNS: - *set |= LELEM(attr.isaat_af_type); + ia->attr_set |= LELEM(attr_type); break; default: - plog("unsupported mode cfg attribute %s received." - , enum_show(&modecfg_attr_names - , attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK )); + plog("unsupported ModeCfg attribute %s received." + , enum_show(&modecfg_attr_names, attr_type)); break; } } return STF_OK; } -/* STATE_MODE_CFG_R0: - * HDR*, HASH, ATTR(REQ=IP) --> HDR*, HASH, ATTR(REPLY=IP) - * - * This state occurs both in the responder and in the initiator. - * - * In the responding server, it occurs when the client *asks* for an IP - * address or other information. - * - * Otherwise, it occurs in the initiator when the server sends a challenge - * a set, or has a reply to our request. +/* + * Parse a ModeCfg message */ -stf_status -modecfg_inR0(struct msg_digest *md) +static stf_status +modecfg_parse_msg(struct msg_digest *md, int isama_type, u_int16_t *isama_id + , internal_addr_t *ia) { struct state *const st = md->st; struct payload_digest *p; stf_status stat; - plog("received ModeCfg request"); - st->st_msgid = md->hdr.isa_msgid; - CHECK_QUICK_HASH(md, mode_cfg_hash(hash_val - ,hash_pbs->roof - , md->message_pbs.roof, st) - , "MODECFG-HASH", "MODE R0"); - /* process the MODECFG payloads therein */ + CHECK_QUICK_HASH(md, modecfg_hash(hash_val + , hash_pbs->roof + , md->message_pbs.roof, st) + , "MODECFG-HASH", "ISAKMP_CFG_MSG"); + + /* process the ModeCfg payloads received */ for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next) { - u_int set_modecfg_attrs = LEMPTY; - - switch (p->payload.attribute.isama_type) - { - default: - plog("Expecting ISAKMP_CFG_REQUEST, got %s instead (ignored)." - , enum_name(&attr_msg_type_names - , p->payload.attribute.isama_type)); - - stat = modecfg_parse_attributes(&p->pbs, &set_modecfg_attrs); - if (stat != STF_OK) - return stat; - break; + internal_addr_t ia_candidate; - case ISAKMP_CFG_REQUEST: - stat = modecfg_parse_attributes(&p->pbs, &set_modecfg_attrs); - if (stat != STF_OK) - return stat; + init_internal_addr(&ia_candidate); - stat = modecfg_resp(st, set_modecfg_attrs - ,&md->rbody - ,ISAKMP_CFG_REPLY - ,TRUE - ,p->payload.attribute.isama_identifier); + if (p->payload.attribute.isama_type == isama_type) + { + *isama_id = p->payload.attribute.isama_identifier; - if (stat != STF_OK) + stat = modecfg_parse_attributes(&p->pbs, &ia_candidate); + if (stat == STF_OK) { - /* notification payload - not exactly the right choice, but okay */ - md->note = CERTIFICATE_UNAVAILABLE; - return stat; + /* retrun with a valid set of attributes */ + *ia = ia_candidate; + return STF_OK; } + } + else + { + plog("expected %s, got %s instead (ignored)" + , enum_name(&attr_msg_type_names, isama_type) + , enum_name(&attr_msg_type_names, p->payload.attribute.isama_type)); - /* they asked us, we responded, msgid is done */ - st->st_msgid = 0; + stat = modecfg_parse_attributes(&p->pbs, &ia_candidate); } + if (stat != STF_OK) + return stat; } - return STF_OK; + return STF_IGNORE; } -/* STATE_MODE_CFG_R2: - * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK) +/* STATE_MODE_CFG_R0: + * HDR*, HASH, ATTR(REQ=IP) --> HDR*, HASH, ATTR(REPLY=IP) * - * used in server push mode, on the client (initiator). + * used in ModeCfg pull mode, on the server (responder) */ -static stf_status -modecfg_inI2(struct msg_digest *md) +stf_status +modecfg_inR0(struct msg_digest *md) { struct state *const st = md->st; - pb_stream *attrs = &md->chain[ISAKMP_NEXT_ATTR]->pbs; - int resp = LEMPTY; + u_int16_t isama_id; + internal_addr_t ia; stf_status stat; - struct payload_digest *p; - u_int16_t isama_id = 0; - - st->st_msgid = md->hdr.isa_msgid; - CHECK_QUICK_HASH(md - , mode_cfg_hash(hash_val - ,hash_pbs->roof - , md->message_pbs.roof - , st) - , "MODECFG-HASH", "MODE R1"); - - for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next) - { - struct isakmp_attribute attr; - pb_stream strattr; - isama_id = p->payload.attribute.isama_identifier; - - if (p->payload.attribute.isama_type != ISAKMP_CFG_SET) - { - plog("Expecting MODE_CFG_SET, got %x instead." - ,md->chain[ISAKMP_NEXT_ATTR]->payload.attribute.isama_type); - return STF_IGNORE; - } - - /* CHECK that SET has been received. */ - - while (pbs_left(attrs) > sizeof(struct isakmp_attribute)) - { - if (!in_struct(&attr, &isakmp_modecfg_attribute_desc - , attrs, &strattr)) - { - int len; - - /* Skip unknown */ - if (attr.isaat_af_type & 0x8000) - len = 4; - else - len = attr.isaat_lv; - - if (len < 4) - { - plog("Attribute was too short: %d", len); - return STF_FAIL; - } - - attrs->cur += len; - } - - switch (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ) - { - case INTERNAL_IP4_ADDRESS: - { - struct connection *c = st->st_connection; - ip_address a; - u_int32_t *ap = (u_int32_t *)(strattr.cur); - a.u.v4.sin_family = AF_INET; - - memcpy(&a.u.v4.sin_addr.s_addr, ap - , sizeof(a.u.v4.sin_addr.s_addr)); - - if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0 - || isanyaddr(&c->spd.this.host_srcip)) - { - char srcip[ADDRTOT_BUF]; - - c->spd.this.host_srcip = a; - addrtot(&a, 0, srcip, sizeof(srcip)); - plog("setting virtual IP source address to %s", srcip); - } - - /* setting client subnet as srcip/32 */ - addrtosubnet(&a, &c->spd.this.client); - c->spd.this.has_client = TRUE; - } - resp |= LELEM(attr.isaat_af_type); - break; - case INTERNAL_IP4_NETMASK: - case INTERNAL_IP4_DNS: - case INTERNAL_IP4_SUBNET: - case INTERNAL_IP4_NBNS: - resp |= LELEM(attr.isaat_af_type); - break; - default: - plog("unsupported mode cfg attribute %s received." - , enum_show(&modecfg_attr_names, (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ))); - break; - } - } - } + stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia); + if (stat != STF_OK) + return stat; - /* ack things */ - stat = modecfg_resp(st, resp - ,&md->rbody - ,ISAKMP_CFG_ACK - ,FALSE - ,isama_id); + get_internal_addr(st->st_connection, &ia); + /* build ISAKMP_CFG_REPLY */ + stat = modecfg_build_msg(st, &md->rbody + , ISAKMP_CFG_REPLY + , &ia + , isama_id); if (stat != STF_OK) { /* notification payload - not exactly the right choice, but okay */ - md->note = CERTIFICATE_UNAVAILABLE; + md->note = ATTRIBUTES_NOT_SUPPORTED; return stat; } - /* - * we are done with this exchange, clear things so - * that we can start phase 2 properly - */ st->st_msgid = 0; - - if (resp) - { - st->st_modecfg.vars_set = TRUE; - } return STF_OK; } /* STATE_MODE_CFG_R1: - * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK) + * HDR*, HASH, ATTR(ACK,OK) + * + * used in ModeCfg push mode, on the server (responder) */ stf_status modecfg_inR1(struct msg_digest *md) { struct state *const st = md->st; - pb_stream *attrs = &md->chain[ISAKMP_NEXT_ATTR]->pbs; - int set_modecfg_attrs = LEMPTY; + u_int16_t isama_id; + internal_addr_t ia; stf_status stat; - struct payload_digest *p; - plog("parsing ModeCfg reply"); - - st->st_msgid = md->hdr.isa_msgid; - CHECK_QUICK_HASH(md, mode_cfg_hash(hash_val,hash_pbs->roof, md->message_pbs.roof, st) - , "MODECFG-HASH", "MODE R1"); + plog("parsing ModeCfg ack"); + stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia); + if (stat != STF_OK) + return stat; - /* process the MODECFG payloads therein */ - for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next) - { - struct isakmp_attribute attr; - pb_stream strattr; - - attrs = &p->pbs; - - switch (p->payload.attribute.isama_type) - { - default: - { - plog("Expecting MODE_CFG_ACK, got %x instead." - ,md->chain[ISAKMP_NEXT_ATTR]->payload.attribute.isama_type); - return STF_IGNORE; - } - break; - - case ISAKMP_CFG_ACK: - /* CHECK that ACK has been received. */ - stat = modecfg_parse_attributes(attrs, &set_modecfg_attrs); - if (stat != STF_OK) - return stat; - break; + st->st_msgid = 0; + return STF_OK; +} - case ISAKMP_CFG_REPLY: - while (pbs_left(attrs) > sizeof(struct isakmp_attribute)) - { - if (!in_struct(&attr, &isakmp_modecfg_attribute_desc - , attrs, &strattr)) - { - /* Skip unknown */ - int len; - if (attr.isaat_af_type & 0x8000) - len = 4; - else - len = attr.isaat_lv; - - if (len < 4) - { - plog("Attribute was too short: %d", len); - return STF_FAIL; - } +/* STATE_MODE_CFG_I1: + * HDR*, HASH, ATTR(REPLY=IP) + * + * used in ModeCfg pull mode, on the client (initiator) + */ +stf_status +modecfg_inI1(struct msg_digest *md) +{ + struct state *const st = md->st; + u_int16_t isama_id; + internal_addr_t ia; + stf_status stat; - attrs->cur += len; - } + plog("parsing ModeCfg reply"); - switch (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ) - { - case INTERNAL_IP4_ADDRESS: - { - struct connection *c = st->st_connection; - ip_address a; - u_int32_t *ap = (u_int32_t *)(strattr.cur); - a.u.v4.sin_family = AF_INET; + stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia); + if (stat != STF_OK) + return stat; - memcpy(&a.u.v4.sin_addr.s_addr, ap - , sizeof(a.u.v4.sin_addr.s_addr)); + st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia); + st->st_msgid = 0; + return STF_OK; +} - if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0 - || isanyaddr(&c->spd.this.host_srcip)) - { - char srcip[ADDRTOT_BUF]; +/* STATE_MODE_CFG_I2: + * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK) + * + * used in ModeCfg push mode, on the client (initiator). + */ +stf_status +modecfg_inI2(struct msg_digest *md) +{ + struct state *const st = md->st; + u_int16_t isama_id; + internal_addr_t ia; + lset_t attr_set; + stf_status stat; - c->spd.this.host_srcip = a; - addrtot(&a, 0, srcip, sizeof(srcip)); - plog("setting virtual IP source address to %s", srcip); - } + plog("parsing ModeCfg set"); - /* setting client subnet as srcip/32 */ - addrtosubnet(&a, &c->spd.this.client); - setportof(0, &c->spd.this.client.addr); - c->spd.this.has_client = TRUE; - } - /* fall through to set attribute flage */ + stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia); + if (stat != STF_OK) + return stat; - case INTERNAL_IP4_NETMASK: - case INTERNAL_IP4_DNS: - case INTERNAL_IP4_SUBNET: - case INTERNAL_IP4_NBNS: - set_modecfg_attrs |= LELEM(attr.isaat_af_type); - break; - default: - plog("unsupported mode cfg attribute %s received." - , enum_show(&modecfg_attr_names - , (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ))); - break; - } - } - break; - } - } + st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia); - /* we are done with this exchange, clear things so that we can start phase 2 properly */ - st->st_msgid = 0; + /* prepare ModeCfg ack which sends zero length attributes */ + attr_set = ia.attr_set; + init_internal_addr(&ia); + ia.attr_set = attr_set & SUPPORTED_ATTR_SET; - if (set_modecfg_attrs) + stat = modecfg_build_msg(st, &md->rbody + , ISAKMP_CFG_ACK + , &ia + , isama_id); + if (stat != STF_OK) { - st->st_modecfg.vars_set = TRUE; + /* notification payload - not exactly the right choice, but okay */ + md->note = ATTRIBUTES_NOT_SUPPORTED; + return stat; } + + st->st_msgid = 0; return STF_OK; } diff --git a/programs/pluto/modecfg.h b/programs/pluto/modecfg.h index f6856d263..1f8259ca8 100644 --- a/programs/pluto/modecfg.h +++ b/programs/pluto/modecfg.h @@ -12,22 +12,17 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: modecfg.h,v 1.1 2005/01/06 22:10:15 as Exp $ + * RCSID $Id: modecfg.h,v 1.3 2006/10/19 21:07:40 as Exp $ */ struct state; -stf_status modecfg_resp(struct state *st - , u_int resp - , pb_stream *s, u_int16_t cmd - , bool hackthat, u_int16_t id); - -stf_status modecfg_send_set(struct state *st); - -extern stf_status modecfg_start_set(struct state *st); - -/* Mode Config States */ +/* ModeConfig starting functions */ +extern stf_status modecfg_send_request(struct state *st); +extern stf_status modecfg_send_set(struct state *st); +/* ModeConfig state transition functions */ extern stf_status modecfg_inR0(struct msg_digest *md); extern stf_status modecfg_inR1(struct msg_digest *md); -extern stf_status modecfg_send_request(struct state *st); +extern stf_status modecfg_inI1(struct msg_digest *md); +extern stf_status modecfg_inI2(struct msg_digest *md); diff --git a/programs/pluto/state.c b/programs/pluto/state.c index 0781d2eb3..8181c34b4 100644 --- a/programs/pluto/state.c +++ b/programs/pluto/state.c @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: state.c,v 1.13 2006/04/29 18:16:02 as Exp $ + * RCSID $Id: state.c,v 1.15 2006/10/20 15:02:23 as Exp $ */ #include <stdio.h> @@ -716,7 +716,7 @@ state_eroute_usage(ip_subnet *ours, ip_subnet *his }); } -void fmt_state(struct state *st, time_t n +void fmt_state(bool all, struct state *st, time_t n , char *state_buf, size_t state_buf_len , char *state_buf2, size_t state_buf2_len) { @@ -735,20 +735,22 @@ void fmt_state(struct state *st, time_t n /* XXX spd-enum */ const char *eo = c->spd.eroute_owner == st->st_serialno ? "; eroute owner" : ""; - + const char *dpd = (all && st->st_dpd && c->dpd_action != DPD_ACTION_NONE) + ? "; DPD active" : ""; + passert(st->st_event != 0); fmt_conn_instance(c, inst); snprintf(state_buf, state_buf_len - , "#%lu: \"%s\"%s %s (%s); %s in %lds%s%s%s" + , "#%lu: \"%s\"%s %s (%s); %s in %lds%s%s%s%s" , st->st_serialno , c->name, inst , enum_name(&state_names, st->st_state) , state_story[st->st_state - STATE_MAIN_R0] , enum_name(&timer_event_names, st->st_event->ev_type) , delta - , np1, np2, eo); + , np1, np2, eo, dpd); /* print out SPIs if SAs are established */ if (state_buf2_len != 0) @@ -846,7 +848,7 @@ state_compare(const void *a, const void *b) } void -show_states_status(const char *name) +show_states_status(bool all, const char *name) { time_t n = now(); int i; @@ -892,7 +894,8 @@ show_states_status(const char *name) st = array[i]; - fmt_state(st, n, state_buf, sizeof(state_buf) + fmt_state(all, st, n + , state_buf, sizeof(state_buf) , state_buf2, sizeof(state_buf2)); whack_log(RC_COMMENT, state_buf); if (state_buf2[0] != '\0') diff --git a/programs/pluto/state.h b/programs/pluto/state.h index 2f30d77f1..c7212fd1a 100644 --- a/programs/pluto/state.h +++ b/programs/pluto/state.h @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: state.h,v 1.11 2006/03/08 22:12:37 as Exp $ + * RCSID $Id: state.h,v 1.12 2006/10/17 10:30:54 as Exp $ */ #include <sys/types.h> @@ -259,11 +259,11 @@ extern struct state *find_phase1_state(const struct connection *c, lset_t ok_states), *find_sender(size_t packet_len, u_char *packet); -extern void show_states_status(const char *name); +extern void show_states_status(bool all, const char *name); extern void for_each_state(void *(f)(struct state *, void *data), void *data); extern void find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi); extern ipsec_spi_t uniquify_his_cpi(ipsec_spi_t cpi, struct state *st); -extern void fmt_state(struct state *st, time_t n +extern void fmt_state(bool all, struct state *st, time_t n , char *state_buf, size_t state_buf_len , char *state_buf2, size_t state_buf_len2); extern void delete_states_by_peer(ip_address *peer); diff --git a/programs/pluto/vendor.c b/programs/pluto/vendor.c index a51971cde..cbb26a5ef 100644 --- a/programs/pluto/vendor.c +++ b/programs/pluto/vendor.c @@ -11,7 +11,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: vendor.c,v 1.39 2006/07/06 12:32:41 as Exp $ + * RCSID $Id: vendor.c,v 1.41 2006/10/19 15:21:08 as Exp $ */ #include <stdlib.h> @@ -200,9 +200,13 @@ static struct vid_struct _vid_tab[] = { */ DEC_MD5_VID(STRONGSWAN_4_0_0, "strongSwan 4.0.0") DEC_MD5_VID(STRONGSWAN_4_0_1, "strongSwan 4.0.1") - DEC_MD5_VID(STRONGSWAN_4_0_1, "strongSwan 4.0.2") + DEC_MD5_VID(STRONGSWAN_4_0_2, "strongSwan 4.0.2") + DEC_MD5_VID(STRONGSWAN_4_0_3, "strongSwan 4.0.3") + DEC_MD5_VID(STRONGSWAN_4_0_4, "strongSwan 4.0.4") + DEC_MD5_VID(STRONGSWAN_4_0_5, "strongSwan 4.0.5") - DEC_MD5_VID(STRONGSWAN, "strongSwan 2.7.3") + DEC_MD5_VID(STRONGSWAN, "strongSwan 2.8.0") + DEC_MD5_VID(STRONGSWAN_2_7_3, "strongSwan 2.7.3") DEC_MD5_VID(STRONGSWAN_2_7_2, "strongSwan 2.7.2") DEC_MD5_VID(STRONGSWAN_2_7_1, "strongSwan 2.7.1") DEC_MD5_VID(STRONGSWAN_2_7_0, "strongSwan 2.7.0") diff --git a/programs/pluto/vendor.h b/programs/pluto/vendor.h index c4ed6d294..c7f70a480 100644 --- a/programs/pluto/vendor.h +++ b/programs/pluto/vendor.h @@ -11,7 +11,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: vendor.h,v 1.34 2006/07/06 12:32:41 as Exp $ + * RCSID $Id: vendor.h,v 1.36 2006/10/19 15:21:08 as Exp $ */ #ifndef _VENDOR_H_ @@ -79,10 +79,14 @@ enum known_vendorid { VID_STRONGSWAN_2_7_0 = 58, VID_STRONGSWAN_2_7_1 = 59, VID_STRONGSWAN_2_7_2 = 60, + VID_STRONGSWAN_2_7_3 = 61, VID_STRONGSWAN_4_0_0 = 70, VID_STRONGSWAN_4_0_1 = 71, VID_STRONGSWAN_4_0_2 = 72, + VID_STRONGSWAN_4_0_3 = 73, + VID_STRONGSWAN_4_0_4 = 74, + VID_STRONGSWAN_4_0_5 = 75, /* 101 - 200 : NAT-Traversal */ VID_NATT_STENBERG_01 =101, diff --git a/programs/pluto/whack.h b/programs/pluto/whack.h index 3086f1543..755918a2c 100644 --- a/programs/pluto/whack.h +++ b/programs/pluto/whack.h @@ -11,7 +11,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: whack.h,v 1.16 2006/04/17 10:39:14 as Exp $ + * RCSID $Id: whack.h,v 1.17 2006/10/19 15:18:43 as Exp $ */ #ifndef _WHACK_H @@ -62,6 +62,7 @@ struct whack_end { bool has_client_wildcard; bool has_port_wildcard; bool has_srcip; + bool has_natip; bool modecfg; bool hostaccess; certpolicy_t sendcert; diff --git a/programs/starter/args.c b/programs/starter/args.c index 6f3da63eb..2b2853a20 100644 --- a/programs/starter/args.c +++ b/programs/starter/args.c @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: args.c,v 1.9 2006/04/17 10:32:36 as Exp $ + * RCSID $Id: args.c,v 1.10 2006/10/19 14:58:30 as Exp $ */ #include <stddef.h> @@ -191,6 +191,7 @@ static const token_info_t token_info[] = { ARG_TIME, offsetof(starter_conn_t, dpd_delay), NULL }, { ARG_TIME, offsetof(starter_conn_t, dpd_timeout), NULL }, { ARG_ENUM, offsetof(starter_conn_t, dpd_action), LST_dpd_action }, + { ARG_MISC, 0, NULL /* KW_MODECONFIG */ }, /* ca section keywords */ { ARG_STR, offsetof(starter_ca_t, name), NULL }, @@ -209,6 +210,7 @@ static const token_info_t token_info[] = { ARG_MISC, 0, NULL /* KW_SUBNETWITHIN */ }, { ARG_MISC, 0, NULL /* KW_PROTOPORT */ }, { ARG_MISC, 0, NULL /* KW_SOURCEIP */ }, + { ARG_MISC, 0, NULL /* KW_NATIP */ }, { ARG_ENUM, offsetof(starter_end_t, firewall), LST_bool }, { ARG_ENUM, offsetof(starter_end_t, hostaccess), LST_bool }, { ARG_STR, offsetof(starter_end_t, updown), NULL }, diff --git a/programs/starter/confread.c b/programs/starter/confread.c index af0f00877..edd041ab4 100644 --- a/programs/starter/confread.c +++ b/programs/starter/confread.c @@ -11,7 +11,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: confread.c,v 1.38 2006/06/20 21:52:53 as Exp $ + * RCSID $Id: confread.c,v 1.39 2006/10/19 14:58:30 as Exp $ */ #include <stddef.h> @@ -255,6 +255,11 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token end->has_port_wildcard = has_port_wildcard; break; case KW_SOURCEIP: + if (end->has_natip) + { + plog("# natip and sourceip cannot be defined at the same time"); + goto err; + } if (streq(value, "%modeconfig") || streq(value, "%modecfg")) { end->modecfg = TRUE; @@ -272,6 +277,22 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token } conn->policy |= POLICY_TUNNEL; break; + case KW_NATIP: + if (end->has_srcip) + { + plog("# natip and sourceip cannot be defined at the same time"); + goto err; + } + conn->tunnel_addr_family = ip_version(value); + ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &end->srcip); + if (ugh != NULL) + { + plog("# bad addr: %s=%s [%s]", name, value, ugh); + goto err; + } + end->has_natip = TRUE; + conn->policy |= POLICY_TUNNEL; + break; default: break; } @@ -430,6 +451,9 @@ load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg) case KW_REKEY: KW_POLICY_FLAG("no", "yes", POLICY_DONT_REKEY) break; + case KW_MODECONFIG: + KW_POLICY_FLAG("push", "pull", POLICY_MODECFG_PUSH) + break; default: break; } diff --git a/programs/starter/confread.h b/programs/starter/confread.h index a3b1b7379..052f5d527 100644 --- a/programs/starter/confread.h +++ b/programs/starter/confread.h @@ -11,7 +11,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: confread.h,v 1.23 2006/04/17 10:32:36 as Exp $ + * RCSID $Id: confread.h,v 1.24 2006/10/19 15:01:05 as Exp $ */ #ifndef _IPSEC_CONFREAD_H_ @@ -49,15 +49,16 @@ struct starter_end { char *cert; char *ca; char *groups; - char *iface; + char *iface; ip_address addr; ip_address nexthop; ip_address srcip; - ip_subnet subnet; + ip_subnet subnet; bool has_client; bool has_client_wildcard; - bool has_port_wildcard; + bool has_port_wildcard; bool has_srcip; + bool has_natip; bool modecfg; certpolicy_t sendcert; bool firewall; diff --git a/programs/starter/keywords.c b/programs/starter/keywords.c index 4cc5c03e8..75be0a542 100644 --- a/programs/starter/keywords.c +++ b/programs/starter/keywords.c @@ -44,7 +44,7 @@ error "gperf generated tables don't work with this execution character set. Plea * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: keywords.c,v 1.7 2006/04/17 10:32:48 as Exp $ + * RCSID $Id: keywords.c,v 1.8 2006/10/19 14:58:30 as Exp $ */ #include <string.h> @@ -56,12 +56,12 @@ struct kw_entry { kw_token_t token; }; -#define TOTAL_KEYWORDS 77 +#define TOTAL_KEYWORDS 80 #define MIN_WORD_LENGTH 3 #define MAX_WORD_LENGTH 17 #define MIN_HASH_VALUE 9 -#define MAX_HASH_VALUE 146 -/* maximum key range = 138, duplicates = 0 */ +#define MAX_HASH_VALUE 156 +/* maximum key range = 148, duplicates = 0 */ #ifdef __GNUC__ __inline @@ -77,32 +77,32 @@ hash (str, len) { static const unsigned char asso_values[] = { - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 15, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 85, 147, 40, - 25, 25, 0, 10, 5, 80, 147, 35, 60, 35, - 60, 55, 10, 147, 15, 20, 5, 65, 147, 147, - 147, 35, 0, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147 + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 25, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 90, 157, 60, + 50, 25, 0, 10, 5, 65, 157, 65, 70, 5, + 0, 75, 35, 157, 10, 20, 5, 70, 157, 157, + 157, 55, 0, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157 }; return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[len - 1]]; } @@ -111,104 +111,113 @@ static const struct kw_entry wordlist[] = { {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {"left", KW_LEFT}, - {""}, {""}, {""}, + {"leftupdown", KW_LEFTUPDOWN}, + {""}, {""}, {"leftcert", KW_LEFTCERT,}, {"auth", KW_AUTH}, {"leftsubnet", KW_LEFTSUBNET}, - {""}, + {"leftsubnetwithin", KW_LEFTSUBNETWITHIN}, {"leftsendcert", KW_LEFTSENDCERT}, {"leftprotoport", KW_LEFTPROTOPORT}, {""}, {"right", KW_RIGHT}, - {"leftnexthop", KW_LEFTNEXTHOP}, - {"leftsourceip", KW_LEFTSOURCEIP}, - {"esp", KW_ESP}, + {"rightupdown", KW_RIGHTUPDOWN}, + {"dumpdir", KW_DUMPDIR}, + {""}, {"rightcert", KW_RIGHTCERT}, {""}, {"rightsubnet", KW_RIGHTSUBNET}, - {""}, + {"rightsubnetwithin", KW_RIGHTSUBNETWITHIN}, {"rightsendcert", KW_RIGHTSENDCERT}, {"rightprotoport", KW_RIGHTPROTOPORT}, {"leftgroups", KW_LEFTGROUPS}, - {"leftid", KW_LEFTID}, - {"rightnexthop", KW_RIGHTNEXTHOP}, - {"rightsourceip", KW_RIGHTSOURCEIP}, + {""}, {""}, + {"compress", KW_COMPRESS}, {"lefthostaccess", KW_LEFTHOSTACCESS}, {"interfaces", KW_INTERFACES}, + {""}, {""}, {""}, {""}, {""}, + {"rightgroups", KW_RIGHTGROUPS}, + {""}, + {"pfs", KW_PFS}, + {"leftnatip", KW_LEFTNATIP}, + {"righthostaccess", KW_RIGHTHOSTACCESS}, + {"leftnexthop", KW_LEFTNEXTHOP}, + {"leftsourceip", KW_LEFTSOURCEIP}, {""}, {""}, + {"virtual_private", KW_VIRTUAL_PRIVATE}, + {""}, {""}, + {"ike", KW_IKE}, + {""}, + {"rightnatip", KW_RIGHTNATIP}, + {"leftid", KW_LEFTID}, + {"rightnexthop", KW_RIGHTNEXTHOP}, + {"rightsourceip", KW_RIGHTSOURCEIP}, + {"dpdaction", KW_DPDACTION}, + {"keep_alive", KW_KEEP_ALIVE}, + {"ikelifetime", KW_IKELIFETIME}, + {""}, {"pfsgroup", KW_PFSGROUP}, {"type", KW_TYPE}, {"dpdtimeout", KW_DPDTIMEOUT}, - {"rightgroups", KW_RIGHTGROUPS}, - {"rightid", KW_RIGHTID}, - {"pfs", KW_PFS}, - {"rekeyfuzz", KW_REKEYFUZZ}, - {"righthostaccess", KW_RIGHTHOSTACCESS}, {"authby", KW_AUTHBY}, - {""}, + {"rightid", KW_RIGHTID}, {"leftrsasigkey", KW_LEFTRSASIGKEY}, - {""}, {""}, + {""}, + {"modeconfig", KW_MODECONFIG}, {"cacert", KW_CACERT}, - {"hidetos", KW_HIDETOS}, - {"ike", KW_IKE}, {""}, - {"virtual_private", KW_VIRTUAL_PRIVATE}, + {"esp", KW_ESP}, + {"rekeyfuzz", KW_REKEYFUZZ}, {""}, - {"dumpdir", KW_DUMPDIR}, + {"rekeymargin", KW_REKEYMARGIN}, + {"hidetos", KW_HIDETOS}, {"packetdefault", KW_PACKETDEFAULT}, {"rightrsasigkey", KW_RIGHTRSASIGKEY}, - {"keep_alive", KW_KEEP_ALIVE}, - {"ikelifetime", KW_IKELIFETIME}, + {"strictcrlpolicy", KW_STRICTCRLPOLICY}, + {""}, + {"leftfirewall", KW_LEFTFIREWALL}, {""}, - {"compress", KW_COMPRESS}, {"auto", KW_AUTO}, - {"strictcrlpolicy", KW_STRICTCRLPOLICY}, + {"klipsdebug", KW_KLIPSDEBUG}, {"keyingtries", KW_KEYINGTRIES}, {"keylife", KW_KEYLIFE}, - {"dpddelay", KW_DPDDELAY}, + {"nat_traversal", KW_NAT_TRAVERSAL}, {"cachecrls", KW_CACHECRLS}, - {"leftupdown", KW_LEFTUPDOWN}, + {"plutodebug", KW_PLUTODEBUG}, {"keyexchange", KW_KEYEXCHANGE}, - {"leftfirewall", KW_LEFTFIREWALL}, - {"nocrsend", KW_NOCRSEND}, + {"ocspuri", KW_OCSPURI}, + {"rightfirewall", KW_RIGHTFIREWALL}, + {"uniqueids", KW_UNIQUEIDS}, {""}, - {"rekey", KW_REKEY}, - {"leftsubnetwithin", KW_LEFTSUBNETWITHIN}, + {"leftca", KW_LEFTCA}, {"pkcs11module", KW_PKCS11MODULE}, - {"nat_traversal", KW_NAT_TRAVERSAL}, + {""}, {"also", KW_ALSO}, {"pkcs11keepstate", KW_PKCS11KEEPSTATE}, - {"rightupdown", KW_RIGHTUPDOWN}, + {""}, {"crluri2", KW_CRLURI2}, - {"rightfirewall", KW_RIGHTFIREWALL}, - {"postpluto", KW_POSTPLUTO}, - {"plutodebug", KW_PLUTODEBUG}, - {"pkcs11proxy", KW_PKCS11PROXY}, - {"rightsubnetwithin", KW_RIGHTSUBNETWITHIN}, - {"prepluto", KW_PREPLUTO}, - {""}, {""}, - {"leftca", KW_LEFTCA}, - {""}, {""}, - {"dpdaction", KW_DPDACTION}, - {""}, {""}, {""}, {"ldaphost", KW_LDAPHOST}, + {"postpluto", KW_POSTPLUTO}, {""}, - {"klipsdebug", KW_KLIPSDEBUG}, {"overridemtu", KW_OVERRIDEMTU}, {"rightca", KW_RIGHTCA}, - {"fragicmp", KW_FRAGICMP}, - {""}, {""}, - {"rekeymargin", KW_REKEYMARGIN}, - {"ocspuri", KW_OCSPURI}, - {""}, - {"uniqueids", KW_UNIQUEIDS}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {"prepluto", KW_PREPLUTO}, + {""}, {""}, {""}, {""}, + {"dpddelay", KW_DPDDELAY}, + {""}, {""}, {""}, {""}, + {"nocrsend", KW_NOCRSEND}, + {""}, {""}, {""}, {""}, {"ldapbase", KW_LDAPBASE}, + {""}, + {"rekey", KW_REKEY}, + {"pkcs11proxy", KW_PKCS11PROXY}, + {""}, {""}, {""}, {""}, {""}, {""}, + {"fragicmp", KW_FRAGICMP}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {"crluri", KW_CRLURI}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {"crlcheckinterval", KW_CRLCHECKINTERVAL}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {"crluri", KW_CRLURI} + {""}, {""}, {""}, {""}, {""}, + {"crlcheckinterval", KW_CRLCHECKINTERVAL} }; #ifdef __GNUC__ diff --git a/programs/starter/keywords.h b/programs/starter/keywords.h index 6542ae1be..be3aabf3b 100644 --- a/programs/starter/keywords.h +++ b/programs/starter/keywords.h @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: keywords.h,v 1.8 2006/04/17 10:30:27 as Exp $ + * RCSID $Id: keywords.h,v 1.9 2006/10/19 14:57:56 as Exp $ */ #ifndef _KEYWORDS_H_ @@ -76,9 +76,10 @@ typedef enum { KW_DPDDELAY, KW_DPDTIMEOUT, KW_DPDACTION, + KW_MODECONFIG, #define KW_CONN_FIRST KW_CONN_SETUP -#define KW_CONN_LAST KW_DPDACTION +#define KW_CONN_LAST KW_MODECONFIG /* ca section keywords */ KW_CA_NAME, @@ -100,6 +101,7 @@ typedef enum { KW_SUBNETWITHIN, KW_PROTOPORT, KW_SOURCEIP, + KW_NATIP, KW_FIREWALL, KW_HOSTACCESS, KW_UPDOWN, @@ -121,6 +123,7 @@ typedef enum { KW_LEFTSUBNETWITHIN, KW_LEFTPROTOPORT, KW_LEFTSOURCEIP, + KW_LEFTNATIP, KW_LEFTFIREWALL, KW_LEFTHOSTACCESS, KW_LEFTUPDOWN, @@ -141,6 +144,7 @@ typedef enum { KW_RIGHTSUBNETWITHIN, KW_RIGHTPROTOPORT, KW_RIGHTSOURCEIP, + KW_RIGHTNATIP, KW_RIGHTFIREWALL, KW_RIGHTHOSTACCESS, KW_RIGHTUPDOWN, diff --git a/programs/starter/keywords.txt b/programs/starter/keywords.txt index dcfdafc98..fc9e49e47 100644 --- a/programs/starter/keywords.txt +++ b/programs/starter/keywords.txt @@ -13,7 +13,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: keywords.txt,v 1.6 2006/04/17 10:30:27 as Exp $ + * RCSID $Id: keywords.txt,v 1.7 2006/10/19 14:57:56 as Exp $ */ #include <string.h> @@ -65,6 +65,7 @@ pfsgroup, KW_PFSGROUP dpddelay, KW_DPDDELAY dpdtimeout, KW_DPDTIMEOUT dpdaction, KW_DPDACTION +modeconfig, KW_MODECONFIG cacert, KW_CACERT ldaphost, KW_LDAPHOST ldapbase, KW_LDAPBASE @@ -77,6 +78,7 @@ leftsubnet, KW_LEFTSUBNET leftsubnetwithin, KW_LEFTSUBNETWITHIN leftprotoport, KW_LEFTPROTOPORT leftsourceip, KW_LEFTSOURCEIP +leftnatip, KW_LEFTNATIP leftfirewall, KW_LEFTFIREWALL lefthostaccess, KW_LEFTHOSTACCESS leftupdown, KW_LEFTUPDOWN @@ -92,6 +94,7 @@ rightsubnet, KW_RIGHTSUBNET rightsubnetwithin, KW_RIGHTSUBNETWITHIN rightprotoport, KW_RIGHTPROTOPORT rightsourceip, KW_RIGHTSOURCEIP +rightnatip, KW_RIGHTNATIP rightfirewall, KW_RIGHTFIREWALL righthostaccess, KW_RIGHTHOSTACCESS rightupdown, KW_RIGHTUPDOWN diff --git a/programs/starter/starterwhack.c b/programs/starter/starterwhack.c index 0d7a3715e..b4bf2fb9d 100644 --- a/programs/starter/starterwhack.c +++ b/programs/starter/starterwhack.c @@ -11,7 +11,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: starterwhack.c,v 1.18 2006/06/20 21:52:53 as Exp $ + * RCSID $Id: starterwhack.c,v 1.19 2006/10/19 15:02:46 as Exp $ */ #include <sys/types.h> @@ -171,6 +171,7 @@ set_whack_end(whack_end_t *w, starter_end_t *end) w->has_client_wildcard = end->has_client_wildcard; w->has_port_wildcard = end->has_port_wildcard; w->has_srcip = end->has_srcip; + w->has_natip = end->has_natip; w->modecfg = end->modecfg; w->hostaccess = end->hostaccess; w->sendcert = end->sendcert; diff --git a/testing/INSTALL b/testing/INSTALL index 055219ae6..cfb9f1806 100644 --- a/testing/INSTALL +++ b/testing/INSTALL @@ -53,7 +53,7 @@ are required for the strongSwan testing environment: * A vanilla Linux kernel on which the UML kernel will be based on. We recommend the use of - http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.17.7.tar.bz2 + http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.1.tar.bz2 * Starting with Linux kernel 2.6.9 no patch must be applied any more in order to make the vanilla kernel UML-capable. For older kernels you'll find @@ -63,15 +63,15 @@ are required for the strongSwan testing environment: * The matching .config file required to compile the UML kernel: - http://download.strongswan.org/uml/.config-2.6.17 + http://download.strongswan.org/uml/.config-2.6.18 * A gentoo-based UML file system (compressed size 130 MBytes) found at - http://download.strongswan.org/uml/gentoo-fs-20060330.tar.bz2 + http://download.strongswan.org/uml/gentoo-fs-20061006.tar.bz2 * The latest strongSwan distribution - http://download.strongswan.org/strongswan-2.7.3.tar.gz + http://download.strongswan.org/strongswan-2.8.0.tar.gz 3. Creating the environment @@ -146,5 +146,5 @@ README document. ----------------------------------------------------------------------------- -This file is RCSID $Id: INSTALL,v 1.43 2006/08/03 10:20:54 as Exp $ +This file is RCSID $Id: INSTALL,v 1.43 2006/10/19 15:36:10 as Exp $ diff --git a/testing/do-tests b/testing/do-tests index ceddd72d8..6119d37d4 100755 --- a/testing/do-tests +++ b/testing/do-tests @@ -14,7 +14,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: do-tests,v 1.20 2006/02/08 21:27:59 as Exp $ +# RCSID $Id: do-tests,v 1.21 2006/10/19 21:12:43 as Exp $ DIR=`dirname $0` @@ -68,15 +68,16 @@ cp -rfp $DEFAULTTESTSDIR/* $TESTSDIR for host in $STRONGSWANHOSTS do - eval ip_${host}="`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $1 }' | awk '{ print $1 }'`" + eval ip_${host}="`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $1 }' | awk '{ print $1 }'`" + case $host in moon) - eval ip1_${host}="`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $2 }' | awk '{ print $1 }'`" + eval ip1_${host}="`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $2 }' | awk '{ print $1 }'`" searchandreplace PH_IP_MOON $ip_moon $TESTSDIR searchandreplace PH_IP1_MOON $ip1_moon $TESTSDIR ;; sun) - eval ip1_${host}="`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $2 }' | awk '{ print $1 }'`" + eval ip1_${host}="`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $2 }' | awk '{ print $1 }'`" searchandreplace PH_IP_SUN $ip_sun $TESTSDIR searchandreplace PH_IP1_SUN $ip1_sun $TESTSDIR ;; @@ -90,12 +91,12 @@ do searchandreplace PH_IP_BOB $ip_bob $TESTSDIR ;; carol) - eval ip1_${host}="`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $2 }' | awk '{ print $1 }'`" + eval ip1_${host}="`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $2 }' | awk '{ print $1 }'`" searchandreplace PH_IP_CAROL $ip_carol $TESTSDIR searchandreplace PH_IP1_CAROL $ip1_carol $TESTSDIR ;; dave) - eval ip1_${host}="`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $2 }' | awk '{ print $1 }'`" + eval ip1_${host}="`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $2 }' | awk '{ print $1 }'`" searchandreplace PH_IP_DAVE $ip_dave $TESTSDIR searchandreplace PH_IP1_DAVE $ip1_dave $TESTSDIR ;; @@ -105,7 +106,6 @@ do esac done - ############################################################################## # create header for the results html file # diff --git a/testing/hosts/alice/etc/conf.d/net b/testing/hosts/alice/etc/conf.d/net index 3070a46b1..02494db97 100644 --- a/testing/hosts/alice/etc/conf.d/net +++ b/testing/hosts/alice/etc/conf.d/net @@ -2,10 +2,9 @@ # This is basically the ifconfig argument without the ifconfig $iface # -iface_lo="127.0.0.1 netmask 255.0.0.0" -iface_eth0="PH_IP_ALICE broadcast 10.1.255.255 netmask 255.255.0.0" +config_eth0=( "PH_IP_ALICE broadcast 10.1.255.255 netmask 255.255.0.0" + "PH_IP6_ALICE/16" ) # For setting the default gateway # -gateway="eth0/PH_IP1_MOON" - +routes_eth0=( "default via PH_IP_MOON1" ) diff --git a/testing/hosts/alice/etc/init.d/net.eth0 b/testing/hosts/alice/etc/init.d/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/alice/etc/init.d/net.eth0 +++ b/testing/hosts/alice/etc/init.d/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/alice/etc/ipsec.conf b/testing/hosts/alice/etc/ipsec.conf index d6cdbba7b..4e525d929 100755 --- a/testing/hosts/alice/etc/ipsec.conf +++ b/testing/hosts/alice/etc/ipsec.conf @@ -1,7 +1,5 @@ # /etc/ipsec.conf - strongSwan IPsec configuration file -version 2.0 # conforms to second version of ipsec.conf specification - config setup plutodebug=control crlcheckinterval=180 diff --git a/testing/hosts/alice/etc/runlevels/default/net.eth0 b/testing/hosts/alice/etc/runlevels/default/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/alice/etc/runlevels/default/net.eth0 +++ b/testing/hosts/alice/etc/runlevels/default/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/bob/etc/conf.d/net b/testing/hosts/bob/etc/conf.d/net index 09133acad..bd0b3a5ce 100644 --- a/testing/hosts/bob/etc/conf.d/net +++ b/testing/hosts/bob/etc/conf.d/net @@ -2,9 +2,9 @@ # This is basically the ifconfig argument without the ifconfig $iface # -iface_lo="127.0.0.1 netmask 255.0.0.0" -iface_eth0="PH_IP_BOB broadcast 10.2.255.255 netmask 255.255.0.0" +config_eth0=( "PH_IP_BOB broadcast 10.2.255.255 netmask 255.255.0.0" + "PH_IP6_BOB/16" ) # For setting the default gateway # -gateway="eth0/PH_IP1_SUN" +routes_eth0=( "default via PH_IP_SUN1" ) diff --git a/testing/hosts/bob/etc/init.d/net.eth0 b/testing/hosts/bob/etc/init.d/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/bob/etc/init.d/net.eth0 +++ b/testing/hosts/bob/etc/init.d/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/bob/etc/ipsec.conf b/testing/hosts/bob/etc/ipsec.conf index cdef4e042..9040fc25d 100755 --- a/testing/hosts/bob/etc/ipsec.conf +++ b/testing/hosts/bob/etc/ipsec.conf @@ -1,7 +1,5 @@ # /etc/ipsec.conf - strongSwan IPsec configuration file -version 2.0 # conforms to second version of ipsec.conf specification - config setup plutodebug=control crlcheckinterval=180 diff --git a/testing/hosts/bob/etc/runlevels/default/net.eth0 b/testing/hosts/bob/etc/runlevels/default/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/bob/etc/runlevels/default/net.eth0 +++ b/testing/hosts/bob/etc/runlevels/default/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/carol/etc/conf.d/net b/testing/hosts/carol/etc/conf.d/net index 39470ad14..f7f685942 100644 --- a/testing/hosts/carol/etc/conf.d/net +++ b/testing/hosts/carol/etc/conf.d/net @@ -2,9 +2,9 @@ # This is basically the ifconfig argument without the ifconfig $iface # -iface_lo="127.0.0.1 netmask 255.0.0.0" -iface_eth0="PH_IP_CAROL broadcast 192.168.0.255 netmask 255.255.255.0" +config_eth0=( "PH_IP_CAROL broadcast 192.168.0.255 netmask 255.255.255.0" + "PH_IP6_CAROL/16" ) # For setting the default gateway # -gateway="eth0/192.168.0.254" +routes_eth0=( "default via 192.168.0.254" ) diff --git a/testing/hosts/carol/etc/init.d/net.eth0 b/testing/hosts/carol/etc/init.d/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/carol/etc/init.d/net.eth0 +++ b/testing/hosts/carol/etc/init.d/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/carol/etc/ipsec.conf b/testing/hosts/carol/etc/ipsec.conf index 3228f4e16..43deae00f 100755 --- a/testing/hosts/carol/etc/ipsec.conf +++ b/testing/hosts/carol/etc/ipsec.conf @@ -1,7 +1,5 @@ # /etc/ipsec.conf - strongSwan IPsec configuration file -version 2.0 # conforms to second version of ipsec.conf specification - config setup plutodebug=control crlcheckinterval=180 diff --git a/testing/hosts/carol/etc/ipsec.d/private/carolKey.pem b/testing/hosts/carol/etc/ipsec.d/private/carolKey.pem index 0522355ce..5a41744f6 100644 --- a/testing/hosts/carol/etc/ipsec.d/private/carolKey.pem +++ b/testing/hosts/carol/etc/ipsec.d/private/carolKey.pem @@ -1,27 +1,30 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAuBuEkgQI4IbI0njTrS6f/AG4noxCO2ErkIAQ+BdP+W9nKehL -GF+5bmB4MILFB6zp1k95vrAlLgXl8feomgsz5nifXetmUITLIwGRwWW8rRo0Vj4B -GzSbtqtRfwHs9+L03pYdNiA7hel4EcsmtlDP0BTRXdLStx79ZW5WOKJL9wmGuBKL -uuXztCjWNg4D0/ToFlAuPR0U1xZasakqn+Fe8EXU5I/1vXmOyAyUIJYsmpeYtUoO -0qAM8sllHX2YguGBwe9rHEPtytov0ZHhCZYtvSbzigAgjBrD7SelkkxgMwx5h461 -x6kJYKZHL5eaypxa7iu00K7TlbVGxeNhkQoGNwIDAQABAoIBAQCnhwq8H4XAYYWN -17quJPYZR6uqQfDmvYX5yD8osXXpgNC8Fo92z2wZnxje86+8S0DA7bLXrMs4NM/H -vVcjTTxd5LcHrHN+o0eBRCVQeXYVgfnL3EH/coCa2Qugaa0q589wV+Ke5Pek5AyJ -DHXegmyHaNoW6Qcq8L0dtigpAq3jTLG5w/3QCo8DMDKOGNR3AJrFpDlS/gW3JXuL -Tn+PUojoWO9W6joDGYDTi4eeYyfZSajzwZvzecEpez3vwKN0pupvHA6BJCR8Mzkq -5EYIH0hvWLtBy8uiWRXTfu/ggoQI9/Z5hBWIQk71m23uMIBbkm+oDn/1fLSBcWfK -cr9RyM+RAoGBANpWewy7xCbkRV/90bgBNkTZ9HeFsFsWOgFVyB1XwM2E/nOqdRJc -rxFt5Qt63DaXB+2REn231EIrsIz/Xd+R9KDl+yZOCY/m/mL4oquTPurEGJPzZdgW -X3kUOFW1pbfcMcmzSp1FPufI17JPiePtUb/q3C4RAjCKlnskHftEyK1pAoGBANfd -eEN8UzoV/R3WsGNDNOecMdIVAX9aiGnkLLraP7CRZ1heCH5y+RV1RB98yppkJG31 -fw5F8a6GoomkMHWGqhzDzQacZQV8w7C6rDY0Bk5TF5vemvJTGlrydwodfMvcJj8Y -KZrS7A0iS3GAAmM6VGr3THyscszfJTq0NwE3v4KfAoGAY7L1wVzENxYpb6nRZ/p1 -s37rGODdJNrDZfSrympVygMexeZiSx4zevv5iQJzKCJTJnIGRY35yLV2iwvY68wU -LpyV0Gn2B9Xs93idn0c/hahBqN2N9dxRgFJxXwHxSEGuInJScfo6vVCC3hNf3cpy -d/Zg0FBH9a5zBIv7fM9t63ECgYAosrSt5I68cNDcA1IWJOGgmS47cYJqxGLbtA1K -3UMMwx08592qGXsktIs3dIuuOBs2MAbYZg9+3Btg3/fS8KS576CEEpBpTHCIrWky -fvSBZ+EXngyQi2J4qyYOXijdNpBvbNrLOeEPSNv4di39D05DLITbLJgoUBnwy3Fj -ZWNR+QKBgEKn19f5QWs/O1DPWBXfvCSc01cuSUx20a6Z3B6Lxj+7MuXBjVxPkGge -kEaZnNzwgm+QQ1C51nIn9gY4LZx7OxMy0idEss76aRq4Lb7I6XakBrCQLQ9IiTkv -gNOeJYGsQv7tkIWWRlBIXjSBGwT6HzTEfN5cvdHSDzARGFGjwYfK +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,1E1991A43D0778B7 + +MAsd1YBlHz54KjvBvhpwDBewinBkxBo/NmdsMetLIcV8Ag87YcKtTXYju+fbW21y +DI12iPDQeS9tk17tS8qE5ubWmx/8n0fa5VCdLZ06JK6eeASXNoomXZh5rGsd42It +sj0irWAnbIA3nFFWQl+Uz5pGZMse7aDSNyk1zs3xtywFIaditYIBsRhrTVmJ/bCK +waVr++S2pwUHJ/phKoZQ8pwgF5KtYOZxdNtYIzfOZNMoplESR3+WYBYSuW8BKuOc +QAign/BL2JVJLD4OpHQ68D8Su2sbh6ZYA5jslZLDgG9O7eiMbkCE+N8DmKO6wNAr +zB5ILb4u5dIyTqun32tOENEhpZqDdMQtZZ34fRBze4IoMx9LrEOAHdZAQyyERP80 +iJCnH8BNf6FerA+XeDs4LVd1yrCklXKFINatqSRP/tNY3kruKw2Q7cAi2AFf+Rv6 +1lrvwK4MiLSHFtzcgEJuxm2bxeceIwXLJ2AVlfLBJvK/yJlq0MPedFbl6E6UwKfw +cMLokF3sa1XrfwpJ93enGLqdpJrkR3dTzrsshjIhjQqfc8lqLwRlbMGc9u+V0ZsK +OJ8e26wc/4l5D7CQ1vmgT/R/tuydBtUskgH96anhNJj1M95odkoh4Zicmm5iLgy2 +kluVYiEk0Fs7hc5Qtv8ZLN7ZoBRvZfJZWhXHDXmh71g1aoVYacIkFwiTMX4NoDy5 +QVq9tFUZ1TW4VrNIzfq++rLoz4XlgVy0Yz8jNWKuB0KRuHPNSsQUY2NHkDX+wOjq +MP1SfNDxqPoqrmCqbgMw/9DmeOj9gyiTyjZhPZTxFOp67FYEYzYtR6bLQKEhdgf6 +iOVROZyrFHMZdBiUgV8GECds1th6ZYWmNRGdvxYjSjExIYgkDrcWbowTqD0bFC9b +zClaSqrxR6GHUzbUVOBuCP+RmUx4j6gPvMRLUcIn5RmpbGtPE0ixeB5sFB0IuRRW +6u2YToCiuq3EG1iJRmxjnBa/zj1aBO6OlsE/aPc0Sx+Jhm+MUbDioxUAriX96bJ+ +DEB4zgDhC0vIvkkUVAzQMkWPX479nPDmiZLpMqUIfqUh75WDpHbCladyGMgSkEo0 +IKq96oAWHJC8WLH0UMxMNuf8Ut+TsSpIO6G0RPl/cx3+hQqSUC5oUB7R3ZAWYx+6 +mawjkNJEx72yeJmQtGiZYEfeMt0Svm10PypMXFu0+2JjiS2eRj2K1yqrUnuL6AnY +GYYmTmR74dnVAd35bRYJjY1XHGC9MyqBn4jLqKZm1BKO3sFsctGDy6vybnvAgPD7 +LioGQHPiOZmQe9Q5mMLedE9NAUCzlR8BHRbWtlnajQWcC0JcVu/mBQsjOt/KHh/V +CY4aFXE56lRH2OpqZQxFpBFOSFDcuVX+zcEBGmKfk65n2MFL4McAJUhVRZL561Zx +r9BvILv1Ld6/hECbodq0sUqvbDYHzv25zxAVKSIk1xy85mP5aNbk8xuGHmm860wg +YOqdePwBEcDHoio+ov/uFYB7+4gt40vV90EzSiyfdq8x9RFMViJU430IkIBcvByo +tFFcbN8ucBozxtl4AX495GVSRI7V0XXBtEdOIwJIzPBylZOHxCuTnA== -----END RSA PRIVATE KEY----- diff --git a/testing/hosts/carol/etc/ipsec.secrets b/testing/hosts/carol/etc/ipsec.secrets index 797f18a01..6a2aea811 100644 --- a/testing/hosts/carol/etc/ipsec.secrets +++ b/testing/hosts/carol/etc/ipsec.secrets @@ -1,7 +1,3 @@ # /etc/ipsec.secrets - strongSwan IPsec secrets file -: RSA carolKey.pem - - - - +: RSA carolKey.pem "nH5ZQEWtku0RJEZ6" diff --git a/testing/hosts/carol/etc/runlevels/default/net.eth0 b/testing/hosts/carol/etc/runlevels/default/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/carol/etc/runlevels/default/net.eth0 +++ b/testing/hosts/carol/etc/runlevels/default/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/dave/etc/conf.d/net b/testing/hosts/dave/etc/conf.d/net index db3753fb0..2b902525a 100644 --- a/testing/hosts/dave/etc/conf.d/net +++ b/testing/hosts/dave/etc/conf.d/net @@ -2,9 +2,9 @@ # This is basically the ifconfig argument without the ifconfig $iface # -iface_lo="127.0.0.1 netmask 255.0.0.0" -iface_eth0="PH_IP_DAVE broadcast 192.168.0.255 netmask 255.255.255.0" +config_eth0=( "PH_IP_DAVE broadcast 192.168.0.255 netmask 255.255.255.0" + "PH_IP6_DAVE/16" ) # For setting the default gateway # -gateway="eth0/192.168.0.254" +routes_eth0=( "default via 192.168.0.254" ) diff --git a/testing/hosts/dave/etc/init.d/net.eth0 b/testing/hosts/dave/etc/init.d/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/dave/etc/init.d/net.eth0 +++ b/testing/hosts/dave/etc/init.d/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/dave/etc/ipsec.conf b/testing/hosts/dave/etc/ipsec.conf index 76623491c..5fc5eef46 100755 --- a/testing/hosts/dave/etc/ipsec.conf +++ b/testing/hosts/dave/etc/ipsec.conf @@ -1,7 +1,5 @@ # /etc/ipsec.conf - strongSwan IPsec configuration file -version 2.0 # conforms to second version of ipsec.conf specification - config setup plutodebug=control crlcheckinterval=180 diff --git a/testing/hosts/dave/etc/runlevels/default/net.eth0 b/testing/hosts/dave/etc/runlevels/default/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/dave/etc/runlevels/default/net.eth0 +++ b/testing/hosts/dave/etc/runlevels/default/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/default/etc/hosts b/testing/hosts/default/etc/hosts index b8bc8da66..25c18ad5e 100644 --- a/testing/hosts/default/etc/hosts +++ b/testing/hosts/default/etc/hosts @@ -12,23 +12,56 @@ 10.1.0.254 uml1.strongswan.org uml1 10.2.0.254 uml1.strongswan.org uml2 -PH_IP_ALICE alice.strongswan.org alice -PH_IP_VENUS venus.strongswan.org venus -PH_IP1_MOON moon1.strongswan.org moon1 -PH_IP_MOON moon.strongswan.org moon -PH_IP_CAROL carol.strongswan.org carol -PH_IP1_CAROL carol1.strongswan.org carol1 -PH_IP_WINNETOU winnetou.strongswan.org winnetou crl.strongswan.org ocsp.strongswan.org ldap.strongswan.org -PH_IP_DAVE dave.strongswan.org dave -PH_IP1_DAVE dave1.strongswan.org dave1 -PH_IP_SUN sun.strongswan.org sun -PH_IP1_SUN sun1.strongswan.org sun1 -PH_IP_BOB bob.strongswan.org bob +10.1.0.10 alice.strongswan.org alice +10.1.0.20 venus.strongswan.org venus +10.1.0.1 moon1.strongswan.org moon1 +192.168.0.1 moon.strongswan.org moon +192.168.0.100 carol.strongswan.org carol +10.3.0.1 carol1.strongswan.org carol1 +192.168.0.150 winnetou.strongswan.org winnetou crl.strongswan.org ocsp.strongswan.org ldap.strongswan.org +192.168.0.200 dave.strongswan.org dave +10.3.0.2 dave1.strongswan.org dave1 +192.168.0.2 sun.strongswan.org sun +10.2.0.1 sun1.strongswan.org sun1 +10.2.0.10 bob.strongswan.org bob -# IPV6 versions of localhost and co +# IPv6 versions of localhost and co ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters ff02::3 ip6-allhosts + +# IPv6 solicited-node multicast addresses +ff02::1:ff00:1 ip6-mcast-1 +ff02::1:ff00:2 ip6-mcast-2 +ff02::1:ff00:10 ip6-mcast-10 +ff02::1:ff00:15 ip6-mcast-15 +ff02::1:ff00:20 ip6-mcast-20 + +# IPv6 site-local addresses +fec1::10 ip6-alice.strongswan.org ip6-alice +fec1::20 ip6-venus.strongswan.org ip6-venus +fec1::1 ip6-moon1.strongswan.org ip6-moon1 +fec0::1 ip6-moon.strongswan.org ip6-moon +fec0::10 ip6-carol.strongswan.org ip6-carol +fec3::1 ip6-carol1.strongswan.org ip6-carol1 +fec0::15 ip6-winnetou.strongswan.org ip6-winnetou +fec0::20 ip6-dave.strongswan.org ip6-dave +fec3::2 ip6-dave1.strongswan.org ip6-dave1 +fec0::2 ip6-sun.strongswan.org ip6-sun +fec2::1 ip6-sun1.strongswan.org ip6-sun1 +fec2::10 ip6-bob.strongswan.org ip6-bob + +# IPv6 link-local HW derived addresses +fe80::fcfd:0aff:fe01:14 ip6-hw-venus.strongswan.org ip6-hw-venus +fe80::fcfd:0aff:fe01:0a ip6-hw-alice.strongswan.org ip6-hw-alice +fe80::fcfd:0aff:fe01:01 ip6-hw-moon1.strongswan.org ip6-hw-moon1 +fe80::fcfd:c0ff:fea8:01 ip6-hw-moon.strongswan.org ip6-hw-moon +fe80::fcfd:c0ff:fea8:64 ip6-hw-carol.strongswan.org ip6-hw-carol +fe80::fcfd:c0ff:fea8:96 ip6-hw-winnetou.strongswan.org ip6-hw-winnetou +fe80::fcfd:c0ff:fea8:c8 ip6-hw-dave.strongswan.org ip6-hw-dave +fe80::fcfd:c0ff:fea8:02 ip6-hw-sun.strongswan.org ip6-hw-sun +fe80::fcfd:0aff:fe02:01 ip6-hw-sun1.strongswan.org ip6-hw-sun1 +fe80::fcfd:0aff:fe02:0a ip6-hw-bob.strongswan.org ip6-hw-bob diff --git a/testing/hosts/moon/etc/conf.d/net b/testing/hosts/moon/etc/conf.d/net index 7dec60ba5..7f09fd8a5 100644 --- a/testing/hosts/moon/etc/conf.d/net +++ b/testing/hosts/moon/etc/conf.d/net @@ -2,10 +2,11 @@ # This is basically the ifconfig argument without the ifconfig $iface # -iface_lo="127.0.0.1 netmask 255.0.0.0" -iface_eth0="PH_IP_MOON broadcast 192.168.0.255 netmask 255.255.255.0" -iface_eth1="PH_IP1_MOON broadcast 10.1.255.255 netmask 255.255.0.0" +config_eth0=( "PH_IP_MOON broadcast 192.168.0.255 netmask 255.255.255.0" + "PH_IP6_MOON/16" ) +config_eth1=( "PH_IP_MOON1 broadcast 10.1.255.255 netmask 255.255.0.0" + "PH_IP6_MOON1/16" ) # For setting the default gateway # -gateway="eth0/192.168.0.254" +routes_eth0=( "default via 192.168.0.254" ) diff --git a/testing/hosts/moon/etc/init.d/net.eth0 b/testing/hosts/moon/etc/init.d/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/moon/etc/init.d/net.eth0 +++ b/testing/hosts/moon/etc/init.d/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/moon/etc/init.d/net.eth1 b/testing/hosts/moon/etc/init.d/net.eth1 index fa1200242..92b3851cf 100755 --- a/testing/hosts/moon/etc/init.d/net.eth1 +++ b/testing/hosts/moon/etc/init.d/net.eth1 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/moon/etc/ipsec.conf b/testing/hosts/moon/etc/ipsec.conf index a0e97e057..c7d7dc2ed 100755 --- a/testing/hosts/moon/etc/ipsec.conf +++ b/testing/hosts/moon/etc/ipsec.conf @@ -1,7 +1,5 @@ # /etc/ipsec.conf - strongSwan IPsec configuration file -version 2.0 # conforms to second version of ipsec.conf specification - config setup plutodebug=control crlcheckinterval=180 @@ -12,7 +10,7 @@ conn %default keylife=20m rekeymargin=3m keyingtries=1 - left=192.168.0.1 + left=PH_IP_MOON leftnexthop=%direct leftcert=moonCert.pem leftid=@moon.strongswan.org @@ -20,13 +18,13 @@ conn %default conn net-net leftsubnet=10.1.0.0/16 - right=192.168.0.2 + right=PH_IP_SUN rightsubnet=10.2.0.0/16 rightid=@sun.strongswan.org auto=add conn host-host - right=192.168.0.2 + right=PH_IP_SUN rightid=@sun.strongswan.org auto=add diff --git a/testing/hosts/moon/etc/runlevels/default/net.eth0 b/testing/hosts/moon/etc/runlevels/default/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/moon/etc/runlevels/default/net.eth0 +++ b/testing/hosts/moon/etc/runlevels/default/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/moon/etc/runlevels/default/net.eth1 b/testing/hosts/moon/etc/runlevels/default/net.eth1 index fa1200242..92b3851cf 100755 --- a/testing/hosts/moon/etc/runlevels/default/net.eth1 +++ b/testing/hosts/moon/etc/runlevels/default/net.eth1 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/sun/etc/conf.d/net b/testing/hosts/sun/etc/conf.d/net index 0f8dc57b1..4a6370ab7 100644 --- a/testing/hosts/sun/etc/conf.d/net +++ b/testing/hosts/sun/etc/conf.d/net @@ -2,12 +2,13 @@ # This is basically the ifconfig argument without the ifconfig $iface # -iface_lo="127.0.0.1 netmask 255.0.0.0" -iface_eth0="PH_IP_SUN broadcast 192.168.0.255 netmask 255.255.255.0" -iface_eth1="PH_IP1_SUN broadcast 10.2.255.255 netmask 255.255.0.0" +config_eth0=( "PH_IP_SUN broadcast 192.168.0.255 netmask 255.255.255.0" + "PH_IP6_SUN/16" ) +config_eth1=( "PH_IP_SUN1 broadcast 10.2.255.255 netmask 255.255.0.0" + "PH_IP6_SUN1/16" ) # For setting the default gateway # -gateway="eth0/192.168.0.254" +routes_eth0=( "default via 192.168.0.254" ) diff --git a/testing/hosts/sun/etc/init.d/net.eth0 b/testing/hosts/sun/etc/init.d/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/sun/etc/init.d/net.eth0 +++ b/testing/hosts/sun/etc/init.d/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/sun/etc/init.d/net.eth1 b/testing/hosts/sun/etc/init.d/net.eth1 index fa1200242..92b3851cf 100755 --- a/testing/hosts/sun/etc/init.d/net.eth1 +++ b/testing/hosts/sun/etc/init.d/net.eth1 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/sun/etc/ipsec.conf b/testing/hosts/sun/etc/ipsec.conf index 4d0299a08..1106ded6f 100755 --- a/testing/hosts/sun/etc/ipsec.conf +++ b/testing/hosts/sun/etc/ipsec.conf @@ -1,7 +1,5 @@ # /etc/ipsec.conf - strongSwan IPsec configuration file -version 2.0 # conforms to second version of ipsec.conf specification - config setup plutodebug=control crlcheckinterval=180 diff --git a/testing/hosts/sun/etc/runlevels/default/net.eth0 b/testing/hosts/sun/etc/runlevels/default/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/sun/etc/runlevels/default/net.eth0 +++ b/testing/hosts/sun/etc/runlevels/default/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/sun/etc/runlevels/default/net.eth1 b/testing/hosts/sun/etc/runlevels/default/net.eth1 index fa1200242..92b3851cf 100755 --- a/testing/hosts/sun/etc/runlevels/default/net.eth1 +++ b/testing/hosts/sun/etc/runlevels/default/net.eth1 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/venus/etc/conf.d/net b/testing/hosts/venus/etc/conf.d/net index 2c55c2c20..43ec97807 100644 --- a/testing/hosts/venus/etc/conf.d/net +++ b/testing/hosts/venus/etc/conf.d/net @@ -2,10 +2,9 @@ # This is basically the ifconfig argument without the ifconfig $iface # -iface_lo="127.0.0.1 netmask 255.0.0.0" -iface_eth0="PH_IP_VENUS broadcast 10.1.255.255 netmask 255.255.0.0" +config_eth0=( "PH_IP_VENUS broadcast 10.1.255.255 netmask 255.255.0.0" + "PH_IP6_VENUS/16" ) # For setting the default gateway # -gateway="eth0/PH_IP1_MOON" - +routes_eth0=( "default via PH_IP_MOON1" ) diff --git a/testing/hosts/venus/etc/init.d/net.eth0 b/testing/hosts/venus/etc/init.d/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/venus/etc/init.d/net.eth0 +++ b/testing/hosts/venus/etc/init.d/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/venus/etc/ipsec.conf b/testing/hosts/venus/etc/ipsec.conf index 35f264f82..8e4e47459 100755 --- a/testing/hosts/venus/etc/ipsec.conf +++ b/testing/hosts/venus/etc/ipsec.conf @@ -1,7 +1,5 @@ # /etc/ipsec.conf - strongSwan IPsec configuration file -version 2.0 # conforms to second version of ipsec.conf specification - config setup plutodebug=control crlcheckinterval=180 diff --git a/testing/hosts/venus/etc/runlevels/default/net.eth0 b/testing/hosts/venus/etc/runlevels/default/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/venus/etc/runlevels/default/net.eth0 +++ b/testing/hosts/venus/etc/runlevels/default/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/winnetou/etc/conf.d/apache2 b/testing/hosts/winnetou/etc/conf.d/apache2 index cfb80a7d9..0c96fe77f 100644 --- a/testing/hosts/winnetou/etc/conf.d/apache2 +++ b/testing/hosts/winnetou/etc/conf.d/apache2 @@ -1,6 +1,6 @@ # Copyright 1999-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/strongswan/testing/hosts/winnetou/etc/conf.d/apache2,v 1.2 2006/01/06 12:21:21 as Exp $ +# $Header: /root/strongswan/testing/hosts/winnetou/etc/conf.d/apache2,v 1.2 2006/01/06 12:21:21 as Exp $ # Config file for /etc/init.d/apache2 diff --git a/testing/hosts/winnetou/etc/conf.d/net b/testing/hosts/winnetou/etc/conf.d/net index 1a32153f3..7fbc37014 100644 --- a/testing/hosts/winnetou/etc/conf.d/net +++ b/testing/hosts/winnetou/etc/conf.d/net @@ -2,9 +2,9 @@ # This is basically the ifconfig argument without the ifconfig $iface # -iface_lo="127.0.0.1 netmask 255.0.0.0" -iface_eth0="PH_IP_WINNETOU broadcast 192.168.0.255 netmask 255.255.255.0" +config_eth0=( "PH_IP_WINNETOU broadcast 192.168.0.255 netmask 255.255.255.0" + "PH_IP6_WINNETOU/16" ) # For setting the default gateway # -gateway="eth0/192.168.0.254" +routes_eth0=( "default via 192.168.0.254" ) diff --git a/testing/hosts/winnetou/etc/init.d/net.eth0 b/testing/hosts/winnetou/etc/init.d/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/winnetou/etc/init.d/net.eth0 +++ b/testing/hosts/winnetou/etc/init.d/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/hosts/winnetou/etc/init.d/slapd b/testing/hosts/winnetou/etc/init.d/slapd index d4c070b33..6e3130e90 100755 --- a/testing/hosts/winnetou/etc/init.d/slapd +++ b/testing/hosts/winnetou/etc/init.d/slapd @@ -1,7 +1,7 @@ #!/sbin/runscript # Copyright 1999-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/strongswan/testing/hosts/winnetou/etc/init.d/slapd,v 1.2 2005/05/31 14:04:43 as Exp $ +# $Header: /root/strongswan/testing/hosts/winnetou/etc/init.d/slapd,v 1.2 2005/05/31 14:04:43 as Exp $ depend() { need net diff --git a/testing/hosts/winnetou/etc/openldap/slapd.conf b/testing/hosts/winnetou/etc/openldap/slapd.conf index 4558ee2e2..5a99f955d 100644 --- a/testing/hosts/winnetou/etc/openldap/slapd.conf +++ b/testing/hosts/winnetou/etc/openldap/slapd.conf @@ -53,9 +53,9 @@ argsfile /var/run/openldap/slapd.args ####################################################################### database bdb -checkpoint 32 30 # <kbyte> <min> suffix "o=Linux strongSwan,c=CH" rootdn "cn=Manager,o=Linux strongSwan,c=CH" +checkpoint 32 30 # <kbyte> <min> # Cleartext passwords, especially for the rootdn, should # be avoid. See slappasswd(8) and slapd.conf(5) for details. # Use of strong authentication encouraged. diff --git a/testing/hosts/winnetou/etc/openssl/index.txt b/testing/hosts/winnetou/etc/openssl/index.txt index 4db6c2924..9e744674d 100644 --- a/testing/hosts/winnetou/etc/openssl/index.txt +++ b/testing/hosts/winnetou/etc/openssl/index.txt @@ -13,3 +13,6 @@ R 140321062536Z 050621195214Z 0C unknown /C=CH/O=Linux strongSwan/OU=Research/CN V 140321062916Z 0D unknown /C=CH/O=Linux strongSwan/OU=Sales/CN=Sales CA V 100607191714Z 0E unknown /C=CH/O=Linux strongSwan/CN=winnetou.strongswan.org V 100620195806Z 0F unknown /C=CH/O=Linux strongSwan/OU=Research/CN=Research CA +V 111007105811Z 10 unknown /C=CH/O=Linux strongSwan/OU=SHA-256/CN=moon.strongswan.org +V 111007121250Z 11 unknown /C=CH/O=Linux strongSwan/OU=SHA-384/CN=carol@strongswan.org +V 111007122112Z 12 unknown /C=CH/O=Linux strongSwan/OU=SHA-512/CN=dave@strongswan.org diff --git a/testing/hosts/winnetou/etc/openssl/index.txt.attr b/testing/hosts/winnetou/etc/openssl/index.txt.attr index 8f7e63a34..3a7e39e6e 100644 --- a/testing/hosts/winnetou/etc/openssl/index.txt.attr +++ b/testing/hosts/winnetou/etc/openssl/index.txt.attr @@ -1 +1 @@ -unique_subject = yes +unique_subject = no diff --git a/testing/hosts/winnetou/etc/openssl/index.txt.attr.old b/testing/hosts/winnetou/etc/openssl/index.txt.attr.old index 8f7e63a34..3a7e39e6e 100644 --- a/testing/hosts/winnetou/etc/openssl/index.txt.attr.old +++ b/testing/hosts/winnetou/etc/openssl/index.txt.attr.old @@ -1 +1 @@ -unique_subject = yes +unique_subject = no diff --git a/testing/hosts/winnetou/etc/openssl/index.txt.old b/testing/hosts/winnetou/etc/openssl/index.txt.old index 669702b0c..4d7201a35 100644 --- a/testing/hosts/winnetou/etc/openssl/index.txt.old +++ b/testing/hosts/winnetou/etc/openssl/index.txt.old @@ -12,3 +12,6 @@ V 100216084430Z 0B unknown /C=CH/O=Linux strongSwan/OU=Authorization Authority/ R 140321062536Z 050621195214Z 0C unknown /C=CH/O=Linux strongSwan/OU=Research/CN=Research CA V 140321062916Z 0D unknown /C=CH/O=Linux strongSwan/OU=Sales/CN=Sales CA V 100607191714Z 0E unknown /C=CH/O=Linux strongSwan/CN=winnetou.strongswan.org +V 100620195806Z 0F unknown /C=CH/O=Linux strongSwan/OU=Research/CN=Research CA +V 111007105811Z 10 unknown /C=CH/O=Linux strongSwan/OU=SHA-256/CN=moon.strongswan.org +V 111007121250Z 11 unknown /C=CH/O=Linux strongSwan/OU=SHA-384/CN=carol@strongswan.org diff --git a/testing/hosts/winnetou/etc/openssl/newcerts/10.pem b/testing/hosts/winnetou/etc/openssl/newcerts/10.pem new file mode 100644 index 000000000..307f4953e --- /dev/null +++ b/testing/hosts/winnetou/etc/openssl/newcerts/10.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEHzCCAwegAwIBAgIBEDANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJDSDEZ +MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS +b290IENBMB4XDTA2MTAwODEwNTgxMVoXDTExMTAwNzEwNTgxMVowWDELMAkGA1UE +BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xEDAOBgNVBAsTB1NIQS0y +NTYxHDAaBgNVBAMTE21vb24uc3Ryb25nc3dhbi5vcmcwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDzXHm8D8sY1lmX7o1KK0jt/M+UzAI2Ifpx7nAqoviH +XQIPe56BOAm4zHhEIlojEMFd1nncplXvDDGjuV/2F0KK1bFxbNtom88Ix1jrRWtk +FLopYwj3ERC2970OhNO3nuPLrnEAzj6k3XPGMTA3drGnpRf162f7mHAdmYIRXtWm +mfaecs4wGFs8BFGdeDfo6SPhQXZSBwZqjzQxvk1PA7E1qifgR5IGNZkNQRQ9IZD0 +86xzjmZgg5DaJcQKw45elpiVKQN6OkdWTngR3uUBfseWNeRGP5UxCUbDnPijWUbA +6ZAdEfFXLgSpSoXHLNttvGg+SWm0kgKTpHYWYhvpflKNAgMBAAGjggEFMIIBATAJ +BgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNVHQ4EFgQU0gL3aEo/H8c/Ld/GkBTb +W9Ma+nUwbQYDVR0jBGYwZIAUXafdcAZRMn7ntm2zteXgYOouTe+hSaRHMEUxCzAJ +BgNVBAYTAkNIMRkwFwYDVQQKExBMaW51eCBzdHJvbmdTd2FuMRswGQYDVQQDExJz +dHJvbmdTd2FuIFJvb3QgQ0GCAQAwHgYDVR0RBBcwFYITbW9vbi5zdHJvbmdzd2Fu +Lm9yZzA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vY3JsLnN0cm9uZ3N3YW4ub3Jn +L3N0cm9uZ3N3YW4uY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQCItzRn3TNWUzczBd8z +MtdPEsRl5Oi4fV3UecQxhjxAmJDLsEZT5I4uNa1XoLkJm6jVdSL7k+bjzjmpNJ1H +uL49cqia2yTdGP4IU0K8dTGaflg3ccaLLGGXTWU/NtgdI1o6yuZTwb6a9ZL7wWZT +x21BAsvyPTzCpUS1yCK4bFeYOxOYDphUGcwb0JTuRxx2/710b+p64BYiCfVkQJxT +eF1ZtjSW6nJgzMRg5n2zNpdrdXMMCPI6Nl7V6wxbs3Cphmz5qx3lijwi7nZt+jE5 +qK5gphph1MkKIhnA7MF66KEcx5Rknao68yLBBDIA/AISZ3bCIj8R1SGgl/tMYfep +sbRF +-----END CERTIFICATE----- diff --git a/testing/hosts/winnetou/etc/openssl/newcerts/11.pem b/testing/hosts/winnetou/etc/openssl/newcerts/11.pem new file mode 100644 index 000000000..d4b532323 --- /dev/null +++ b/testing/hosts/winnetou/etc/openssl/newcerts/11.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEITCCAwmgAwIBAgIBETANBgkqhkiG9w0BAQwFADBFMQswCQYDVQQGEwJDSDEZ +MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS +b290IENBMB4XDTA2MTAwODEyMTI1MFoXDTExMTAwNzEyMTI1MFowWTELMAkGA1UE +BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xEDAOBgNVBAsTB1NIQS0z +ODQxHTAbBgNVBAMUFGNhcm9sQHN0cm9uZ3N3YW4ub3JnMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAtCwjB6Yni4jSTbPJ4GX0kM06nr2tDBdU0PH6dZra +IXNaNiBthBNPNDeCYAQDG/ouwuywAJ6L2Lt0GYEhJSwfXMm87fYSG8qRP+C/nlKz +3fCfsuZ8yOAo5NAp2kgvbFVdB5cMeOtid21UqUvDxkncjFRDgpERtrjSthalUFYu +ObIcSMPdlcDho73jzq6zVK5XDJ4l1LHUQLbS4SzyrphCYKekTIoDy3YwRUys6Pdm +4QlFBIXuBwOYHjclvVu0HQVNSM4nWAJd+204KUm/+8neO0kn1Yakv9yoa47o3KGP +3XjtmcgY9SqBbuF+8yDcZQ7+5zUBjc0J+d8txdPoIjLi7wIDAQABo4IBBjCCAQIw +CQYDVR0TBAIwADALBgNVHQ8EBAMCA6gwHQYDVR0OBBYEFIUlEfDm3V0eDmRrpIvj +4FiPpGlpMG0GA1UdIwRmMGSAFF2n3XAGUTJ+57Zts7Xl4GDqLk3voUmkRzBFMQsw +CQYDVQQGEwJDSDEZMBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMS +c3Ryb25nU3dhbiBSb290IENBggEAMB8GA1UdEQQYMBaBFGNhcm9sQHN0cm9uZ3N3 +YW4ub3JnMDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwuc3Ryb25nc3dhbi5v +cmcvc3Ryb25nc3dhbi5jcmwwDQYJKoZIhvcNAQEMBQADggEBAL5ZmFmy8lW4Vdwq +hWB6qTtLLa1wwCvTXwbV9V+F8dK39AvHj6CHFqTiFhAbGIq/Ryt9cg2XGy1TDjVj +hQEua7mjp8XH2j2NLY2SiFTMjchbHmMylFk2FrHy2ZnmlRCiH83TAw+EnUWsQKj+ +gL+7Of9SpiaaIblrl+aCiBVktRuXcFSaxjYWTVXOeTCwnxQdF2SNtUKDoCuVPk1J +XCrs86mj575xL/FGjyN4SVbjTEZ4lm1emxrf/RblZOhCKp7mUic8KyP0kf7o6X8E +MXXjq9fDQVrSDG/q62uhZu7CyInnBpWnoUKiMImSxRn/cs0r7RUspC5DtJyhE33Y +DW2BzIc= +-----END CERTIFICATE----- diff --git a/testing/hosts/winnetou/etc/openssl/newcerts/12.pem b/testing/hosts/winnetou/etc/openssl/newcerts/12.pem new file mode 100644 index 000000000..73088cd1d --- /dev/null +++ b/testing/hosts/winnetou/etc/openssl/newcerts/12.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEHzCCAwegAwIBAgIBEjANBgkqhkiG9w0BAQ0FADBFMQswCQYDVQQGEwJDSDEZ +MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS +b290IENBMB4XDTA2MTAwODEyMjExMloXDTExMTAwNzEyMjExMlowWDELMAkGA1UE +BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xEDAOBgNVBAsTB1NIQS01 +MTIxHDAaBgNVBAMUE2RhdmVAc3Ryb25nc3dhbi5vcmcwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDL4+PsltDM0QCCS08tkefhll5Q0nb2VEdRZotBIdt6 +XEY1kmDlw0yQOp0XUznnIhcrxXpKeWpLqJdbo56jSxMaUB3Mod1u+aKvVhCgkOT8 +uQa7gIdcNMuXnfnch7yYYS6YxVfzdr/qXBxmVYNbR9sXy48vAD6glZLEVjDITHJO +a6tEVSrAOMyeuA9XTYJiGw5loj63YbUr6Ikp6W9SncPCtfX6G2Amk38MTuITu93W +Pd/bGB06ra6gmMQGAhXuGs14n3QZfQz9PWTp9TPsQNqQZdEjQyNdfeAKtPuz5jnO +cnZuhvVR0q4sxWuy64vkyZ57luTZAXyxdInBeBOp7sC3AgMBAAGjggEFMIIBATAJ +BgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNVHQ4EFgQU0wvMMeoe59mocM/RiYnD +iw9NUm0wbQYDVR0jBGYwZIAUXafdcAZRMn7ntm2zteXgYOouTe+hSaRHMEUxCzAJ +BgNVBAYTAkNIMRkwFwYDVQQKExBMaW51eCBzdHJvbmdTd2FuMRswGQYDVQQDExJz +dHJvbmdTd2FuIFJvb3QgQ0GCAQAwHgYDVR0RBBcwFYETZGF2ZUBzdHJvbmdzd2Fu +Lm9yZzA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vY3JsLnN0cm9uZ3N3YW4ub3Jn +L3N0cm9uZ3N3YW4uY3JsMA0GCSqGSIb3DQEBDQUAA4IBAQC/uKe2O9elbSFgpKP5 +7ZjJrCkYu493iH/PDm5G4D76q6WkRvZDqTgGDSIrXrt1xRLIsVJES+HERxfED0DB +yXNe22p1jR8iZdCesZxmEsKYyLh9XmeixKCfnLvStWCVs0+vqwhJlIkyEAveZ4HR +Yq121khdmCDDUugpjEl/nU7CLvCRVgFrlhDm1QLs2rYqxwQrJ2SH4/1W0YRdkY2R +vKZ2ngjLBNjBfXWNXSOpEAG367nVam5lFAepUC0wZTshyCUXt1NzClTnxWABm6M6 +x2Qwg4D6Qt5iXSjR8+DGVh+LaBL/alQi1YYcjkxufdFHnko294c0HsZcTZ3KRghk +ue1F +-----END CERTIFICATE----- diff --git a/testing/hosts/winnetou/etc/openssl/serial b/testing/hosts/winnetou/etc/openssl/serial index f599e28b8..b1bd38b62 100644 --- a/testing/hosts/winnetou/etc/openssl/serial +++ b/testing/hosts/winnetou/etc/openssl/serial @@ -1 +1 @@ -10 +13 diff --git a/testing/hosts/winnetou/etc/openssl/serial.old b/testing/hosts/winnetou/etc/openssl/serial.old index 0ced2f35e..48082f72f 100644 --- a/testing/hosts/winnetou/etc/openssl/serial.old +++ b/testing/hosts/winnetou/etc/openssl/serial.old @@ -1 +1 @@ -0F +12 diff --git a/testing/hosts/winnetou/etc/runlevels/default/net.eth0 b/testing/hosts/winnetou/etc/runlevels/default/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/winnetou/etc/runlevels/default/net.eth0 +++ b/testing/hosts/winnetou/etc/runlevels/default/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia -} + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 + + return 0 +} + +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" +} + +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] +} + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" + + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" + return 0 fi + + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route + + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) + + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod= func= x= i= + local -a ivars=() ovars1=() ovars2=() + local ifvar=$(bash_variable "${iface}") + + for mod in ${MODULES[@]}; do + is_function ${mod}_variables || continue + for v in $(${mod}_variables) ; do + x= + [[ -n ${option2} ]] && x="${v}_${option2}[@]" + [[ -z ${!x} ]] && x="${v}_${option1}[@]" + [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )" done + done + + return 0 +} +# bool module_load_minimum(char *module) +# +# Does the minimum checking on a module - even when forcing +module_load_minimum() { + local f="$1.sh" MODULE="${1##*/}" + + if [[ ! -f ${f} ]] ; then + eerror "${f} does not exist" + return 1 fi - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) + if ! source "${f}" ; then + eerror "${MODULE} failed a sanity check" + return 1 fi + + for f in depend; do + is_function "${MODULE}_${f}" && continue + eerror "${MODULE}.sh does not support the required function ${f}" + return 1 + done + + return 0 } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" +# bool modules_load_auto() +# +# Load and check each module for sanity +# If the module is not installed, the functions are to be removed +modules_load_auto() { + local i j inst + + # Populate the MODULES array + # Basically we treat evey file in ${MODULES_DIR} as a module + MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) ) + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES_DIR}/${MODULES[i]}" + [[ ! -f ${MODULES[i]} ]] && unset MODULES[i] + done + MODULES=( "${MODULES[@]}" ) + + # Each of these sources into the global namespace, so it's + # important that module functions and variables are prefixed with + # the module name, for example iproute2_ + + j="${#MODULES[@]}" + loaded_interface=false + for (( i=0; i<j; i++ )); do + MODULES[i]="${MODULES[i]%.sh*}" + if [[ ${MODULES[i]##*/} == "interface" ]] ; then + eerror "interface is a reserved name - cannot load a module called interface" + return 1 fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" + + ( + u=0; + module_load_minimum "${MODULES[i]}" || u=1; + if [[ ${u} == 0 ]] ; then + inst="${MODULES[i]##*/}_check_installed"; + if is_function "${inst}" ; then + ${inst} false || u=1; + fi + fi + exit "${u}"; + ) + + if [[ $? == 0 ]] ; then + source "${MODULES[i]}.sh" + MODULES[i]="${MODULES[i]##*/}" else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" + unset MODULES[i] + fi + done + + MODULES=( "${MODULES[@]}" ) + return 0 +} + +# bool modules_check_installed(void) +# +# Ensure that all modules have the required modules loaded +# This enables us to remove modules from the MODULES array +# Whilst other modules can still explicitly call them +# One example of this is essidnet which configures network +# settings for the specific ESSID connected to as the user +# may be using a daemon to configure wireless instead of our +# iwconfig module +modules_check_installed() { + local i j missingdeps nmods="${#MODULES[@]}" + + for (( i=0; i<nmods; i++ )); do + is_function "${MODULES[i]}_instlled" || continue + for j in $( ${MODULES[i]}_instlled ); do + missingdeps=true + if is_function "${j}_check_installed" ; then + ${j}_check_installed && missingdeps=false + elif is_function "${j}_depend" ; then + missingdeps=false + fi + ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) +} + +# bool modules_check_user(void) +modules_check_user() { + local iface="$1" ifvar=$(bash_variable "${IFACE}") + local i= j= k= l= nmods="${#MODULES[@]}" + local -a umods=() + + # Has the interface got any specific modules? + umods="modules_${ifvar}[@]" + umods=( "${!umods}" ) + + # Global setting follows interface-specific setting + umods=( "${umods[@]}" "${modules[@]}" ) + + # Add our preferred modules + local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" ) + umods=( "${umods[@]}" "${pmods[@]}" ) + + # First we strip any modules that conflict from user settings + # So if the user specifies pump then we don't use dhcpcd + for (( i=0; i<${#umods[@]}; i++ )); do + # Some users will inevitably put "dhcp" in their modules + # list. To keep users from screwing up their system this + # way, ignore this setting so that the default dhcp + # module will be used. + [[ ${umods[i]} == "dhcp" ]] && continue + + # We remove any modules we explicitly don't want + if [[ ${umods[i]} == "!"* ]] ; then + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${umods[i]:1} == "${MODULES[j]}" \ + || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then + # We may need to setup a class wrapper for it even though + # we don't use it directly + # However, we put it into an array and wrap later as + # another module may provide the same thing + ${MODULES[j]}_check_installed \ + && WRAP_MODULES=( + "${WRAP_MODULES[@]}" + "${MODULES[j]} ${PROVIDES[j]}" + ) + unset MODULES[j] + unset PROVIDES[j] fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? + done + continue + fi + + if ! is_function "${umods[i]}_depend" ; then + # If the module is one of our preferred modules, then + # ignore this error; whatever is available will be + # used instead. + (( i < ${#umods[@]} - ${#pmods[@]} )) || continue + + # The function may not exist because the modules software is + # not installed. Load the module and report its error + if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then + source "${MODULES_DIR}/${umods[i]}.sh" + is_function "${umods[i]}_check_installed" \ + && ${umods[i]}_check_installed true else - return $retval + eerror "The module \"${umods[i]}\" does not exist" fi + return 1 fi - fi - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? + if is_function "${umods[i]}_provide" ; then + mod=$(${umods[i]}_provide) + else + mod="${umods[i]}" + fi + for (( j=0; j<nmods; j++ )); do + [[ -z ${MODULES[j]} ]] && continue + if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then + # We don't have a match - now ensure that we still provide an + # alternative. This is to handle our preferred modules. + for (( l=0; l<nmods; l++ )); do + [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue + if [[ ${PROVIDES[l]} == "${mod}" ]] ; then + unset MODULES[j] + unset PROVIDES[j] + break + fi + done + fi + done + done + + # Then we strip conflicting modules. + # We only need to do this for 3rd party modules that conflict with + # our own modules and the preferred list AND the user modules + # list doesn't specify a preference. + for (( i=0; i<nmods-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( j=i+1; j<nmods; j++)); do + [[ -z ${MODULES[j]} ]] && continue + [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \ + && unset MODULES[j] && unset PROVIDES[j] + done + done + + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + return 0 +} + +# void modules_sort(void) +# +# Sort our modules +modules_sort() { + local i= j= nmods=${#MODULES[@]} m= + local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=() + + # Make our provide list + for ((i=0; i<nmods; i++)); do + dead[i]="false" + if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then + local provided=false + for ((j=0; j<${#provide[@]}; j++)); do + if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then + provide_list[j]="${provide_list[j]} ${MODULES[i]}" + provided=true + fi + done + if ! ${provided}; then + provide[j]="${PROVIDES[i]}" + provide_list[j]="${MODULES[i]}" + fi + fi + done + + # Create an after array, which holds which modules the module at + # index i must be after + for ((i=0; i<nmods; i++)); do + if is_function "${MODULES[i]}_after" ; then + after[i]=" ${after[i]} $(${MODULES[i]}_after) " + fi + if is_function "${MODULES[i]}_before" ; then + for m in $(${MODULES[i]}_before); do + for ((j=0; j<nmods; j++)) ; do + if [[ ${PROVIDES[j]} == "${m}" ]] ; then + after[j]=" ${after[j]} ${MODULES[i]} " + break + fi + done + done + fi + done + + # Replace the after list modules with real modules + for ((i=0; i<nmods; i++)); do + if [[ -n ${after[i]} ]] ; then + for ((j=0; j<${#provide[@]}; j++)); do + after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }" + done + fi + done + + # We then use the below code to provide a topologial sort + module_after_visit() { + local name="$1" i= x= + + for ((i=0; i<nmods; i++)); do + [[ ${MODULES[i]} == "$1" ]] && break done + + ${dead[i]} && return + dead[i]="true" + + for x in ${after[i]} ; do + module_after_visit "${x}" + done + + sorted=( "${sorted[@]}" "${MODULES[i]}" ) + sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" ) + } + + for x in ${MODULES[@]}; do + module_after_visit "${x}" + done + + MODULES=( "${sorted[@]}" ) + PROVIDES=( "${sortedp[@]}" ) +} + +# bool modules_check_depends(bool showprovides) +modules_check_depends() { + local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod= + local missingdeps= p= interface=false + + for (( i=0; i<nmods; i++ )); do + if is_function "${MODULES[i]}_need" ; then + for needmod in $(${MODULES[i]}_need); do + missingdeps=true + for (( j=0; j<nmods; j++ )); do + if [[ ${needmod} == "${MODULES[j]}" \ + || ${needmod} == "${PROVIDES[j]}" ]] ; then + missingdeps=false + break + fi + done + if ${missingdeps} ; then + eerror "${MODULES[i]} needs ${needmod} (dependency failure)" + return 1 + fi + done + fi + + if is_function "${MODULES[i]}_functions" ; then + for f in $(${MODULES[i]}_functions); do + if ! is_function "${f}" ; then + eerror "${MODULES[i]}: missing required function \"${f}\"" + return 1 + fi + done + fi + + [[ ${PROVIDES[i]} == "interface" ]] && interface=true + + if ${showprovides} ; then + [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \ + && veinfo "${MODULES[i]} provides ${PROVIDES[i]}" + fi + done + + if ! ${interface} ; then + eerror "no interface module has been loaded" + return 1 fi - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? + return 0 +} + +# bool modules_load(char *iface, bool starting) +# +# Loads the defined handler and modules for the interface +# Returns 0 on success, otherwise 1 +modules_load() { + local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k= + local -a x=() + local RC_INDENTATION="${RC_INDENTATION}" + local -a PROVIDES=() WRAP_MODULES=() + + if ! is_loopback "${iface}" ; then + x="modules_force_${iface}[@]" + [[ -n ${!x} ]] && modules_force=( "${!x}" ) + if [[ -n ${modules_force} ]] ; then + ewarn "WARNING: You are forcing modules!" + ewarn "Do not complain or file bugs if things start breaking" + report=true + fi + fi + + veinfo "Loading networking modules for ${iface}" + eindent + + if [[ -z ${modules_force} ]] ; then + modules_load_auto || return 1 + else + j="${#modules_force[@]}" + for (( i=0; i<j; i++ )); do + module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1 + if is_function "${modules_force[i]}_check_installed" ; then + ${modules_force[i]}_check_installed || unset modules_force[i] + fi done + MODULES=( "${modules_force[@]}" ) fi - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + # Now load our dependencies - we need to use the MODULE variable + # here as the after/before/need functions use it + MODULE="${MODULES[i]}" + ${MODULE}_depend + + # expose does exactly the same thing as depend + # However it is more "correct" as it exposes things to other modules + # instead of depending on them ;) + is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose + + # If no provide is given, assume module name + if is_function "${MODULES[i]}_provide" ; then + PROVIDES[i]=$(${MODULES[i]}_provide) + else + PROVIDES[i]="${MODULES[i]}" + fi + done + + if [[ -n ${modules_force[@]} ]] ; then + # Strip any duplicate modules providing the same thing + j="${#MODULES[@]}" + for (( i=0; i<j-1; i++ )); do + [[ -z ${MODULES[i]} ]] && continue + for (( k=i+1; k<j; k++ )); do + if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then + unset MODULES[k] + unset PROVIDES[k] + fi + done done + MODULES=( "${MODULES[@]}" ) + PROVIDES=( "${PROVIDES[@]}" ) + else + if ${starting}; then + modules_check_user "${iface}" || return 1 + else + # Always prefer iproute2 for taking down interfaces + if is_function iproute2_provide ; then + function_wrap iproute2 "$(iproute2_provide)" + fi + fi fi + + # Wrap our modules + j="${#MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap "${MODULES[i]}" "${PROVIDES[i]}" + done + j="${#WRAP_MODULES[@]}" + for (( i=0; i<j; i++ )); do + function_wrap ${WRAP_MODULES[i]} + done + + if [[ -z ${modules_force[@]} ]] ; then + modules_check_installed || return 1 + modules_sort || return 1 + fi + + veinfo "modules: ${MODULES[@]}" + eindent + + ${starting} && p=true + modules_check_depends "${p}" || return 1 + return 0 +} + +# bool iface_start(char *interface) +# +# iface_start is called from start. It's expected to start the base +# interface (for example "eth0"), aliases (for example "eth0:1") and to start +# VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by +# calling itself recursively. +iface_start() { + local iface="$1" mod config_counter="-1" x config_worked=false + local RC_INDENTATION="${RC_INDENTATION}" + local -a config=() fallback=() fallback_route=() conf=() a=() b=() + local ifvar=$(bash_variable "$1") i= j= metric=0 - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } + # pre Start any modules with + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_start" ; then + ${mod}_pre_start "${iface}" || { eend 1; return 1; } fi + done + + x="metric_${ifvar}" + # If we don't have a metric then calculate one + # Our modules will set the metric variable to a suitable base + # in their pre starts. + if [[ -z ${!x} ]] ; then + eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\"" fi - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter + # We now expand the configuration parameters and pray that the + # fallbacks expand to the same number as config or there will be + # trouble! + a="config_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + config=( "${config[@]}" "${b[@]}" ) + done + + a="fallback_${ifvar}[@]" + a=( "${!a}" ) + for (( i=0; i<${#a[@]}; i++ )); do + eval b=( $(expand_parameters "${a[i]}") ) + fallback=( "${fallback[@]}" "${b[@]}" ) + done + + # We don't expand routes + fallback_route="fallback_route_${ifvar}[@]" + fallback_route=( "${!fallback_route}" ) + + # We must support old configs + if [[ -z ${config} ]] ; then + interface_get_old_config "${iface}" || return 1 + if [[ -n ${config} ]] ; then + ewarn "You are using a deprecated configuration syntax for ${iface}" + ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly" + fi + fi + + # Handle "noop" correctly + if [[ ${config[0]} == "noop" ]] ; then + if interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + return 0 + fi + + # Remove noop from the config var + config=( "${config[@]:1}" ) + fi + + # Provide a default of DHCP if no configuration is set and we're auto + # Otherwise a default of NULL + if [[ -z ${config} ]] ; then + ewarn "Configuration not set for ${iface} - assuming DHCP" + if is_function "dhcp_start" ; then + config=( "dhcp" ) + else + eerror "No DHCP client installed" + return 1 + fi fi + + einfo "Bringing up ${iface}" + eindent + for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do + # Handle null and noop correctly + if [[ ${config[config_counter]} == "null" \ + || ${config[config_counter]} == "noop" ]] ; then + eend 0 + config_worked=true + continue + fi + + # We convert it to an array - this has the added + # bonus of trimming spaces! + conf=( ${config[config_counter]} ) + einfo "${conf[0]}" + + # Do we have a function for our config? + if is_function "${conf[0]}_start" ; then + eindent + ${conf[0]}_start "${iface}" ; x=$? + eoutdent + [[ ${x} == 0 ]] && config_worked=true && continue + # We need to test to see if it's an IP address or a function + # We do this by testing if the 1st character is a digit + elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then + x="0" + if ! is_loopback "${iface}" ; then + if [[ " ${MODULES[@]} " == *" arping "* ]] ; then + if arping_address_exists "${iface}" "${conf[0]}" ; then + eerror "${conf[0]%%/*} already taken on ${iface}" + x="1" + fi + fi + fi + [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?" + eend "${x}" && config_worked=true && continue + else + if [[ ${conf[0]} == "dhcp" ]] ; then + eerror "No DHCP client installed" + else + eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)" + fi + fi + + if [[ -n ${fallback[config_counter]} ]] ; then + einfo "Trying fallback configuration" + config[config_counter]="${fallback[config_counter]}" + fallback[config_counter]="" + + # Do we have a fallback route? + if [[ -n ${fallback_route[config_counter]} ]] ; then + x="fallback_route[config_counter]" + eval "routes_${ifvar}=( \"\${!x}\" )" + fallback_route[config_counter]="" + fi + + (( config_counter-- )) # since the loop will increment it + continue + fi + done + eoutdent + + # We return failure if no configuration parameters worked + ${config_worked} || return 1 + + # Start any modules with _post_start + for mod in ${MODULES[@]}; do + if is_function "${mod}_post_start" ; then + ${mod}_post_start "${iface}" || return 1 + fi + done + + return 0 } +# bool iface_stop(char *interface) +# # iface_stop: bring down an interface. Don't trust information in # /etc/conf.d/net since the configuration might have changed since # iface_start ran. Instead query for current configuration and bring # down the interface. iface_stop() { - local IFACE=${1} i x aliases inet6 count - - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 - return 0 - fi + local iface="$1" i= aliases= need_begin=false mod= + local RC_INDENTATION="${RC_INDENTATION}" - einfo "Bringing ${IFACE} down" + # pre Stop any modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_pre_stop" ; then + ${mod}_pre_stop "${iface}" || return 1 + fi + done + + einfo "Bringing down ${iface}" + eindent + + # Collect list of aliases for this interface. + # List will be in reverse order. + if interface_exists "${iface}" ; then + aliases=$(interface_get_aliases_rev "${iface}") + fi # Stop aliases before primary interface. # Note this must be done in reverse order, since ifconfig eth0:1 # will remove eth0:2, etc. It might be sufficient to simply remove # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do - - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done + for i in ${aliases} ${iface}; do + # Stop all our modules + for mod in ${MODULES[@]}; do + if is_function "${mod}_stop" ; then + ${mod}_stop "${i}" || return 1 + fi + done + + # A module may have removed the interface + if ! interface_exists "${iface}" ; then + eend 0 + continue fi - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" + # We don't delete ppp assigned addresses + if ! is_function pppd_exists || ! pppd_exists "${i}" ; then + # Delete all the addresses for this alias + interface_del_addresses "${i}" fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 + + # Do final shut down of this alias + if [[ ${IN_BACKGROUND} != "true" \ + && ${RC_DOWN_INTERFACE} == "yes" ]] ; then + ebegin "Shutting down ${i}" + interface_iface_stop "${i}" + eend "$?" + fi + done + + # post Stop any modules + for mod in ${MODULES[@]}; do + # We have already taken down the interface, so no need to error + is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}" done return 0 } -start() { - # These variables are set by setup_vars - local status_IFACE vlans_IFACE dhcpcd_IFACE - local -a ifconfig_IFACE routes_IFACE inet6_IFACE +# bool run_start(char *iface) +# +# Brings up ${IFACE}. Calls preup, iface_start, then postup. +# Returns 0 (success) unless preup or iface_start returns 1 (failure). +# Ignores the return value from postup. +# We cannot check that the device exists ourselves as modules like +# tuntap make create it. +run_start() { + local iface="$1" IFVAR=$(bash_variable "$1") + + # We do this so users can specify additional addresses for lo if they + # need too - additional routes too + # However, no extra modules are loaded as they are just not needed + if [[ ${iface} == "lo" ]] ; then + metric_lo="0" + config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" ) + elif [[ ${iface} == "lo0" ]] ; then + metric_lo0="0" + config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" ) + routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" ) + fi + + # We may not have a loaded module for ${iface} + # Some users may have "alias natsemi eth0" in /etc/modules.d/foo + # so we can work with this + # However, if they do the same with eth1 and try to start it + # but eth0 has not been loaded then the module gets loaded as + # eth0. + # Not much we can do about this :( + # Also, we cannot error here as some modules - such as bridge + # create interfaces + if ! interface_exists "${iface}" ; then + /sbin/modprobe "${iface}" &>/dev/null + fi # Call user-defined preup function if it exists - if [[ $(type -t preup) == function ]]; then + if is_function preup ; then einfo "Running preup function" - preup ${IFACE} || { - eerror "preup ${IFACE} failed" - return 1 - } + eindent + ( preup "${iface}" ) + eend "$?" "preup ${iface} failed" || return 1 + eoutdent fi - # Start the primary interface and aliases - setup_vars ${IFACE} - iface_start ${IFACE} || return 1 + # If config is set to noop and the interface is up with an address + # then we don't start it + local config= + config="config_${IFVAR}[@]" + config=( "${!config}" ) + if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then + einfo "Keeping current configuration for ${iface}" + eend 0 + else + # Remove noop from the config var + [[ ${config[0]} == "noop" ]] \ + && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )" - # Start vlans - local vlan - for vlan in ${vlans_IFACE}; do - /sbin/vconfig add ${IFACE} ${vlan} >${devnull} - setup_vars ${IFACE}.${vlan} - iface_start ${IFACE}.${vlan} - done + # There may be existing ip address info - so we strip it + if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \ + && ${IN_BACKGROUND} != "true" ]] ; then + interface_del_addresses "${iface}" + fi + + # Start the interface + if ! iface_start "${iface}" ; then + if [[ ${IN_BACKGROUND} != "true" ]] ; then + interface_exists "${iface}" && interface_down "${iface}" + fi + eend 1 + return 1 + fi + fi # Call user-defined postup function if it exists - if [[ $(type -t postup) == function ]]; then + if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postup function" - postup ${IFACE} + eindent + ( postup "${iface}" ) + eoutdent fi + + return 0 } -stop() { +# bool run_stop(char *iface) { +# +# Brings down ${iface}. If predown call returns non-zero, then +# stop returns non-zero to indicate failure bringing down device. +# In all other cases stop returns 0 to indicate success. +run_stop() { + local iface="$1" IFVAR=$(bash_variable "$1") x + + # Load our ESSID variable so users can use it in predown() instead + # of having to write code. + local ESSID=$(get_options ESSID) ESSIDVAR= + [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}") + # Call user-defined predown function if it exists - if [[ $(type -t predown) == function ]]; then + if is_function predown ; then einfo "Running predown function" - predown ${IFACE} + eindent + ( predown "${iface}" ) + eend $? "predown ${iface} failed" || return 1 + eoutdent + elif is_net_fs / ; then + eerror "root filesystem is network mounted -- can't stop ${iface}" + return 1 + elif is_union_fs / ; then + for x in $(unionctl "${dir}" --list \ + | sed -e 's/^\(.*\) .*/\1/') ; do + if is_net_fs "${x}" ; then + eerror "Part of the root filesystem is network mounted - cannot stop ${iface}" + return 1 + fi + done fi - # Don't depend on setup_vars since configuration might have changed. - # Investigate current configuration instead. - local vlan - for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do - iface_stop ${vlan} - /sbin/vconfig rem ${vlan} >${devnull} - done + iface_stop "${iface}" || return 1 # always succeeds, btw - iface_stop ${IFACE} || return 1 # always succeeds, btw + # Release resolv.conf information. + [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}" + + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" # Call user-defined postdown function if it exists - if [[ $(type -t postdown) == function ]]; then + if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" + end_service "net.${iface}" 0 einfo "Running postdown function" - postdown ${IFACE} + eindent + ( postdown "${iface}" ) + eoutdent + fi + + + return 0 +} + +# bool run(char *iface, char *cmd) +# +# Main start/stop entry point +# We load modules here and remove any functions that they +# added as we may be called inside the same shell scope for another interface +run() { + local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}" + local starting=true + local -a MODULES=() mods=() + local IN_BACKGROUND="${IN_BACKGROUND}" + + if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then + IN_BACKGROUND=true + else + IN_BACKGROUND=false + fi + + # We need to override the exit function as runscript.sh now checks + # for it. We need it so we can mark the service as inactive ourselves. + unset -f exit + + eindent + [[ ${cmd} == "stop" ]] && starting=false + + # We force lo to only use these modules for a major speed boost + if is_loopback "${iface}" ; then + modules_force=( "iproute2" "ifconfig" "system" ) + fi + + if modules_load "${iface}" "${starting}" ; then + if [[ ${cmd} == "stop" ]] ; then + # Reverse the module list for stopping + mods=( "${MODULES[@]}" ) + for ((i = 0; i < ${#mods[@]}; i++)); do + MODULES[i]=${mods[((${#mods[@]} - i - 1))]} + done + + run_stop "${iface}" && r=0 + else + # Only hotplug on ethernet interfaces + if [[ ${IN_HOTPLUG} == 1 ]] ; then + if ! interface_is_ethernet "${iface}" ; then + eerror "We only hotplug for ethernet interfaces" + return 1 + fi + fi + + run_start "${iface}" && r=0 + fi + fi + + if [[ ${r} != "0" ]] ; then + if [[ ${cmd} == "start" ]] ; then + # Call user-defined failup if it exists + if is_function failup ; then + einfo "Running failup function" + eindent + ( failup "${iface}" ) + eoutdent + fi + else + # Call user-defined faildown if it exists + if is_function faildown ; then + einfo "Running faildown function" + eindent + ( faildown "${iface}" ) + eoutdent + fi + fi + [[ ${IN_BACKGROUND} == "true" ]] \ + && mark_service_inactive "net.${iface}" fi + + return "${r}" +} + +# bool start(void) +# +# Start entry point so that we only have one function +# which localises variables and unsets functions +start() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Starting ${IFACE}" + run "${IFACE}" start +} + +# bool stop(void) +# +# Stop entry point so that we only have one function +# which localises variables and unsets functions +stop() { + declare -r IFACE="${SVCNAME#*.}" + einfo "Stopping ${IFACE}" + run "${IFACE}" stop } # vim:ts=4 diff --git a/testing/scripts/build-hostconfig b/testing/scripts/build-hostconfig index 0df8861c8..28b321a70 100755 --- a/testing/scripts/build-hostconfig +++ b/testing/scripts/build-hostconfig @@ -14,7 +14,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: build-hostconfig,v 1.3 2005/02/08 10:40:48 as Exp $ +# RCSID $Id: build-hostconfig,v 1.4 2006/10/19 21:38:45 as Exp $ DIR=`dirname $0` @@ -58,44 +58,61 @@ HOSTIP=`ifconfig eth0 |grep inet |sed -e "s/.*inet addr://" -e "s/ Bcast.*//"` for host in $STRONGSWANHOSTS do cecho-n "${host}.." - eval ip_${host}="`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $1 }' | awk '{ print $1 }'`" + eval ipv4_${host}="`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $1 }' | awk '{ print $1 }'`" + eval ipv6_${host}="`echo $HOSTNAMEIPV6 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $1 }' | awk '{ print $1 }'`" - [ "`eval echo \\\$ip_${host}`" != "$HOSTIP" ] || die "$host has the same IP as eth0 (Host)! Please change that." + [ "`eval echo \\\$ipv4_${host}`" != "$HOSTIP" ] || die "$host has the same IP as eth0 (Host)! Please change that." case $host in moon) - eval ip1_${host}="`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $2 }' | awk '{ print $1 }'`" - [ "`eval echo \\\$ip1_${host}`" != "$HOSTIP" ] || die "eth1 of $host has the same IP as eth0 (Host)! Please change that." - searchandreplace PH_IP_MOON $ip_moon $HOSTCONFIGDIR - searchandreplace PH_IP1_MOON $ip1_moon $HOSTCONFIGDIR + eval ipv4_moon1="`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $2 }' | awk '{ print $1 }'`" + [ "`eval echo \\\$ipv4_moon1`" != "$HOSTIP" ] || die "eth1 of $host has the same IP as eth0 (Host)! Please change that." + searchandreplace PH_IP_MOON1 $ipv4_moon1 $HOSTCONFIGDIR + searchandreplace PH_IP_MOON $ipv4_moon $HOSTCONFIGDIR + eval ipv6_moon1="`echo $HOSTNAMEIPV6 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $2 }' | awk '{ print $1 }'`" + searchandreplace PH_IP6_MOON1 $ipv6_moon1 $HOSTCONFIGDIR + searchandreplace PH_IP6_MOON $ipv6_moon $HOSTCONFIGDIR ;; sun) - eval ip1_${host}="`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $2 }' | awk '{ print $1 }'`" - [ "`eval echo \\\$ip1_${host}`" != "$HOSTIP" ] || die "eth1 of $host has the same IP as eth0 (Host)! Please change that." - searchandreplace PH_IP_SUN $ip_sun $HOSTCONFIGDIR - searchandreplace PH_IP1_SUN $ip1_sun $HOSTCONFIGDIR + eval ipv4_sun1="`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $2 }' | awk '{ print $1 }'`" + [ "`eval echo \\\$ipv4_sun1`" != "$HOSTIP" ] || die "eth1 of $host has the same IP as eth0 (Host)! Please change that." + searchandreplace PH_IP_SUN1 $ipv4_sun1 $HOSTCONFIGDIR + searchandreplace PH_IP_SUN $ipv4_sun $HOSTCONFIGDIR + eval ipv6_sun1="`echo $HOSTNAMEIPV6 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $2 }' | awk '{ print $1 }'`" + searchandreplace PH_IP6_SUN1 $ipv6_sun1 $HOSTCONFIGDIR + searchandreplace PH_IP6_SUN $ipv6_sun $HOSTCONFIGDIR ;; alice) - searchandreplace PH_IP_ALICE $ip_alice $HOSTCONFIGDIR + searchandreplace PH_IP_ALICE $ipv4_alice $HOSTCONFIGDIR + searchandreplace PH_IP6_ALICE $ipv6_alice $HOSTCONFIGDIR ;; venus) - searchandreplace PH_IP_VENUS $ip_venus $HOSTCONFIGDIR + searchandreplace PH_IP_VENUS $ipv4_venus $HOSTCONFIGDIR + searchandreplace PH_IP6_VENUS $ipv6_venus $HOSTCONFIGDIR ;; bob) - searchandreplace PH_IP_BOB $ip_bob $HOSTCONFIGDIR + searchandreplace PH_IP_BOB $ipv4_bob $HOSTCONFIGDIR + searchandreplace PH_IP6_BOB $ipv6_bob $HOSTCONFIGDIR ;; carol) - eval ip1_${host}="`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $2 }' | awk '{ print $1 }'`" - searchandreplace PH_IP_CAROL $ip_carol $HOSTCONFIGDIR - searchandreplace PH_IP1_CAROL $ip1_carol $HOSTCONFIGDIR + eval ipv4_carol1="`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $2 }' | awk '{ print $1 }'`" + searchandreplace PH_IP_CAROL1 $ipv4_carol1 $HOSTCONFIGDIR + searchandreplace PH_IP_CAROL $ipv4_carol $HOSTCONFIGDIR + eval ipv6_carol1="`echo $HOSTNAMEIPV6 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $2 }' | awk '{ print $1 }'`" + searchandreplace PH_IP6_CAROL1 $ipv6_carol1 $HOSTCONFIGDIR + searchandreplace PH_IP6_CAROL $ipv6_carol $HOSTCONFIGDIR ;; dave) - eval ip1_${host}="`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $2 }' | awk '{ print $1 }'`" - searchandreplace PH_IP_DAVE $ip_dave $HOSTCONFIGDIR - searchandreplace PH_IP1_DAVE $ip1_dave $HOSTCONFIGDIR + eval ipv4_dave1="`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $2 }' | awk '{ print $1 }'`" + searchandreplace PH_IP_DAVE1 $ipv4_dave1 $HOSTCONFIGDIR + searchandreplace PH_IP_DAVE $ipv4_dave $HOSTCONFIGDIR + eval ipv6_dave1="`echo $HOSTNAMEIPV6 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $2 }' | awk '{ print $1 }'`" + searchandreplace PH_IP6_DAVE1 $ipv6_dave1 $HOSTCONFIGDIR + searchandreplace PH_IP6_DAVE $ipv6_dave $HOSTCONFIGDIR ;; winnetou) - searchandreplace PH_IP_WINNETOU $ip_winnetou $HOSTCONFIGDIR + searchandreplace PH_IP_WINNETOU $ipv4_winnetou $HOSTCONFIGDIR + searchandreplace PH_IP6_WINNETOU $ipv6_winnetou $HOSTCONFIGDIR ;; esac done diff --git a/testing/scripts/build-sshkeys b/testing/scripts/build-sshkeys index f4d584d6b..2faa3963d 100755 --- a/testing/scripts/build-sshkeys +++ b/testing/scripts/build-sshkeys @@ -14,7 +14,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: build-sshkeys,v 1.2 2005/02/15 14:12:16 as Exp $ +# RCSID $Id: build-sshkeys,v 1.3 2006/10/19 21:38:45 as Exp $ DIR=`dirname $0` @@ -58,10 +58,10 @@ else cecho "done" fi -for host in $HOSTNAMEIPS +for host in $HOSTNAMEIPV4 do - HOSTNAME=`echo $host | awk -F : '{ print $1 }'` - IP=`echo $host | awk -F : '{ print $2 }'` + HOSTNAME=`echo $host | awk -F, '{ print $1 }'` + IP=`echo $host | awk -F, '{ print $2 }'` if [ `grep "$IP " ~/.ssh/known_hosts | wc -l` != "0" ] then cecho "!! Warning: An entry exists for the following IP address: $IP" diff --git a/testing/scripts/build-umlrootfs b/testing/scripts/build-umlrootfs index ba103838f..1d534c81b 100755 --- a/testing/scripts/build-umlrootfs +++ b/testing/scripts/build-umlrootfs @@ -14,7 +14,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: build-umlrootfs,v 1.11 2006/01/08 22:29:56 as Exp $ +# RCSID $Id: build-umlrootfs,v 1.12 2006/10/20 14:26:05 as Exp $ DIR=`dirname $0` @@ -91,6 +91,12 @@ cecho "done" ###################################################### +# remove /etc/resolv.conf +# +cecho " * Removing /etc/resolv.conf" +rm -f $LOOPDIR/etc/resolv.conf + +###################################################### # copying default /etc/hosts to the root filesystem # cecho " * Copying '$HOSTCONFIGDIR/default/etc/hosts' to the root filesystem" @@ -153,7 +159,7 @@ cp $LOOPDIR/etc/ssh/ssh_host_rsa_key $LOOPDIR/root/.ssh/id_rsa for host in $STRONGSWANHOSTS do - eval ip="`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $1 }' | awk '{ print $1 }'`" + eval ip="`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $1 }' | awk '{ print $1 }'`" echo "$host,$ip `cat $HOSTCONFIGDIR/ssh_host_rsa_key.pub`" >> $LOOPDIR/root/.ssh/known_hosts echo "`cat $HOSTCONFIGDIR/ssh_host_rsa_key.pub` root@$host" >> $LOOPDIR/root/.ssh/authorized_keys done diff --git a/testing/scripts/load-testconfig b/testing/scripts/load-testconfig index 89da17e72..9c0477e54 100755 --- a/testing/scripts/load-testconfig +++ b/testing/scripts/load-testconfig @@ -14,7 +14,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: load-testconfig,v 1.2 2004/12/13 21:02:42 as Exp $ +# RCSID $Id: load-testconfig,v 1.3 2006/10/19 21:38:45 as Exp $ DIR=`dirname $0` @@ -46,7 +46,7 @@ if [ -d $TESTSDIR/$testname/hosts ] then for host in `ls $TESTSDIR/$testname/hosts` do - eval HOSTLOGIN="root@`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $1 }' | awk '{ print $1 }'`" + eval HOSTLOGIN="root@`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $1 }' | awk '{ print $1 }'`" scp -rp $TESTSDIR/$testname/hosts/$host/etc $HOSTLOGIN:/ > /dev/null 2>&1 done fi @@ -58,7 +58,7 @@ fi for host in $IPSECHOSTS do - eval HOSTLOGIN="root@`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $1 }' | awk '{ print $1 }'`" + eval HOSTLOGIN="root@`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $1 }' | awk '{ print $1 }'`" ssh $HOSTLOGIN 'rm -f /var/log/auth.log; \ kill -SIGHUP `cat /var/run/syslogd.pid`' > /dev/null 2>&1 done diff --git a/testing/scripts/restore-defaults b/testing/scripts/restore-defaults index 129e46f56..03f723e82 100755 --- a/testing/scripts/restore-defaults +++ b/testing/scripts/restore-defaults @@ -14,7 +14,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: restore-defaults,v 1.2 2004/12/20 07:56:33 as Exp $ +# RCSID $Id: restore-defaults,v 1.3 2006/10/19 21:40:27 as Exp $ DIR=`dirname $0` @@ -47,7 +47,7 @@ if [ -d $TESTSDIR/${testname}/hosts ] then for host in `ls $TESTSDIR/${testname}/hosts` do - eval HOSTLOGIN="root@`echo $HOSTNAMEIPS | sed -n -e "s/^.*${host}://gp" | awk -F : '{ print $1 }' | awk '{ print $1 }'`" + eval HOSTLOGIN="root@`echo $HOSTNAMEIPV4 | sed -n -e "s/^.*${host},//gp" | awk -F, '{ print $1 }' | awk '{ print $1 }'`" scp -rp $HOSTCONFIGDIR/${host}/etc $HOSTLOGIN:/ > /dev/null 2>&1 done fi diff --git a/testing/testing.conf b/testing/testing.conf index 4f323d354..6a2db67fd 100755 --- a/testing/testing.conf +++ b/testing/testing.conf @@ -14,34 +14,34 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: testing.conf,v 1.56 2006/08/03 10:20:54 as Exp $ +# RCSID $Id: testing.conf,v 1.57 2006/10/19 21:38:44 as Exp $ # Root directory of testing UMLTESTDIR=~/strongswan-testing # Bzipped kernel sources # (file extension .tar.bz2 required) -KERNEL=$UMLTESTDIR/linux-2.6.17.7.tar.bz2 +KERNEL=$UMLTESTDIR/linux-2.6.18.1.tar.bz2 # Extract kernel version KERNELVERSION=`basename $KERNEL .tar.bz2 | sed -e 's/linux-//'` # Kernel configuration file -KERNELCONFIG=$UMLTESTDIR/.config-2.6.17 +KERNELCONFIG=$UMLTESTDIR/.config-2.6.18 # Bzipped uml patch for kernel # (not needed anymore for 2.6.9 kernel or higher) -UMLPATCH= +UMLPATCH=$UMLTESTDIR/uml_jmpbuf-2.6.18.patch.bz2 # Bzipped source of strongSwan -STRONGSWAN=$UMLTESTDIR/strongswan-2.7.3.tar.bz2 +STRONGSWAN=$UMLTESTDIR/strongswan-2.8.0.tar.bz2 # strongSwan compile options (use "yes" or "no") USE_LIBCURL="yes" USE_LDAP="yes" # Gentoo linux root filesystem -ROOTFS=$UMLTESTDIR/gentoo-fs-20060330.tar.bz2 +ROOTFS=$UMLTESTDIR/gentoo-fs-20061006.tar.bz2 # Size of the finished root filesystem in MB ROOTFSSIZE=544 @@ -98,20 +98,30 @@ SELECTEDTESTSONLY="no" SELECTEDTESTS="net2net-cert" ############################################################## -# hostname and according IP(s) -# You may change the IPs but keep them in the same net, +# hostname and corresponding IPv4 and IPv6 addresses +# You may change the IPs but keep them in the same subnet, # this means retain the netmasks! # Also don't use IPs ending with 254, they are reserved! # -HOSTNAMEIPS="\ -alice:10.1.0.10 \ -venus:10.1.0.20 \ -moon:192.168.0.1:10.1.0.1 \ -carol:192.168.0.100:10.3.0.1 \ -winnetou:192.168.0.150 \ -dave:192.168.0.200:10.3.0.2 \ -sun:192.168.0.2:10.2.0.1 \ -bob:10.2.0.10" +HOSTNAMEIPV4="\ +alice,10.1.0.10 \ +venus,10.1.0.20 \ +moon,192.168.0.1,10.1.0.1 \ +carol,192.168.0.100,10.3.0.1 \ +winnetou,192.168.0.150 \ +dave,192.168.0.200,10.3.0.2 \ +sun,192.168.0.2,10.2.0.1 \ +bob,10.2.0.10" + +HOSTNAMEIPV6="\ +alice,fec1::10 \ +venus,fec1::20 \ +moon,fec0::1,fec1::1 \ +carol,fec0::10,fec3::1 \ +winnetou,fec0::15 \ +dave,fec0::20,fec3::2 \ +sun,fec0::2,fec2::1 \ +bob,fec2::10" ############################################################## # VPN gateways / clients @@ -138,17 +148,13 @@ IFCONFIG_2="10.2.0.254 netmask 255.255.0.0" ############################################################## # Network interfaces of the UML instances # -SWITCH_alice="eth0=daemon,,unix,/tmp/umlswitch1" -SWITCH_venus="eth0=daemon,,unix,/tmp/umlswitch1" -SWITCH_moon="eth0=daemon,,unix,/tmp/umlswitch0 \ - eth1=daemon,,unix,/tmp/umlswitch1" -SWITCH_carol="eth0=daemon,,unix,/tmp/umlswitch0" -SWITCH_winnetou="eth0=daemon,,unix,/tmp/umlswitch0" -SWITCH_dave="eth0=daemon,,unix,/tmp/umlswitch0" -SWITCH_sun="eth0=daemon,,unix,/tmp/umlswitch0 \ - eth1=daemon,,unix,/tmp/umlswitch2" -SWITCH_bob="eth0=daemon,,unix,/tmp/umlswitch2" - - - - +SWITCH_alice="eth0=daemon,fe:fd:0a:01:00:0a,unix,/tmp/umlswitch1" +SWITCH_venus="eth0=daemon,fe:fd:0a:01:00:14,unix,/tmp/umlswitch1" +SWITCH_moon="eth0=daemon,fe:fd:c0:a8:00:01,unix,/tmp/umlswitch0 \ + eth1=daemon,fe:fd:0a:01:00:01,unix,/tmp/umlswitch1" +SWITCH_carol="eth0=daemon,fe:fd:c0:a8:00:64,unix,/tmp/umlswitch0" +SWITCH_winnetou="eth0=daemon,fe:fd:c0:a8:00:96,unix,/tmp/umlswitch0" +SWITCH_dave="eth0=daemon,fe:fd:c0:a8:00:c8,unix,/tmp/umlswitch0" +SWITCH_sun="eth0=daemon,fe:fd:c0:a8:00:02,unix,/tmp/umlswitch0 \ + eth1=daemon,fe:fd:0a:02:00:01,unix,/tmp/umlswitch2" +SWITCH_bob="eth0=daemon,fe:fd:0a:02:00:0a,unix,/tmp/umlswitch2" diff --git a/testing/tests/crl-ldap/pretest.dat b/testing/tests/crl-ldap/pretest.dat index 64fae2a16..0097e78f4 100644 --- a/testing/tests/crl-ldap/pretest.dat +++ b/testing/tests/crl-ldap/pretest.dat @@ -5,3 +5,4 @@ moon::ipsec start carol::ipsec start carol::sleep 2 carol::ipsec up home +carol::sleep 2 diff --git a/testing/tests/dpd-clear/evaltest.dat b/testing/tests/dpd-clear/evaltest.dat index 98d5b146b..da3567d3e 100644 --- a/testing/tests/dpd-clear/evaltest.dat +++ b/testing/tests/dpd-clear/evaltest.dat @@ -1,5 +1,6 @@ carol::ipsec status::STATE_MAIN_I4 (ISAKMP SA established)::YES carol::iptables -A INPUT -i eth0 -s PH_IP_MOON -j DROP::no output expected::NO +moon::ipsec statusall::DPD active::YES moon::sleep 50::no output expected::NO moon::cat /var/log/auth.log::inserting event EVENT_DPD::YES moon::cat /var/log/auth.log::DPD: No response from peer - declaring peer dead::YES diff --git a/testing/tests/mode-config-push/description.txt b/testing/tests/mode-config-push/description.txt new file mode 100644 index 000000000..387c3b409 --- /dev/null +++ b/testing/tests/mode-config-push/description.txt @@ -0,0 +1,10 @@ +The roadwarriors <b>carol</b> and <b>dave</b> set up a connection each to gateway <b>moon</b>. +Both <b>carol</b> and <b>dave</b> request a <b>virtual IP</b> via the IKE Mode Config protocol +by using the <b>leftsourceip=%modeconfig</b> parameter. By setting the option <b>modeconfig=push</b> +on both the roadwarriors and the gateway, the Mode Config server <b>moon</b> will actively push +the configuration down to <b>carol</b> and <b>dave</b>. +<p> +<b>leftfirewall=yes</b> automatically inserts iptables-based firewall rules that let pass the +tunneled traffic. In order to test the tunnels, <b>carol</b> and <b>dave</b> then ping the client +<b>alice</b> behind the gateway <b>moon</b>. The source IP addresses of the two pings will +be the virtual IPs <b>carol1</b> and <b>dave1</b>, respectively. diff --git a/testing/tests/mode-config-push/evaltest.dat b/testing/tests/mode-config-push/evaltest.dat new file mode 100644 index 000000000..7de32d681 --- /dev/null +++ b/testing/tests/mode-config-push/evaltest.dat @@ -0,0 +1,16 @@ +carol::cat /var/log/auth.log::setting virtual IP source address to 10.3.0.1::YES +carol::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::YES +carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES +dave::cat /var/log/auth.log::setting virtual IP source address to 10.3.0.2::YES +dave::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::YES +dave::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES +moon::ipsec status::rw-carol.*STATE_QUICK_R2.*IPsec SA established::YES +moon::ipsec status::rw-dave.*STATE_QUICK_R2.*IPsec SA established::YES +moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES +moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES +moon::tcpdump::IP dave.strongswan.org > moon.strongswan.org: ESP::YES +moon::tcpdump::IP moon.strongswan.org > dave.strongswan.org: ESP::YES +alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: ICMP echo request::YES +alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: ICMP echo reply::YES +alice::tcpdump::IP dave1.strongswan.org > alice.strongswan.org: ICMP echo request::YES +alice::tcpdump::IP alice.strongswan.org > dave1.strongswan.org: ICMP echo reply::YES diff --git a/testing/tests/mode-config-push/hosts/carol/etc/ipsec.conf b/testing/tests/mode-config-push/hosts/carol/etc/ipsec.conf new file mode 100755 index 000000000..d66c4d329 --- /dev/null +++ b/testing/tests/mode-config-push/hosts/carol/etc/ipsec.conf @@ -0,0 +1,31 @@ +# /etc/ipsec.conf - strongSwan IPsec configuration file + +version 2.0 # conforms to second version of ipsec.conf specification + +config setup + plutodebug=control + crlcheckinterval=180 + strictcrlpolicy=no + +conn %default + ikelifetime=60m + keylife=20m + rekeymargin=3m + keyingtries=1 + modeconfig=push + +conn home + left=PH_IP_CAROL + leftsourceip=%modeconfig + leftnexthop=%direct + leftcert=carolCert.pem + leftid=carol@strongswan.org + leftfirewall=yes + right=PH_IP_MOON + rightsubnet=10.1.0.0/16 + rightid=@moon.strongswan.org + auto=add + + + + diff --git a/testing/tests/mode-config-push/hosts/dave/etc/ipsec.conf b/testing/tests/mode-config-push/hosts/dave/etc/ipsec.conf new file mode 100755 index 000000000..bf2625148 --- /dev/null +++ b/testing/tests/mode-config-push/hosts/dave/etc/ipsec.conf @@ -0,0 +1,31 @@ +# /etc/ipsec.conf - strongSwan IPsec configuration file + +version 2.0 # conforms to second version of ipsec.conf specification + +config setup + plutodebug=control + crlcheckinterval=180 + strictcrlpolicy=no + +conn %default + ikelifetime=60m + keylife=20m + rekeymargin=3m + keyingtries=1 + modeconfig=push + +conn home + left=PH_IP_DAVE + leftsourceip=%modeconfig + leftnexthop=%direct + leftcert=daveCert.pem + leftid=dave@strongswan.org + leftfirewall=yes + right=PH_IP_MOON + rightsubnet=10.1.0.0/16 + rightid=@moon.strongswan.org + auto=add + + + + diff --git a/testing/tests/mode-config-push/hosts/moon/etc/ipsec.conf b/testing/tests/mode-config-push/hosts/moon/etc/ipsec.conf new file mode 100755 index 000000000..3416c5d68 --- /dev/null +++ b/testing/tests/mode-config-push/hosts/moon/etc/ipsec.conf @@ -0,0 +1,34 @@ +# /etc/ipsec.conf - strongSwan IPsec configuration file + +version 2.0 # conforms to second version of ipsec.conf specification + +config setup + plutodebug=control + crlcheckinterval=180 + strictcrlpolicy=no + +conn %default + ikelifetime=60m + keylife=20m + rekeymargin=3m + keyingtries=1 + modeconfig=push + left=PH_IP_MOON + leftsubnet=10.1.0.0/16 + leftsourceip=PH_IP1_MOON + leftnexthop=%direct + leftcert=moonCert.pem + leftid=@moon.strongswan.org + leftfirewall=yes + +conn rw-carol + right=%any + rightid=carol@strongswan.org + rightsourceip=PH_IP1_CAROL + auto=add + +conn rw-dave + right=%any + rightid=dave@strongswan.org + rightsourceip=PH_IP1_DAVE + auto=add diff --git a/testing/tests/mode-config-push/posttest.dat b/testing/tests/mode-config-push/posttest.dat new file mode 100644 index 000000000..932b319a7 --- /dev/null +++ b/testing/tests/mode-config-push/posttest.dat @@ -0,0 +1,11 @@ +moon::iptables -v -n -L +carol::iptables -v -n -L +dave::iptables -v -n -L +moon::ipsec stop +carol::ipsec stop +dave::ipsec stop +moon::/etc/init.d/iptables stop 2> /dev/null +carol::/etc/init.d/iptables stop 2> /dev/null +dave::/etc/init.d/iptables stop 2> /dev/null +carol::ip addr del PH_IP1_CAROL/32 dev eth0 +dave::ip addr del PH_IP1_DAVE/32 dev eth0 diff --git a/testing/tests/mode-config-push/pretest.dat b/testing/tests/mode-config-push/pretest.dat new file mode 100644 index 000000000..1e45f00fd --- /dev/null +++ b/testing/tests/mode-config-push/pretest.dat @@ -0,0 +1,9 @@ +moon::/etc/init.d/iptables start 2> /dev/null +carol::/etc/init.d/iptables start 2> /dev/null +dave::/etc/init.d/iptables start 2> /dev/null +carol::ipsec start +dave::ipsec start +moon::ipsec start +carol::sleep 2 +carol::ipsec up home +dave::ipsec up home diff --git a/testing/tests/mode-config-push/test.conf b/testing/tests/mode-config-push/test.conf new file mode 100644 index 000000000..1a8f2a4e0 --- /dev/null +++ b/testing/tests/mode-config-push/test.conf @@ -0,0 +1,21 @@ +#!/bin/bash +# +# This configuration file provides information on the +# UML instances used for this test + +# All UML instances that are required for this test +# +UMLHOSTS="alice moon carol winnetou dave" + +# Corresponding block diagram +# +DIAGRAM="a-m-c-w-d.png" + +# UML instances on which tcpdump is to be started +# +TCPDUMPHOSTS="moon alice" + +# UML instances on which IPsec is started +# Used for IPsec logging purposes +# +IPSECHOSTS="moon carol dave" diff --git a/testing/tests/mode-config-swapped/evaltest.dat b/testing/tests/mode-config-swapped/evaltest.dat index be8ca6ef5..7de32d681 100644 --- a/testing/tests/mode-config-swapped/evaltest.dat +++ b/testing/tests/mode-config-swapped/evaltest.dat @@ -10,7 +10,7 @@ moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES moon::tcpdump::IP dave.strongswan.org > moon.strongswan.org: ESP::YES moon::tcpdump::IP moon.strongswan.org > dave.strongswan.org: ESP::YES -alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: icmp::YES -alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: icmp::YES -alice::tcpdump::IP dave1.strongswan.org > alice.strongswan.org: icmp::YES -alice::tcpdump::IP alice.strongswan.org > dave1.strongswan.org: icmp::YES +alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: ICMP echo request::YES +alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: ICMP echo reply::YES +alice::tcpdump::IP dave1.strongswan.org > alice.strongswan.org: ICMP echo request::YES +alice::tcpdump::IP alice.strongswan.org > dave1.strongswan.org: ICMP echo reply::YES diff --git a/testing/tests/mode-config/evaltest.dat b/testing/tests/mode-config/evaltest.dat index be8ca6ef5..7de32d681 100644 --- a/testing/tests/mode-config/evaltest.dat +++ b/testing/tests/mode-config/evaltest.dat @@ -10,7 +10,7 @@ moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES moon::tcpdump::IP dave.strongswan.org > moon.strongswan.org: ESP::YES moon::tcpdump::IP moon.strongswan.org > dave.strongswan.org: ESP::YES -alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: icmp::YES -alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: icmp::YES -alice::tcpdump::IP dave1.strongswan.org > alice.strongswan.org: icmp::YES -alice::tcpdump::IP alice.strongswan.org > dave1.strongswan.org: icmp::YES +alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: ICMP echo request::YES +alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: ICMP echo reply::YES +alice::tcpdump::IP dave1.strongswan.org > alice.strongswan.org: ICMP echo request::YES +alice::tcpdump::IP alice.strongswan.org > dave1.strongswan.org: ICMP echo reply::YES diff --git a/testing/tests/multi-level-ca-ldap/hosts/carol/etc/ipsec.secrets b/testing/tests/multi-level-ca-ldap/hosts/carol/etc/ipsec.secrets new file mode 100644 index 000000000..fac55d63b --- /dev/null +++ b/testing/tests/multi-level-ca-ldap/hosts/carol/etc/ipsec.secrets @@ -0,0 +1,3 @@ +# /etc/ipsec.secrets - strongSwan IPsec secrets file + +: RSA carolKey.pem diff --git a/testing/tests/multi-level-ca-loop/hosts/carol/etc/ipsec.secrets b/testing/tests/multi-level-ca-loop/hosts/carol/etc/ipsec.secrets new file mode 100644 index 000000000..fac55d63b --- /dev/null +++ b/testing/tests/multi-level-ca-loop/hosts/carol/etc/ipsec.secrets @@ -0,0 +1,3 @@ +# /etc/ipsec.secrets - strongSwan IPsec secrets file + +: RSA carolKey.pem diff --git a/testing/tests/multi-level-ca-strict/hosts/carol/etc/ipsec.secrets b/testing/tests/multi-level-ca-strict/hosts/carol/etc/ipsec.secrets new file mode 100644 index 000000000..fac55d63b --- /dev/null +++ b/testing/tests/multi-level-ca-strict/hosts/carol/etc/ipsec.secrets @@ -0,0 +1,3 @@ +# /etc/ipsec.secrets - strongSwan IPsec secrets file + +: RSA carolKey.pem diff --git a/testing/tests/multi-level-ca/hosts/carol/etc/ipsec.secrets b/testing/tests/multi-level-ca/hosts/carol/etc/ipsec.secrets new file mode 100644 index 000000000..fac55d63b --- /dev/null +++ b/testing/tests/multi-level-ca/hosts/carol/etc/ipsec.secrets @@ -0,0 +1,3 @@ +# /etc/ipsec.secrets - strongSwan IPsec secrets file + +: RSA carolKey.pem diff --git a/testing/tests/starter-also-loop/pretest.dat b/testing/tests/starter-also-loop/pretest.dat index aa46124dc..b135b12c3 100644 --- a/testing/tests/starter-also-loop/pretest.dat +++ b/testing/tests/starter-also-loop/pretest.dat @@ -1 +1,2 @@ moon::ipsec start --debug-all +moon::sleep 1 diff --git a/testing/tests/starter-includes/evaltest.dat b/testing/tests/starter-includes/evaltest.dat index be8ca6ef5..7de32d681 100644 --- a/testing/tests/starter-includes/evaltest.dat +++ b/testing/tests/starter-includes/evaltest.dat @@ -10,7 +10,7 @@ moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES moon::tcpdump::IP dave.strongswan.org > moon.strongswan.org: ESP::YES moon::tcpdump::IP moon.strongswan.org > dave.strongswan.org: ESP::YES -alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: icmp::YES -alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: icmp::YES -alice::tcpdump::IP dave1.strongswan.org > alice.strongswan.org: icmp::YES -alice::tcpdump::IP alice.strongswan.org > dave1.strongswan.org: icmp::YES +alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: ICMP echo request::YES +alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: ICMP echo reply::YES +alice::tcpdump::IP dave1.strongswan.org > alice.strongswan.org: ICMP echo request::YES +alice::tcpdump::IP alice.strongswan.org > dave1.strongswan.org: ICMP echo reply::YES diff --git a/testing/tests/virtual-ip-swapped/evaltest.dat b/testing/tests/virtual-ip-swapped/evaltest.dat index 5160a340f..bf3965727 100644 --- a/testing/tests/virtual-ip-swapped/evaltest.dat +++ b/testing/tests/virtual-ip-swapped/evaltest.dat @@ -5,5 +5,5 @@ carol::ping -c 1 PH_IP1_MOON::64 bytes from PH_IP1_MOON: icmp_seq=1::YES moon::ping -c 1 PH_IP1_CAROL::64 bytes from PH_IP1_CAROL: icmp_seq=1::YES moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES -alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: icmp::YES -alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: icmp::YES +alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: ICMP echo request::YES +alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: ICMP echo reply::YES diff --git a/testing/tests/virtual-ip/evaltest.dat b/testing/tests/virtual-ip/evaltest.dat index 5160a340f..bf3965727 100644 --- a/testing/tests/virtual-ip/evaltest.dat +++ b/testing/tests/virtual-ip/evaltest.dat @@ -5,5 +5,5 @@ carol::ping -c 1 PH_IP1_MOON::64 bytes from PH_IP1_MOON: icmp_seq=1::YES moon::ping -c 1 PH_IP1_CAROL::64 bytes from PH_IP1_CAROL: icmp_seq=1::YES moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES -alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: icmp::YES -alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: icmp::YES +alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: ICMP echo request::YES +alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: ICMP echo reply::YES diff --git a/testing/tests/wlan/evaltest.dat b/testing/tests/wlan/evaltest.dat index ccf5d0c8a..1936c93a3 100644 --- a/testing/tests/wlan/evaltest.dat +++ b/testing/tests/wlan/evaltest.dat @@ -8,4 +8,4 @@ alice::ping -c 1 PH_IP_MOON::64 bytes from PH_IP_MOON: icmp_seq=1::YES alice::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_seq=1::YES venus::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_seq=1::YES moon::tcpdump::ESP::YES -sun::tcpdump::icmp::YES +sun::tcpdump::ICMP::YES |