From: Anas Nashif Date: Wed, 7 Nov 2012 06:48:54 +0000 (-0800) Subject: Imported Upstream version 1.0.10 X-Git-Tag: upstream/1.0.10^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=73fd264946be25652a3ce5acabdd65fc65724cdf;p=platform%2Fupstream%2Flksctp-tools.git Imported Upstream version 1.0.10 --- 73fd264946be25652a3ce5acabdd65fc65724cdf diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..98ffb31 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,36 @@ + +The initial developer and founder of the project: +------------------------------------------------- +La Monte H.P. Yarroll + +Current Maintainer: +------------------- +Sridhar Samudrala + +Previous Maintainers: +-------------------- +Jon Grimm + +Contributors: +------------- +Karl Knutson + +Xingang Guo + +Daisy Chang + +Inaky Perez-Gonzalez + +Hui Huang + +Dajiang Zhang + +Ryan Layer + +Francois-Xavier Kowalski + +Vlad Yasevich + +Frank Filz + +Are you missing? drop us a line! diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..dc63aac --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/COPYING.lib b/COPYING.lib new file mode 100644 index 0000000..7d31de0 --- /dev/null +++ b/COPYING.lib @@ -0,0 +1,456 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..28e51e6 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,858 @@ +Version 2.6.28-1.0.10 of the Developers' Release of the SCTP +Linux Kernel Implementation is available from + + http://www.kernel.org + +lksctp-2.6.28-1.0.10: Fri Mar 27 11:15:25 EDT 2009 +T:TEST Split the kernel frame test framework from lksctp-tools. The + framework is very sensitive to all kernel changes, not just ones + related to SCTP. As such, it has been a gating fractor to the + releases of the new tools. +T:APP New tool sctp_status to be used with SCTP conformance tests. + http://networktest.sourceforge.net/ +T:APP Add -T option to sctp_test +T:APP Fix the -e option to sctp_darn +T:LIB Fix building of static libraries. +T:LIB Fix compile warning in addrs.c +T:APP Update the application useage of sctp_connectx +T:TEST Update the sctp_connectx() functional tests. +T:API Update to the sctp_connectx(). Now takes additional argument. +T:API Let sctp_recvmsg() honor passed in MSG_ flags +K: See kernel change log for details. We'll track only tools + changes here from now on. +lksctp-2.6.26-1.0.9: Sun Jul 13 14:51:29 PDT 2008 +T:Patch Make frame tests work with 2.6.26 kernel. +T:Patch Implement and export SCTP-AUTH API extensions based on + sctpsocket-16 draft +T:NA Process withsctp.in at build time +K:Patch Add documentation for sctp sysctl variable +K:NA Mark the tsn as received after all allocations finish +K:NA Make sure N * sizeof(union sctp_addr) does not overflow. +K:NA Correclty set changeover_active for SFR-CACC +K:NA Correctly cleanup procfs entries upon failure. +K:NA Fix ECN markings for IPv6 +K:NA Flush the queue only once during fast retransmit. +K:NA Start T3-RTX timer when fast retransmitting lowest TSN +K:NA Correctly implement Fast Recovery cwnd manipulations. +K:NA Move sctp_v4_dst_saddr out of loop +K:NA retran_path update bug fix +K:NA Fix NULL dereference of asoc. +K:NA Fix use of uninitialized pointer +K:NA Add address type check while process paramaters of ASCONF chunk +K:NA Do not enable peer IPv6 address support on PF_INET socket +K:NA Initialize partial_bytes_acked to 0, when all of the data is acked +K:NA IPv4 vs IPv6 addresses mess in sctp_inet[6]addr_event. +K:NA Fix compiler warning about const qualifiers +K:NA Fix protocol violation when receiving an error lenght INIT-ACK +K:NA Add check for hmac_algo parameter in sctp_verify_param() +K:Patch New sctp mailing list +K:NA Remove an unused parameter from sctp_cmd_hb_timer_update +K:Patch "list_for_each()" -> "list_for_each_entry()" where appropriate. +K:NA Correct /proc/net/assocs formatting error +K:Patch Use snmp_mib_{init,free}(). +K:Patch Remove useless assignment from __sctp_rcv_lookup_endpoint +K:NA fix wrong debug counting of bind_bucket +K:NA fix wrong debug counting of datamsg +K:Patch Replace socket with sock for SCTP control socket. +K:Patch Use inet_ctl_sock_create for control socket creation. +K:Patch Remove sctp_add_cmd_sf wrapper bloat +K:Patch Remove redundant wrapper functions. +K:Patch Replace char msg[] with static const char[] +K:NA Fix a race between module load and protosw access +K:NA fix misannotated __sctp_rcv_asconf_lookup() +K:NA Fix local_addr deletions during list traversals. +K:Patch Bring MAX_BURST socket option into ietf API extension compliance +K:NA Fix chunk parameter processing bug +K:Patch Kill unused static inline sctp_sysctl_jiffies_ms +K:Patch extend exported data in /proc/net/sctp/assoc +K:Patch Use proc_create to setup de->proc_fops. +K:Patch Update AUTH structures to match declarations in draft-16. +K:NA Incorrect length was used in SCTP_*_AUTH_CHUNKS socket option +K:Patch Clean up naming conventions of sctp protocol/address family + registration +K:NA Correctly set the length of sctp_assoc_change notification +K:NA Pick up an orphaned sctp_sockets_allocated counter. +K:Patch Convert sctp_dbg_objcnt to seq files. +K:Patch Use snmp_fold_field instead of a homebrew analogue. +K:NA Make sure the chunk is off the transmitted list prior to freeing. +K:NA Fix kernel panic while received ASCONF chunk with bad serial + number +K:NA Set ports in every address returned by sctp_getladdrs() +K:NA Correctly reap SSNs when processing FORWARD_TSN chunk +K:NA Fix kernel panic while received AUTH chunk with BAD shared key + identifier +K:NA Fix kernel panic while received AUTH chunk while enabled auth +K:Patch Kill silly inlines in ulpqueue.c +K:NA Do not increase rwnd when reading partial notification. +K:Patch Stop claiming that this is a "reference implementation" +K:NA Fix miss of report unrecognized HMAC Algorithm parameter +K:NA Correctly initialize error when parameter validation failed. +K:Patch Follow Add-IP security consideratiosn wrt INIT/INIT-ACK +K:Patch Implement ADD-IP special case processing for ABORT chunk +K:Patch Change use_as_src into a full address state +K:Patch Update ASCONF processing to conform to spec. +K:Patch ADD-IP updates the states where ASCONFs can be sent +K:Patch Update association lookup to look at ASCONF chunks as well +K:Patch Add the handling of "Set Primary IP Address" parameter to INIT +K:Patch Handle the wildcard ADD-IP Address parameter +K:Patch Discard unauthenticated ASCONF and ASCONF ACK chunks +K:Patch Use crc32c library for checksum calculations. +K:Patch Use ipv4_is_ + +lksctp-2.6.24-1.0.8: Fri Feb 01 14:55:00 EST 2008 +K:NA Add back the code that accounted for FORWARD_TSN parameter in + INIT. +K:NA Correctly handle AUTH parameters in unexpected INIT +K:NA Fix the name of the authentication event. +K:NA Spelling fixes +K:NA Flush fragment queue when exiting partial delivery. +K:NA Fix the bind_addr info during migration. +K:NA Add bind hash locking to the migrate code +K:NA Fix build issues with SCTP AUTH. +K:NA Fix chunk acceptance when no authenticated chunks were listed. +K:NA Fix the supported extensions paramter +K:NA Fix SCTP-AUTH to correctly add HMACS paramter. +K:NA Fix the number of HB transmissions. +K:NA Add missing "space" +K:NA Always flush the queue when uncorcking. +K:NA Clean-up some defines for regressions tests. +K:NA Fix PR-SCTP to deliver all the accumulated ordered chunks +K:NA Make sctp_verify_param return multiple indications. +K:NA Convert custom hash lists to use hlist. +K:NA Use hashed lookup when looking for an association. +K:NA Fix a potential race between timers and receive path. +K:NA Allow ADD_IP to work with AUTH for backward compatibility. +K:NA Correctly disable ADD-IP when AUTH is not supported. +K:NA Update RCU handling during the ADD-IP case +K:NA Fix difference cases of retransmit. +K:NA Fix to process bundled ASCONF chunk correctly +K:NA Fix bad formatted comment in outqueue.c +Patch Use the {DEFINE|REF}_PROTO_INUSE infrastructure +K:NA SCTP endianness annotations regression +K:NA net/sctp/auth.c: make 3 functions static +K:NA #if 0 sctp_update_copy_cksum() +K:NA Consolidate sctp_ulpq_renege_xxx functions +Patch port randomization +Patch Tie ADD-IP and AUTH functionality as required by spec. +Patch API updates to suport SCTP-AUTH extensions. +Patch Implement the receive and verification of AUTH chunk +Patch Enable the sending of the AUTH chunk. +Patch Implement SCTP-AUTH parameter processing +Patch Implement SCTP-AUTH initializations. +Patch Implement SCTP-AUTH internals +Patch protocol definitions for SCTP-AUTH implementation +K:NA Move sysctl_sctp_[rw]mem definitions to protocol. +Patch Implement the Supported Extensions Parameter +K:NA net/sctp/socket.c: make 3 variables static +K:NA Make sctp_addto_param() static. +Patch Rewrite of sctp buffer management code +K:NA Add paramters validity check for ASCONF chunk +K:NA Discard OOTB packetes with bundled INIT early. +K:NA Clean up OOTB handling and fix infinite loop processing +K:NA Explicitely discard OOTB chunks +K:NA Send ABORT chunk with correct tag in response to INIT ACK +K:NA Validate buffer room when processing sequential chunks +K:NA Convert bind_addr_list locking to RCU +K:NA Add RCU synchronization around sctp_localaddr_list +K:NA Fix to handle invalid parameter length correctly +K:NA Abort on COOKIE-ECHO if backlog is exceeded. +K:NA Correctly disable listening when backlog is 0. +K:NA Do not retransmit chunks that are newer then rtt. +K:NA Uncomfirmed transports can't become Inactive +K:NA Pick the correct port when binding to 0. +K:NA Use net_ratelimit to suppress error messages print too fast +K:NA Fix to encode PROTOCOL VIOLATION error cause correctly +K:NA Fix sctp_addto_chunk() to add pad with correct length +K:NA Assign stream sequence numbers to the entire message +K:NA properly clean up fragment and ordering queues during FWD-TSN. +K:NA remove useless code in function sctp_init_cause +K:NA drop SACK if ctsn is not less than the next tsn of assoc +K:NA IPv4 mapped addr not returned in SCTPv6 accept() +K:NA Fix whitespace errors. + +lksctp-2.6.22-1.0.7: Thu Jul 12 12:24:14 EDT 2007 +K:NA Don't disable PMTU discovery when mtu is small +K:NA Flag a pmtu change request +K:NA Update pmtu handling to be similar to tcp +K:NA Fix leak in sctp_getsockopt_local_addrs when copy_to_user fails +K:NA Allow unspecified port in sctp_bindx() +K:NA Correctly set daddr for IPv6 sockets during peeloff +K:NA Do not include ABORT chunk header in the notification. +K:NA Correctly copy addresses in sctp_copy_laddrs. +K:NA Prevent OOPS if hmac modules didn't load +K:NA Set assoc_id correctly during INIT collision. +K:NA Re-order SCTP initializations to avoid race with sctp_rcv() +K:NA Fix the SO_REUSEADDR handling to be similar to TCP. +K:NA Verify all destination ports in sctp_connectx. +K:NA Fix sctp_getsockopt_local_addrs_old() to use local storage. +K:NA Implement SCTP_MAX_BURST socket option. +K:NA Implement sac_info field in SCTP_ASSOC_CHANGE notification. +K:NA Honor flags when setting peer address parameters +K:NA Implement SCTP_ADDR_CONFIRMED state for ADDR_CHNAGE event. +K:NA Implement SCTP_PARTIAL_DELIVERY_POINT option. +K:NA Implement SCTP_FRAGMENT_INTERLEAVE socket option +K:NA Do not interleave non-fragments when in partial delivery +K:NA Unmap v4mapped addresses during SCTP_BINDX_REM_ADDR operation. +K:NA Fix assertion (!atomic_read(&sk->sk_rmem_alloc)) failed message +K:NA Correctly reset ssthresh when restarting association +K:NA Reset some transport and association variables on restart +K:NA Increment error counters on user requested HBs. +K:NA Cleanup stale data during association restart +K:NA Strike the transport before updating rto. +K:NA Fix connection hang/slowdown with PR-SCTP. +K:NA Force update of the rto when processing HB-ACK +K:NA Fix SACK sequence during shutdown. +K:NA Correctly handle unexpected INIT-ACK chunk. +K:NA Verify some mandatory parameters. +K:NA Set correct error cause value for missing parameters +K:NA Fix err_hdr assignment in sctp_init_cause. +T:NA Add support for sctp_getaddrlen() API. +K,T:NA Fix typo adaption -> adaptation as per the latest API draft. +K:NA Don't export include/linux/sctp.h to userspace. +K,T:NA Add support for SCTP_CONTEXT socket option. +K:NA Enable auto loading of SCTP when creating an ipv6 SCTP socket. +K:NA Handle address add/delete events in a more efficient way. +K:NA SCTP endianness annotations. +K:NA Cleanup of the sctp state table code. +K:NA Remove temporary associations from backlog and hash. +K:NA Correctly set IP id for SCTP traffic. +K:NA Always linearize packet on input. +K:NA Fix the RX queue size shown in /proc/net/sctp/assocs output. +K:NA Fix receive buffer accounting. +K:NA Do not timestamp every SCTP packet. +K:NA Use correct mask when disabling PMTUD. +K:NA Include sk_buff overhead while updating the peer's receive window. +K:NA Enable Nagle algorithm by default. +K:NA Remove multiple levels of msecs to jiffies conversions. +K:NA Use the flags value that is passed as an arg to sctp_accept. +K:NA Fix IPv6 address flag setting when doing peel-off/accept. +K:NA Cleanup nomem handling in the state functions. +K:NA Extend /proc/net/sctp/snmp to provide more statistics. +K:NA Convert SCTP to use the new HMAC template and hash interface. +K:NA Fix sctp_primitive_ABORT() call in sctp_close(). +K:NA Fix sctp_make_abort_user() to avoid use of buggy + get_user_iov_size(). +K:Bug 1502698 ADDIP: Don't use an address as source until it is ASCONF-ACKed. +K:NA Set chunk->data_accepted only if we are going to accept it. +K:NA Verify all the paths to a peer via heartbeat before using them. +K:NA Unhash the endpoint in sctp_endpoint_free(). +K:NA Check for NULL input to sctp_bucket_destroy(). +K:NA Fix persistent slowdown in sctp when a gap ack consumes rx buffer. +K:NA Send only 1 window update SACK per message. +K:NA Don't do CRC32C checksum over loopback. +K:NA Reset rtt_in_progress for the chunk when processing its sack. +K:NA Reject sctp packets with broadcast addresses. +K:NA Limit association max_retrans setting in ASSOCINFO setsockopt. +T:NA updates to linux 2.6.17 +K:NA Allow linger to abort 1-N style sockets. +K:NA Validate the parameter length in HB-ACK chunk. +K:NA A better solution to fix the race between sctp_peeloff() and + sctp_rcv(). +K:Bug 1439226 Set sk_err so that poll wakes up after a non-blocking connect + failure. +K:NA Fix state table entries for chunks received in CLOSED state. +K:NA Fix panic's when receiving fragmented SCTP control chunks. +K:NA Prevent possible infinite recursion with multiple bundled DATA. +K:NA Allow spillover of receive buffer to avoid deadlock. +T:NA Fix the type of 'len' argument in sctp_recvmsg() man page. + +lksctp-2.6.16-1.0.6: Fri Feb 3 10:54:20 PST 2006 +K:NA Fix 'fast retransmit' to send a TSN only once. +K:NA Heartbeats exceed maximum retransmission limit. +K:NA Correct the number of INIT retransmissions. +K:NA Fix sctp_rcv_ootb() to handle the last chunk of a packet + correctly. +K:NA Fix couple of races between sctp_peeloff() and sctp_rcv(). +K:NA Fix machine check/connection hang on IA64. +K:NA Fix bad sysctl formatting of SCTP timeout values on 64-bit m/cs. +K:NA Fix sctp_assoc_seq_show() panics on big-endian systems. +K:NA sctp doesn't show all associations/endpoints in /proc. +K:NA Fix sctp_cookie alignment in the packet. +K:NA Fix potential race condition between sctp_close() and sctp_rcv(). +K,T:NA Add support for SCTP_DELAYED_ACK_TIME socket option. +K,T:NA Update SCTP_PEER_ADDR_PARAMS socket option to the latest api. + draft11. + +lksctp-2.6.15-1.0.5: Tue Jan 3 15:49:27 PST 2006 +K:NA Fix SCTP to not return erroneous POLLOUT events. +K:NA Fix getsockname for sctp when an ipv6 socket accepts a + connection from an ipv4 socket. +K:NA Return socket errors only if the receive queue is empty. +K,T:NA Include ulpevents in socket receive buffer accounting. +K:Bug 1350514 Fix ia64 NaT consumption fault with sctp_sideeffect commands. +K:NA Remove timeouts[] array from sctp_endpoint. +K:Bug 1350521 Fix potential NULL pointer dereference in sctp_v4_get_saddr. +K:NA Do not allow unprivileged programs initiating new assocs on + privileged ports. +K:NA Allow SCTP_MAXSEG to revert to default frag point with a '0' + value. +K:NA Fix SCTP_SETADAPTION sockopt to use the correct structure. +K,T:NA Rename SCTP specific control message flags to use SCTP_ prefix + rather than MSG_ prefix. + +lksctp-2.6.14-1.0.4: Fri Oct 28 10:56:04 PDT 2005 +T:NA Add sctp_send() API support, testcases and manpage. +T:NA Add preprocessor constants for PR-SCTP, ADDIP & CANSET_PRIMARY +K,T:NA Fix SCTP socket options to work with 32-bit apps on 64-bit + kernels. +K,T:NA Fix sctp_get{pl}addrs() API to work with 32-bit apps on 64-bit + kernels. +T:NA Ignore MSG_CMSG_COMPAT flag leaked to 32-bit userspace with + 64-bit kernels <= 2.6.13. +K,T:Bug 1122994Fix SCTP_SHUTDOWN notifications for 1-1 style sockets. + +lksctp-2.6.13-1.0.3: Thu Sep 1 10:54:22 PDT 2005 +T:NA Update to 2.6.13 +K:NA Fix potential NULL pointer dereference while handling an ICMP + error. +K:NA Make init & delayed sack timeouts configurable by user. +K:NA Fix incorrect setting of sk_bound_dev_if when binding/sending + to a ipv6 link local address. +K:NA Support IP_FREEBIND socket option and ip_nonlocal_bind sysctl. +K:NA Extend the info exported via /proc/net/sctp to support + netstat for SCTP. +K:NA Support SO_BINDTODEVICE option on incoming packets. +K:Bug 120804 Fix bug in restart of peeled-off association. +K,T:NA sctp_connectx() support. +T:NA Increase sk_sndbuf to address send buffer accounting changes. +T:NA Update SCTP internet drafts in doc directory +T:NA Fix inconsistencies in license stmt in the library files. +K:Bug 1155119 Add sctp send buffer accounting. +K:NA Replace incorrect use of dev_alloc_skb with alloc_skb in + sctp_packet_transmit(). +K:NA Fix bug in sctp_init() error handling code. +K:NA Use ipv6_addr_any() rather than ipv6_addr_type() in + sctp_v6_is_any(). +T:Bug 1150885 Fix subscript out of range bug in sctp_test.c +K:Bug 1158878 Implement Sec 2.41 of SCTP Implementers guide. +K:Bug 1121085 Fix SCTP_ASSOCINFO getsockopt for 1-1 style sockets. +K:Bug 1155130 Add sctp receive buffer accounting. + +lksctp-2.6.10-1.0.2: Thu Dec 30 15:55:27 PST 2004 +Bug 1074664 Fix sctp_getladdrs() to return valid local addresses on an + endpoint that is bound to INADDR_ANY or inaddr6_any. +NA Update to 2.6.10 +Bug 1028605 Fix misc. issues in SCTP_PEER_ADDR_PARAMS set socket option. +NA Fix bug in setting ephemeral port while adding a bind address. +Bug 1090392 Clean up the T3_rtx timer when deleting a transport. +Patch 1090027Implementation of SCTP IG Section 2.35 +Bug 905731 Validate and respond to invalid chunk/parameter lengths. +Bug 1085959 Treat ICMP protocol unreachable errors from non-SCTP capable + hosts as ABORTs. +NA Code cleanup: remove unused code and make needlessly global code + static +Bug 1058857 Fix potential null pointer dereference in sctp_err_lookup(). +Bug 982971 Validate fromlen/msg_flags in sctp_recvmsg before dereferencing. +Bug 860345 Fix invalid msg length to sctp_sendmsg in sctp_xconnect.c +Bug 1008149 Fix HEARTBEAT_ACKs being sent to wrong dest. ip address in a + multihoming scenario after failback. (Jorge) +NA Update any transports that are caching a deleted address as + a source address. +NA Update cwnd/ssthresh as per the sctpimpguide modifications. +NA Adaption layer indication support +NA Change sctp_assoc_t to a sized type(s32) +NA Update to 2.6.9 +NA Update to 2.6.8-rc2 +NA Mark chunks as ineligible for fast retransmit after handling + retransmit. +Bug 995918 Fix missing '+' in the computation of sack chunk size in + sctp_sm_pull_sack(). +NA Use idr_get_new_above() with a starting id of 1 to avoid returning + an associd of 0. +Bug 968562 Fix issues with handling stale cookie error over multihoming + associations. +Bug 991991 Fix data not being delivered in SHUTDOWN_SENT state. +Bug 979178 Set/Get default SCTP_PEER_ADDR_PARAMS for endpoint when associd + and peer address are 0. +Bug 965359 Fix missing VTAG validation on certain incoming packets. +Bug 965278 Fix to wakeup blocking connect() after max INIT retries failed. +Bug 965276 Fix the use of cached non-zero vtag in a INIT that is resent + after a stale cookie error. +Bug 962587 Fix poll() on a 1-1 style socket so that it returns when the + association is aborted by peer. +Bug 962530 Add association states to netinet/sctp.h +Bug 954271 Fix to not start a new association on a 1-many style sendmsg() + with MSG_EOF/MSG_ABORT flag and no data. +Bug 948012 Fix to not setup a new association if the endpoint is in + SHUTDOWN_ACK_SENT state and recognizes that the peer has restarted. + +lksctp-2.6.6-1.0.1: Tue May 11 10:08:56 PDT 2004 +Bug 949429 Fix multihomed connection failures on 64bit systems. (Vlad) +Bug 932698 fix accessing gap ack blocks array with -ve index in + sctp_outq_sack(). +Bug 932692 memset parameter misordering. +NA Fix the 3rd arg to sctp_recvmsg() to size_t instead of a ptr. +NA Rename SCTP_ADDR_REACHBLE as SCTP_ADDR_AVAILABLE. +NA Fix bugs in handling overlapping INIT and peer restart over a + multi-homed association. +NA SCTP crc table can be static const (Stephen Hemminger) +NA Update sctp_test message sizes to match the new frag point of + 1452 bytes for AF_INET sockets with 1500 mtu. +NA Propagate error from sctp_proc_init. (Olaf Kirch) +Patch 751951 Partial Reliability extension support. +NA Cleanup sctp_packet and sctp_outq infrastructure. +NA Avoid the use of constant SCTP_IP_OVERHEAD to determine the max + data size in a SCTP packet. +NA Add MSG_EOF to netinet/sctp.h +NA Use id to ptr translation service to assign and validate assoc ids. +NA Update sctp_ulpevent structure. +NA Fix typo in entry name of remove_proc_entry() call. +NA Enable association change and data io events in sctp_test. +NA Add set_peer_primary interactive option to sctp_darn. +NA Use AM_CFLAGS/AM_LDFLAGS in Makefile.am's. +NA Avoid the use of hackish CONFIG_IPV6_SCTP__ option. +NA Don't do any ppid byte-order conversions as it is opaque to SCTP. + +lksctp-2.6.3-1.0.0: +Bug 905331 Fix incorrect sinit_max_init_timeo behavior. (samudrala) +NA Force enable crypto options needed by SCTP (samudrala) +NA Update to 2.6.3 (samudrala) +NA Add support to get/set primary addr of an assoc to sctp_darn. +NA Add __BEGIN_DECLS/__END_DECLS to sctp.h (Ian) +NA Fix sctp_getladdrs()/sctp_getpaddrs() API so that the port value + in the returned addresses is in network byte order. (samudrala) +NA Fix SCTP_INITMSG set socket option so that a parameter with 0 + value will not change its current value. (samudrala) +NA Use __get_free_pages() to allocate ssnmap to avoid kmalloc's + 128K limit. (samudrala) + +lksctp-2.6.2-0.9.0: +NA Updated withsctp to capture and replace TCP_NODELAY + setsockopt() (samudrala) +Patch 890787 RPM packaging bugfixes. (FiX) +NA Removed the deprecated ADLER32 checksum support. (samudrala) +NA Update to 2.6.2 (samudrala) +NA Added manpages for SCTP. (samudrala) +Patch 887176 autoconf cleanup/ Initial RPM packaging (FiX) +Patch 878417 Added new 1-1 style API testcases. (damien, samudrala) +NA Add sysctl parameters to change socket receive/send buffer sizes + and update the default receive buffer to 65535 bytes. +NA provide valid tos and oif values for ip_route_output_key. +NA Fix bugs in byte order conversion while processing certain + address related socket options. (samudrala) +Patch 869098 ADDIP: T4 RTO timer support. (kevin.gao) +Patch 865250 withsctp: a tool to replace TCP with SCTP. (La Monte) +NA Enable shared libraries in lksctp-tools. (FiX) +Patch 843544 ADDIP: Process incoming ASCONF_ACK chunks. (kevin.gao) +NA Add a testcase to verify that a SHUTDOWN_COMP notification is + received on a SHUT_RW one-to-one style socket. (samudrala) +NA Add peeloff test to src/apps. (samudrala) +NA Fix overflow in the macros JIFFIES_TO_MSECS/MSECS_TO_JIFFIES + when used with large values. (samudrala) +NA Fix the duplicate increment of checksum error counter and + counting bad packet errors as checksum errors. (samudrala) +NA Fix to free assocs in the acceptq of a one-to-one style socket + that is closed. (samudrala) +NA ADDIP: Add sysctl parameter to enable/disable addip (samudrala) +NA Fix extra semicolon bug in sctp_cacc_skip_3_1() (Ed Rupp) +Patch 831522 ADDIP: Testcase for delete IP (kevin.gao) +Patch 822546 ADDIP: Process ASCONF and respond with ASCONF_ACK (kevin.gao) + +lksctp-2.6.0-test7-0.7.4: +NA Update SCTP tests so that they can be run under LTP (samudrala) +NA Update to 2.6.0-test7 (samudrala) +Patch 809137 ADDIP: Support to create ASCONF_ACK chunk. (kevin.gao) +Patch 798988 ADDIP: ASCONF chunk send support. (kevin.gao) +NA lksctp-tools tree re-organization (samudrala) +NA Fix malloc calls in kernel tests with no error checks. (samudrala) +NA Fix bugs in conversions between msecs and jiffies. (samudrala) +NA Update to 2.6.0-test6 (samudrala) +PARISC64 Convert tv_add() from a static inline to macro to fix an + obscure assembler issue with parisc64 (samudrala) +NA Update to 2.6.0-test5 (samudrala) +PPC64 port Use correct types for args passed to sctp_recvmsg() calls. +PPC64 port Change the last arg of sctp_opt_info() to match the last arg + of getsockopt(). (samudrala) +PPC64 port Don't overload the optval of ADDRS_NUM socket options with + different types for input and output. (samudrala) + +lksctp-2_6_0-test4-0_7_3: +NA draft 07 API: (samudrala) + - listen() with 0 backlog disables listening. + - By default all notifications are turned off even with + one-to-many(UDP) style sockets. +Bug 799468 Fixes for a couple of issues with ssnmap allocation. (samudrala) +NA Convert sctp_param2sockaddr() and sockaddr2sctp_addr to address + family specific routines. (samudrala) +NA draft 07 API: sctp_bindx() update. (samudrala) +Patch 791660 ADDIP: SCTP_SET_PEER_PRIMARY socket option support. (kevin.gao) +NA Update to 2.6.0-test4 (samudrala) +NA draft 07 API: getp/laddrs, freep/laddrs changes (samudrala) +NA draft 07 API: sctp_recvmsg() arg type change. (samudrala) +NA draft 07 API: sctp_peeloff() takes associd, not a ptr (samudrala) +Patch 784504 ADDIP: Testcase to verify basic ADDIP functionality. (kevin.gao) +Bug 787008 Bugs in sysctl set/get of sctp rto parameters. (samudrala) +NA Update to 2.6.0-test3 (samudrala) +Bug 783176 Fix to avoid large kmalloc failures on 64bit platforms (samudrala) +Patch 776732 ADDIP basic infrastructure support. (ardelle.fan) +Patch 775227 sctp_recvmsg() API support. (rlayer) + +lksctp-2_6_0-test1-0_7_2: +NA Set output interface for link-local v6 addresses (jgrimm) +Patch 769844 Add V6 and freebsd support to sctp_test (rlayer) +Patch 772062 Support IPV6_V6ONLY socket option. (ardelle.fan) +Patch 757888 Support v4-mapped-v6 addresses (ardelle.fan) +NA Update API names to be compatible with draft07 (samudrala) +NA Update to 2.6.0-test1 (samudrala) +Patch 767208 Shutdown transport selection fix. (rlayer) +Patch 769792 Fix for panic on recvmsg() with MSG_PEEK & misc stuff (samudrala) +Patch 765676 Fix nasty race on skb destructor with AF_PACKET sockets (jgrimm) + +lksctp-2_5_72-0_7_1: +Patch 759352 Perf: Don't search for gap ack blocks past highest TSN (jgrimm) +Patch 758202 Perf: Remove update_pending() from SACK path (jgrimm) +NA Update to 2.5.72 +NA Fix hlist bug introduced by mainline kernel (jgrimm) +NA sctp_xconnect test tool (rlayer) +Patch 729089 ASSOCINFO/RTOINFO sockopts (pems & rlayer) +NA Update to 2.5.71 (jgrimm) +Bug 754129 Incorrect VTAG in stale cookie error chunk (samudrala) +Patch 749587 Change rto sysctl vars to milliseconds (rmlayer) +Patch 752321 Add kamikaze test. (ardelle.fan) +Bug 752808 Bug fix for input loop exiting too early on TCP-style (jgrimm) + +lksctp-2_5_70-0_7_0: +NA Fix hostname parameter handling, should ABORT (jgrimm) +NA Fix ft_frame_unkparam testcase (rlayer) +Bug 751458 Fixes from InterOp (jgrimm, samudrala) +Bug 746295 Fix div by 0 in sctp_jitter (jgrimm) +NA Make T5 timer cleanup SHUTDOWN-PENDING state. (jgrimm) +Patch 744633 /proc interface to display associations/endpoints (samudrala) +NA Update to 2.5.70 kernel. (samudrala) +NA sctp_getladdrs(), sctp_getpaddrs() bug fixes. (samudrala) +Patch 738592 sctp_sendmsg() api support. (ardelle.fan) +Patch 738550 SCTP_SHUTDOWN_EVENT notification support. (samudrala) +NA Rename struct sctp_protocol as sctp_globals (samudrala) +Patch 737395 SCTP_GET_PEER_ADDR_INFO socket option. (samudrala) +Bug 695324 Report error cause in CANT_STR_ASSOC (ardelle.fan) +Bug 695322 Stale cookie might not be first err cause (ardelle.fan) +Patch 735933 Support for socket options that take addr & associd (samudrala) +Patch 718726 Add CACC frametest (ardelle.fan) +NA slab cache for chunks & bind_bucket (jgrimm) +NA Update to 2.5.69 kernel. (samudrala) +Patch 733320 SCTP ECN & IPv6 (jgrimm) +NA Bug in get_peer_addr_params. (jgrimm, report by yfj@stanford.edu) +Patch 730924 Add sinfo_timetolive support. (jgrimm) +Patch 730461 SO_LINGER support for TCP-style sockets. (samudrala) +Bug 729234 Initialize missing v4 fields of a v6 accept socket (samudrala) +Bug 729652 Free chunk(s) when primitive_SEND fails (jgrimm) +Patch 704841 SEND_FAILed for fragmented messages (jgrimm, ardelle.fan) +Patch 727821 sendmsg() updates for TCP-style sockets. (samudrala) +Patch 727454 Add control chunk bundling (jgrimm) +Patch 718726 Add SFR-CACC support. (ardelle.fan) +Patch 726343 Add SCTP_MAXSEG support. (jgrimm) +NA Add some macros to help cleanup code. (jgrimm) +Patch 725367 Fix for poll() on a TCP-style listening socket. (samudrala) +Patch 725219 Add per message fragment tracking (jgrimm) +NA Update to 2.5.68 kernel. (samudrala) + +lksctp-2_5_67-0_6_9: +Patch 723414 Handle accept() of a CLOSED association. (samudrala) +Patch 722206 shutdown() support for TCP-style sockets. (samudrala) +Bug 722169 Fix can't send to routed ipv6 address bug (jgrimm) +NA Fix GFP_KERNEL allocation while spinlock. (jgrimm) +Patch 721330 Allow v4 private to v4 global association. (jgrimm) +Patch 720930 getsockname/getpeername support for TCP-style sockets (samudrala) +Patch 719232 optimization: csum_update_copy && ulpq short-circuit (jgrimm) +NA Update to 2.5.67 kernel. (samudrala) +Patch 717587 Use kernel crypto api (jgrimm) +Patch 714270 listen backlog support for TCP-style sockets. (samudrala) +Patch 712929 Fix SACK bundling bug & a few minor fixes (jgrimm) +Patch 711590 Add V6_LINKLOCAL & sin6_scope_id support. (jgrimm) +Patch 711584 Add '--interface' option to sctp_darn tool. (jgrimm) +Patch 704841 Add SEND_FAILED support (ardelle.fan) +NA Update to 2.5.66 kernel (jgrimm) +Patch 709527 Add icmpv6 handler and PKT_TOOBIG support. (jgrimm) + +lksctp-2_5_65-0_6_8: +Patch 706470 Bundle SACK with outgoing DATA (jgrimm) +NA Add --echo option to sctp_darn (jgrimm) +NA Update to 2.5.65 kernel and config changes. (jgrimm) +Patch 702439 New kernel test to verify TCP-style socket interfaces. (samudrala) +Bug 701294 Invalid associd passed to getsockopt() in sctp_darn. (samudrala) + +lksctp-2_5_64-0_6_7: +NA Update to 2.5.64 kernel. (samudrala) +Bug 699299 Panic in close(). (jgrimm) +Patch 698437 frametest for TCP-style sockets. (samudrala) +Patch 698877 Receiver SWS prevention. (jgrimm) +Patch 689872 Nagle-like support for SCTP. (ardelle.fan) +Patch 694884 accept() support for TCP-style sockets. (samudrala) +NA Bug fix from mailing list (Norbert Kiesel) +Patch 689872 SCTP_NODELAY testcases (ardelle.fan) + +lksctp-2_5_63-0_6_6: +NA Update to 2.5.63 kernel. (samudrala) +Patch 692590 Add set/getsockopt SET_PEER_PRIMARY_ADDR (jgrimm) +Bug 601470 Fix PF_INET sockets advertise v6 support bug (jgrimm) +NA Fix testframe for non-SMP build (jgrimm) +Bug 688408 Fix testcases for v4 only configurations (jgrimm) +Patch 677351 Add getsockopt for DEFAULT_SEND_PARAM (ardelle.fan) +Patch 689446 Renege for "fills gap" case. (jgrimm) +Bug 611888 Round-robin retransmit path updates. (samudrala) +NA Update to 2.5.61 kernel. (samudrala) +NA Update to 2.5.60 kernel. (samudrala) +Bug 649355 v6 source address selection support. (samudrala) +Patch 680361 Add testcase for partial data delivery. (jgrimm) +Patch 677351 SET_DEFAULT_SEND_PARAM setsockopt. (ardelle.fan) +Patch 681914 Skinny up ulpevent and support sinfo_cumtsn (jgrimm) +Patch 685246 Partial Data Delivery. (jgrimm). +Patch 683736 Override primary destination with MSG_ADDR_OVER (ardelle.fan) +Patch 630124 SCTP snmp mib statistics update/display support. (samudrala) +Patch 686131 Move duplicate TSN tracking to tsnmap & cleanup (jgrimm) +NA C99 struct initializer cleanup. (Art Haas) + +lksctp-2_5_59-0_6_5: +Patch 674359 Handling for Invalid Stream in INIT & missing cookie. (jgrimm) +Patch 676473 Add v6 scoping testcases. (jgrimm) +Bug 677107 af->dst_saddr doesn't fill in the port (samudrala) +Patch 676468 Cleanup of assoc bind addr list initialization (samudrala) +Patch 678481 Large Message Fragmentation support (jgrimm) +Bug 679839 Kconfig can emit bad config of ipv6=m, sctp=y (jgrimm) + +lksctp-2_5_59-0_6_4: +Patch 673715 Fix to update rwnd on partial reads. (samudrala) +Patch 673678 Minor fixes to overlapping init. (jgrimm) +Patch 673309 Minor fixes to icmp error handler. (samudrala) +Bug 672878 Free chunks in rtx & control queues on teardown.(samudrala) +Patch 672759 Advisory marker as 'unsafe' for unload. (jgrimm) +Patch 671916 Heartbeat timer during shutdown fixes (jgrimm) +Patch 670970 Path mtu support for v4 addresses. (samudrala) +NA Update to 2.5.59 kernel. (samudrala) +Patch 667038 Add heartbeat jitter (ardelle.fan) +Patch 670020 Remove hardcoded stream limits (jgrimm) +NA Update to 2.5.56 kernel. (samudrala) +Patch 662296 Handle ip re-assembled non-linear skb's (samudrala) +Patch 663633 get/free paddrs and laddrs support (ardelle.fan) +Bug 664112 Retransmitting already gap-acked TSNs (jgrimm) +NA Update to 2.5.53 kernel. (samudrala) +Bug 667037 ft_frame_rwnd_receiver fail with v4 only (ardelle.fan) + +lksctp-2_5_52-0_6_3: +NA Update to 2.5.52 kernel. (samudrala) +Patch 652802 Window update SACK support. (samudrala) +Patch 651063 Fixes for compiler issues with gcc 3.2 (samudrala) +Patch 649819 Notifier registration for v6 addr events. (samudrala) +Patch 638235 Stale cookie support. (ardelle.fan) +Patch 648103 v6 source address selection support. (samudrala) +Bug 645067 memcpy in sctp_sendmsg() may copy too much. (samudrala) +NA Update to 2.5.50 kernel. (samudrala) +Patch 644936 SCTP_INITMSG socket option. (samudrala) +NA Update to 2.5.49 kernel. (samudrala) +Bug 641066 Bad dereference in sctp_cmd_assoc_failed. (samudrala) +Patch 639177 MSG_PEEK support for recvmsg(). (samudrala) + +lksctp-2_5_47-0_6_2: +Patch 637943 MSG_EOR support for recvmsg(). (samudrala) +NA Update to 2.5.47 kernel. (samudrala) +Patch 636734 v6 autobind (jgrimm) +Patch 635797 Blocking connect() support. (samudrala) +Patch 634730 udp-style connect(non-blocking) support. (samudrala) +NA Update to 2.5.46 kernel. (samudrala) +Patch 555335 Peer address parameters socket option (ardelle) +NA Update to 2.5.45 kernel. (samudrala) +Patch 631750 sctpParam_t cleanup (jgrimm) +Bug 587078 sctp_process_init() can fail (jgrimm) +Patch 633338 Handle HOST_NAME_ADDR parm and misc. (jgrimm) +Patch 625413 sockaddr_storage_t cleanup (jgrimm) +Patch 635246 short circuit "no route" case (jgrimm) +Bug 581734 PF_INET6 listen can't receiving v4 addresses (jgrimm) + +lksctp-2_5_44-0_6_1: +Patch 628901 Initial Source address selection support. (samudrala) +Bug 611930 Lost CWR scenario fix (jgrimm) +NA 2.5.44 (jgrimm) +Patch 628333 SNMP MIB infrastructure for SCTP. (nivedita) +Patch 628318 Checks for tcp-style sockets. (nivedita) +Bug 547270 Retain the order of retransmission. (daisyc) +Patch 622919 Handle User initiated ABORT. (ardelle.fan) +Bug 611927 Bug in the calculation of highest new tsn in sack. (samudrala) +Bug 611916 Data can end up getting sent ahead of pend. rtx data (jgrimm) +NA Update to 2.5.43 kernel. (samudrala) +Bug 623286 SHUTDOWN_COMPLETE has 0 vtag on lost SDC + restart. (samudrala) +Patch 601756 VTAG checks for ABORT and SHUTDOWN_COMPLETE chunks. (ardelle.fan) +Patch 619993 Fixes a couple of sctp_peeloff() issues. (samudrala) +Bug 611919 Fast retranmist should ignore cwnd limit. (daisyc) +Bug 611840 Restart address needs to check INIT and happen earlier (jgrimm) + +lksctp-2_5_41-0_6_0: +NA Update to 2.5.41 kernel (samudrala) +Bug 621054 v6 kernel tests pass without IPv6 configured. (daisyc) +NA Update to 2.5.40 kernel (jgrimm) +NA Split into user/kernel repositories (inaky, daisyc) +Bug 611928 Alloc GFP_KERNEL with locks held (jgrimm) +Bug 602650 Dropping packets > frag_point (jgrimm, samudrala) +Patch 601367 Handle Unrecognized Parms (daisyc) +Patch 609744 Add abort and shutdown to sctp_darn (ardelle.fan) +Bug 604251 Association freed twice (jgrimm) +Bug 611835 Fix Restart address check (jgrimm) + +lksctp-2_5_29-0_5_0: +Patch 588249 misc. user header file fixes (jgrimm) + +lksctp-2_5_29-0_4_99: +Patch 582166 sctp_peeloff() support. (samudrala) +Bug 583874 sendmsg/init with bad buf. has leak (jgrimm) +Patch 581963 Handle select/poll syscalls (daisyc) +Bug 583798 Need GFP_ATOMIC when BH disabled (samudrala) +Bug 585351 MSG_UNORDERED not set on fragmented chunks (samudrala) +Patch 585474 Remove old DEFAULT_STREAM sock opt (jgrimm) +Bug 585653 Fix V6INADDR_ANY to choose a saddr (jgrimm) +Bug 585929 more leaks in sendmsg() on error cases. (samudrala) +Patch 574420 overlapping init/restart (dajiang, jgrimm) +Bug 581992 zero probe shouldn't error association (samudrala) +Patch 587986 move to Linux 2.5.29 (samudrala) + +lksctp-2_5_24-0_4_12: +Patch 569943 graceful shutdown of an individual association. (samudrala) +Patch 572054 move to linux kernel 2.5.24. (samudrala) +Bug 574069 bugs in fragmentation & reassembly. (samudrala) +Patch 579301 check for No User Data error and testcase (jgrimm) +Bug 574071 less strict rwnd check at rcvr (samudrala) +Patch 579525 SCTP_AUTOCLOSE socket option. (samudrala) +Patch 575712 modify sctp_darn tool to use select (daisyc) +NA misc.: cleanup jiffies decl., update docs. (jgrimm) +Patch 581745 getsockname needs sk->sport (jgrimm) +Patch 582273 handle DATA while in SHUTDOWN-SENT (jgrimm) +Bug 581997 sctp_wait_for_sndbuf fault (jgrimm) +Patch 573958 Overlapping Init testcases (dajiang) +Patch 582905 misc: remove md5 files. update cause code values (jgrimm) + +lksctp-2_5_15-0_4_11: +Patch 560341 assoc_hash and more locking (jgrimm) +Bug 541062 local_addr_list not not writer safe (jgrimm) +Patch 564637 new ep_hash and locking down address list read/writes (jgrimm) +Patch 565087 protect against timer overfiring (jgrimm) +Patch 565935 Collapse ep/asoc hash links into common substructure (jgrimm) +Bug 565868 Ctl-sock (OOTB) traps sending to ipv6 dest. (jgrimm) +Bug 565878 Xmit to wrong peer when no asoc. (jgrimm) +Patch 565686 Update RTO upon Heartbeat ACK. (samudrala) +Patch 567028 Cleanup unneeded atomic_t fields (jgrimm) +Patch 567061 Some sctp-socket-04.txt updates (jgrimm) +Patch 567646 Combine sctp_func_t/sctp_af_specific_t (jgrimm) +Patch 568562 Sysctl support for RFC 2960 variables (jgrimm) +Patch 567514 SCTP_SET_EVENTS sock options (samudrala) +Patch 567492 block/non-block send and SNDBUF/RCVBUF (daisyc) + +lksctp-2_5_15-0_4_10: +Patch 561757 congestion control, handle SACKs indicating renege (samudrala) +Patch 561632 v4 scoping rules (daisyc) +lksctp-2_5_15-0_4_9: +Patch 554705 Locking phase 1 (off the BH, use socklock and backlog) (jgrimm) +Bug 550363 Shutdown handling of CTSN incorrect (jgrimm) +Patch 558565 testframe ipv4 only, doesn't compile (samudrala) +Patch 556572 Fix INADDR_ANY and some IPv4 scoping (daisyc) +Patch 559801 Cleanup old locking stuff and various naming/style (jgrimm) + +lksctp-2_5_15-0_4_8: +Patch 557034 Port to 2.5.15 (samudrala) +Patch 550903 sys_bindx removal (inaky, samudrala) + +lksctp-2_4_18-0_4_8: +Patch 546328 sctp_transport cleanup (jgrimm) +Bug 545852 sk->err cleanup (samudrala) +Bug 547147 association leaks the inqueue->in_progress chunk (jgrimm) +Bug 541065 fix port_rover race conditition in bind path (jgrimm) +Patch 544577 heartbeat ack and failover (dajiang) +NA Make lksctp a module (inaky) +NA bindx over sockopt (inaky) +Patch 547885 Split out v6 code and cleanup module patch (jgrimm) +Patch 544583 ft_frame_hbACK updates (dajiang, huang) +Patch 547340 fix testframe for "run once" (samudrala) +Patch 548772 sctp_lock primitives (jgrimm) +Patch 547319 naming cleanup in statefuns (daisyc) +Patch 549266 sctp_lock unittests (jgrimm) +Patch 548815 Disable fragments option and more tests. (samudrala) +Patch 550400 Add OOTB testcase (daisyc) +Patch 550520 transport & association error thresholds (samudrala) +NA fix ft_frame_init_timer to not conflict with OOTB (jgrimm) +Patch 549356 Small fixes and cleanup of bindx code (inaky) +Patch 549360 bindx through sockopt (inaky) +Patch 551716 Start using sctp_opts field instead of endpoint (jgrimm) +Patch 551657 RTT Measurements and RTO updates (samudrala) +Patch 552084 sctp_endpoint_common (jgrimm) +Patch 553100 Testcase for RTT Measurements (samudrala) +Bug 553329 Sendmsg + INIT CMSG has path which can corrupt assoc (jgrimm) +Patch 553394 Move sctp_association to use endpoint_common (jgrimm) +Patch 553528 rtx and heartbeat failures cleanup (samudrala) +Patch 553844 OOTB packet processing (daisyc) + +lksctp-2_4_18-0_4_7: +Bug 541198 Old-style retval->state races with CMD (jgrimm) +Patch 541820 listen auto-bind support (samudrala) +Patch 543421 Complete removal of retval structs/processing (jgrimm) +Patch 544908 Object Count Debugging facilities (jgrimm) +Patch 544806 Fix inqueue leak of chunks (daisyc) +Patch 544460 Fragmentation/Reassembly support (samudrala) + +lksctp-2_4_18-0_4_6: +Patch 529522 Primary Addr from saddr (jgrimm, daisyc, hui_huang) +Patch 529530 Use skb_copy_datagram_iovec (samudrala) +Patch 529961 sctphdr, PARAM constants in net order (jgrimm) +Patch 529707 Changes to sctp_make_data* interfaces (samudrala) +Patch 531206 Massive linux/sctp.h changes (jgrimm) +Patch NA Eliminate sctp_io.h (jgrimm) +Patch 532575 sctp_opt as a per socket structure (jgrimm) +Patch 532245 Patch to eliminate tcp_func dependency (samudrala) +Patch 533351 Update headers to Socket Extensions 03 draft (jgrimm) +Patch 531647 Initialize MTU from routing information (samudrala) +Patch NA Update csum I-D. (jgrimm) +Patch 529783 Send heartbeats (dajiang, hui_huang) +Bug 529726 SACK response sent to incorrect dest (jgrimm) +Patch NA More cleanup, mostly naming, dead field removal. (jgrimm) +Bug 539452 sk->err should have errno as positive value (jgrimm). + +lksctp-2_4_18-0_4_5: +Bug 513536 association lookup can fail (jgrimm) +NA Unused file/header cleanup (jgrimm) +NA Move sctp_socket() to testframe (jgrimm) +Patch 524687 Stop byteswapping the rcv skb part 1 (daisyc) +Patch 525009 Stop byteswapping the rcv skb part 2 (daisyc) +NA Change CRC32C per Connectathon (jgrimm) +Patch 526505 Change crc code to skip checksum field (jgrimm) +Patch 526177 Incorrect use of skb->end (samudrala) +Patch 526740 Missing bindx support (samudrala) +NA A few sctp_darn fixes (jgrimm) +NA updatelinux_sctp.sh to handle links (loretos) +Patch 513912 Invalid stream verification (daisyc) +Patch 528541 ABORT handling during initiation phase (jgrimm) +Patch 528679 Misc. Cleanup. (jgrimm) +Patch 528611 Fix testframe skb for fraglist support (samudrala) +Patch 526156 SCTP_STATUS sockopt (samudrala) + + +lksctp-2_4_17_0-4_4: + +Patch 515054 INIT retransmission (jgrimm) +Patch 511394 Invalid StreamId tests (daisyc) + README suggestions (baqaqi) +Bug 519410 test_kernel spinlock initialization (sridhar) +Patch 520992 Enable COOKIE-ECHO bundling (jgrimm) +Patch 520627 Fix autobind twice bug (daisyc) +Patch 520755 A couple bugs from Debug Memory Allocations (sridhar) +Patch 521216 Fix bind_addrs_to_raw calling kmalloc(GFP_KERNL) on int. (jgrimm) + +lksctp-2_4_17-0_4_3: +New Update to 2.4.17 (sridhar) +Patch 512680 Frame test bindx for IPv6 (hui) +Patch 510317 Failing testcase for source addr bug (daisyc) + +lksctp-2_4_1-0_4_3: +Patch 511028 New CRC32C (dinakarjb) +Patch 510797 Sendmsg w/associd (jgrimm) +Patch 499262 Testcase for stream negotiation (daisyc) +Bug 473322 Sendmsg insists on msg_name (jgrimm) + + +If you would like to follow the day-to-day development of the SCTP +kernel, refer to: + + http://lists.sourceforge.net/lists/listinfo/lksctp-developers + +Post messages for the developers (including bug reports) to + + lksctp-developers@lists.sourceforge.net + +If you wish to participate in development, please subscribe to the +developers' list, drop a note to lksctp-developers. + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..88c32f1 --- /dev/null +++ b/INSTALL @@ -0,0 +1,92 @@ + HOW TO COMPILE, RUN AND INSTALL + ------------------------------- + +CONTENTS +-------- + +The lksctp-tools package is intended for two audiences. + 1) SCTP application developers + 2) LKSCTP project developers + +For SCTP application developers, this package provides the user-level +C language header files and a library for accessing SCTP specific +application programming interfaces not provided by the standard sockets. + +For LKSCTP project developers, this package provides the functional +and API regression tests. + +For either role, this project provides sample code, utilities, and +tests that one may find useful. + +The below INSTALL directions are provided with in each of these roles. + +NOTE: To build, run and install the lksctp-tools package, your system is +required to be running with linux-2.5.36, or a later version of the +kernel, configured with the Network options "SCTP Configuration" +support enabled. + +______________________________________________________________________ + + +INSTALLATION +------------- +Prerequisite: A Linux kernel with SCTP support. This may come stock with +your distrbution (some day), or you will need to build your own 2.5.36 or +later kernel. + +To install/build the lksctp-tools utilities/tests do the following: + +1) Download and install the following binary RPMs from the lksctp sourceforge + website at + http://sourceforge.net/project/showfiles.php?group_id=26529 + * lksctp-tools-x.y.z-1.i386.rpm + * lksctp-tools-x.y.z-devel-1.i386.rpm + * lksctp-tools-x.y.z-doc-1.i386.rpm + + lksctp-tools-x.y.z-1.i386.rpm includes + * SCTP run-time library. + * Sample SCTP applications: sctp_darn and sctp_test. + * withsctp: a tool when used with existing TCP binaries replaces TCP + with SCTP. + + lksctp-tools-x.y.z-devel-1.i386.rpm includes + * SCTP header file /usr/include/netinet/sctp.h + * SCTP man pages. + * Source code for sample SCTP applications. + + lksctp-tools-x.y.z-doc-1.i386.rpm includes + * SCTP RFC's and internet drafts. + + If you want to run and play with the included sample SCTP applications or + develop your own SCTP applications, you can skip the rest of the + instructions. + + If you are interested in running the functional regression tests included + in the lksctp-tools package, continue with the following instructions. + +2) Download and install the following source RPM form the lksctp sourceforge + website at + http://sourceforge.net/project/showfiles.php?group_id=26529 + * lksctp-tools-x.y.z-1.src.rpm + This will install the lksctp-tools gzipped tarball and RPM spec file. + +3) Untar the lksctp-tools directory from the gzipped tarball. This creates a + subdirectory called lksctp-tools-x.y.z. + + Ensure you have autoconf, automake and libtool packages installed on your + system. + +4) Run ./bootstrap + +5) Run ./configure + +6) Run make + +7) To run the SCTP kernel regression tests, + + $ cd src/func_tests + $ make v4test (regression tests for the IPv4 socket support) + $ make v6test (regression tests for the IPv6 socket support) + +8) Run other SCTP test tools/applications in src/apps directory to verify the + running SCTP. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..109f01d --- /dev/null +++ b/Makefile.am @@ -0,0 +1,20 @@ +include $(top_srcdir)/Makefile.vars +include $(top_srcdir)/Makefile.rules + +DISTCLEANFILES += config.h stamp-h libtool +MAINTAINERCLEANFILES += aclocal.m4 config.h.in configure stamp-h.in \ + config.h stamp-h + +EXTRA_DIST += ChangeLog AUTHORS COPYING COPYING.lib INSTALL \ + README ROADMAP NEWS \ + Makefile.vars Makefile.rules Makefile.dirs + +# bin or src products may be required to generate stuff in test/ +SUBDIRS = man bin src doc + +# Libtool support +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +libtool: $(LIBTOOL_DEPS) + $(SHELL) ./config.status --recheck + +## FIXME: Your stuff here diff --git a/Makefile.dirs b/Makefile.dirs new file mode 100644 index 0000000..f376712 --- /dev/null +++ b/Makefile.dirs @@ -0,0 +1,60 @@ +# -*-makefile-*- +# +# Define here directories you want + +rootbindir = /bin +rootsbindir = /sbin +rootlibdir = /lib + +localedir = $(datadir)/locale +pkgsysconfdir = $(sysconfdir)/@PACKAGE@ +pkgdocdir = $(datadir)/@PACKAGE@ + +vpkgsysconfdir = $(pkgsysconfdir)/v@VERSION@ +vpkgdatadir = $(pkgdatadir)/v@VERSION@ +vpkglibdir = $(pkglibdir)/v@VERSION@ +vpkgdocdir = $(docdir)/v@VERSION@ + +# List here all the directories you want listed in the file to be used +# in your programs: + +directories := \ + localedir \ + pkgsysconfdir \ + rootbindir \ + rootlibdir \ + rootsbindir \ + vpkgdatadir \ + vpkgdocdir \ + vpkglibdir \ + vpkgsysconfdir \ + \ + bindir \ + datadir \ + libdir \ + pkgdatadir \ + pkgdocdir \ + pkglibdir \ + sbindir + +# To modify this target for another language, just copy, paste and +# modify the target to generate directories.h. We depend on +# config.status and Makefile.dirs, as anything changed is going to be +# reflected there. + +# This is for generating the list in C/C++ +directories.h: $(top_builddir)/config.status $(top_srcdir)/Makefile.dirs + @rm -f $@ + @echo -n "Creating $@ ..." + @echo "#ifndef __$(subst .,_,$@)__" > $@ + @echo "# define __$(subst .,_,$@)__" >> $@ + @echo "" >> $@ + @echo -e $(foreach v,$(directories),$(shell echo 'D_$(v) \"$($v)\"\\n')) \ + | sed 's/^ *D_/# define D_/' >> $@ + @echo "#endif" >> $@ + @echo " done" + +DISTCLEANFILES += directories.h +MAINTAINERCLEANFILES += directories.h + +## FIXME: Your stuff here diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..7ac440c --- /dev/null +++ b/Makefile.in @@ -0,0 +1,661 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*-makefile-*- +# +# type: deep, strictness: gnu +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = . +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(srcdir)/lksctp-tools.spec.in $(top_srcdir)/Makefile.rules \ + $(top_srcdir)/Makefile.vars $(top_srcdir)/configure AUTHORS \ + COPYING ChangeLog INSTALL NEWS +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno configure.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = lksctp-tools.spec +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ + +# Libtool support +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.h.in configure \ + stamp-h.in config.h stamp-h +DISTCLEANFILES = \\\ config.h stamp-h libtool +CLEANFILES = +MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io +EXTRA_DIST = ChangeLog AUTHORS COPYING COPYING.lib INSTALL README \ + ROADMAP NEWS Makefile.vars Makefile.rules Makefile.dirs +LATEX = @LATEX@ +DVIPS = @DVIPS@ +DVIPDFM = @DVIPDFM@ +ENSCRIPTBIN = @ENSCRIPTBIN@ +PS2PDF = @PS2PDF@ +edit = @sed \ + -e "s|\@bindir\@|$(bindir)|" \ + -e "s|\@libdir\@|$(libdir)|" \ + -e "s|\@PACKAGE\@|$(PACKAGE)|" + + +# bin or src products may be required to generate stuff in test/ +SUBDIRS = man bin src doc +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.vars $(top_srcdir)/Makefile.rules $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ + cd $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + cd $(top_srcdir) && $(AUTOHEADER) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +lksctp-tools.spec: $(top_builddir)/config.status $(srcdir)/lksctp-tools.spec.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + mkdir $(distdir) + $(mkdir_p) $(distdir)/. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(mkdir_p) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ + check-am clean clean-generic clean-libtool clean-recursive \ + ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ + dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-recursive distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + maintainer-clean-recursive mostlyclean mostlyclean-generic \ + mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am uninstall-info-am + + +# -*-makefile-*- +# +# Generate pre-parsed C code. +%.i: %.c + $(COMPILE) -E -c $^ -o $@ + +.PRECIOUS: %.i +%.ci: %.i + -grep -v -e "^#" -e "^ *$$" $^ | indent > $@ + mv -f $@ $^ +libtool: $(LIBTOOL_DEPS) + $(SHELL) ./config.status --recheck +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Makefile.rules b/Makefile.rules new file mode 100644 index 0000000..83f5f0c --- /dev/null +++ b/Makefile.rules @@ -0,0 +1,18 @@ +# -*-makefile-*- +# +# Generate pre-parsed C code. +%.i: %.c + $(COMPILE) -E -c $^ -o $@ + +.PRECIOUS: %.i +%.ci: %.i + -grep -v -e "^#" -e "^ *$$" $^ | indent > $@ + mv -f $@ $^ + + +## FIXME: Your stuff here + +edit = @sed \ + -e "s|\@bindir\@|$(bindir)|" \ + -e "s|\@libdir\@|$(libdir)|" \ + -e "s|\@PACKAGE\@|$(PACKAGE)|" diff --git a/Makefile.vars b/Makefile.vars new file mode 100644 index 0000000..068c29c --- /dev/null +++ b/Makefile.vars @@ -0,0 +1,18 @@ +# -*-makefile-*- +# +# type: deep, strictness: gnu + +MAINTAINERCLEANFILES = Makefile.in +DISTCLEANFILES = \\\#*\\\# Makefile +CLEANFILES = +MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io + +EXTRA_DIST = + +LATEX = @LATEX@ +DVIPS = @DVIPS@ +DVIPDFM = @DVIPDFM@ +ENSCRIPTBIN = @ENSCRIPTBIN@ +PS2PDF = @PS2PDF@ + +## FIXME: Your stuff here diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..62767ee --- /dev/null +++ b/NEWS @@ -0,0 +1,8 @@ + +The Linux Kernel SCTP Reference Implementation release 0.5.0 is included in +Linux 2.5 Kernel release 2.5.34 and up. + +From release 0.6.0 and on, we will adopt the new build and installation +process for lksctp users and developers. Please check the INSTALL and +ROADMAP for more details. + diff --git a/README b/README new file mode 100644 index 0000000..6af164c --- /dev/null +++ b/README @@ -0,0 +1,178 @@ +(C) Copyright 2007 Hewlett-Packard Development Company, L.P. +(C) Copyright IBM Corp. 2001, 2003 +Copyright 2001 Motorola, Cisco, Intel, Nokia, La Monte Yarroll. +Copyright 2002 Nokia, La Monte Yarroll, Intel. + +This is the lksctp-tools package for Linux Kernel SCTP Reference +Implementation. + +This package is intended to supplement the Linux Kernel SCTP +Reference Implementation now available in the Linux kernel source +tree in versions 2.5.36 and following. For more information on LKSCTP +see the below section titled "LKSCTP - Linux Kernel SCTP." + +lksctp-tools +____________ + +The lksctp-tools package is intended for two audiences. + 1) SCTP application developers + 2) LKSCTP project developers + +For SCTP application developers, this package provides the user-level +C language header files and a library for accessing SCTP specific +application programming interfaces not provided by the standard sockets. + +For LKSCTP project developers, this package provides the API +regression and functional tests. Developers should also check +lksctp_tests package that provides low level kernel tests. These +are available from git.kernel.org. + +For either role, this project provides sample code, utilities, and +tests that one may find useful. + + +LKSCTP - Linux Kernel SCTP +__________________________ + +The Linux Kernel SCTP Reference Implementation is free software; you +can redistribute it and/or modify it under the terms of the GNU +General Public License as published by the Free Software Foundation; +either version 2, or (at your option) any later version. For more +information on licensing terms, please see the file COPYING in this +directory. + +SCTP (Stream Control Transmission Protocol) is a message oriented, +reliable transport protocol, with congestion control, support for +transparent multi-homing, and multiple ordered streams of messages. +RFC2960 defines the core protocol. The IETF SIGTRAN Working Group +developed SCTP. The primary architects are Randy Stewart and Qiaobing +Xie. + +The Kernel Reference is first and foremost an exposition of +RFC2960 and related documents. You will find that the comments and +variable names tie closely back to the RFC and Internet Drafts. + +This work was started by a small team of developers at Motorola. +Throughout this document, "we" refers to that team. We intend for the +meaning of "we" to expand to include the whole development community, +all 27 million programmers on the planet. + +The Kernel Reference has loose origins in the SCTP User Space Reference +by Randy Stewart and Qiaobing Xie. + +MANIFEST +-------- +. +|-- bin +|-- doc +|-- man +|-- src + |-- apps + |-- func_tests + |-- include + | `-- netinet + |-- lib + |-- testlib + `-- withsctp + +You may want to check the following files: + +COPYING.lib Licensing terms of libsctp +COPYING Licensing terms of other pieces of the package +ROADMAP A tour around the files in the distribution of SCTP-tools. +INSTALL How to install and run this beast. +ChangeLog What has changed since the last release? + +DESIGN GOALS +------------ + +- A primary design goal is to reflect RFC 2960 as closely as +practical. We have changed many names from the user space reference to +follow the draft as closely as possible. We have also included +extensive quotes from the draft adjacent to the code which implements +them. + +- The other primary design goal is to integrate Linux kernel data +structures and idioms as much as possible. The test framework (in +directory test/) provides many of the functions which would otherwise +come from the kernel. The test frame does use libc features, but the +state machine code should be libc-free. + +- A lesser design goal is to completely describe the actions for each +state transition in an sctp_command_t (see sctp_command.h). This +means that the state functions (sctp_state_fn_t in sctp_sm.h) are NOT +allowed to modify their endpoint, association, or chunk arguments. +This is enforced by const modifiers--please respect the compiler +warnings. All actions must be described in the last argument to the +state function. + +- A byte order convention for dealing with the SCTP chunk headers: +all SCTP chunks, regardless if the chunk is to be sent outbound +to the network or was received inbound from the network, the header portion +of the chunk is ALWAYS created and retained in the NETWORK BYTE ORDER. + +- An error code handling convention is to return negative values internally. +The sk->err field holds a positive valued errno values, so will need our +internal values negated. + +- We are moving toward an XP development model. So far we have +adopted pair-programming, coding-to-test (functional and unit), design +through refactoring, and story-based planning. + +In order to make XP work, it is very important that we have a complete +set of tests for the code. We can not safely refactor major parts of +the code without a way to find the things we break. If you decide to +extend the SCTP Kernel Implementation we ask that you do the following: + + 1) Pick an XP story. Tell lksctp-developers@lists.sourceforge.net + 2) Write a functional test for that XP story. The functional + test defines "DONE" for the story. + 3) Submit the functional test as a patch on SourceForge. + 4) Write unit tests for any new "objects" you define. + 5) Implement your feature. + 6) Submit the feature and the unit tests as a separate + SourceForge patch. + +Look in src/func_tests and in lksctp-tests package for examples of of tests. +Please do not submit code that fails its own tests or any of the unit tests. +If it fails a functional test, please document that with the submission. + +Another XP requirement is to code only what is you need to make the +current test work. Where this means omitting required features, we +have put in prominent BUG comments describing the omitted +functionality. + +FEATURES +-------- +This implementation uses a fairly compact cookie which is isolated in +its own substructure of SCTP_association. We have been moving toward +aggregating data elements which need to travel together to minimize +copying of individual elements in favour of more efficient structure +copies. + +You will find what we believe to be the smallest possible Internet +simulator in the middle of the function test_kernel.c:simulate_internet(). +The simulator makes a few simplifying assumptions... + +MAILING LISTS and WEB SITES +--------------------------- +http://www.sourceforge.net/projects/lksctp + + This is the lksctp project webpage. + +lksctp-developers@lists.sourceforge.net + + This is the discussion list for developers. Join this list if + you are interested in following the day-to-day activities of + the SCTP Kernel Reference Implementation development community. + See subscription directions at: + http://lists.sourceforge.net/lists/listinfo/lksctp-developers + +http://www.sctp.org + + This is Randy Stewart's SCTP web site. + +http://sctp.de + + This is Michael Tuexen's SCTP web site. Michael has collected + dozens of documents related to SCTP. diff --git a/ROADMAP b/ROADMAP new file mode 100644 index 0000000..0a65578 --- /dev/null +++ b/ROADMAP @@ -0,0 +1,45 @@ +TOUR +---- +COPYING.lib Licensing terms of libsctp + +COPYING Licensing terms of other pieces of the package + +README Read this before developing. + +ChangeLog What has changed since the last release? + +AUTHORS Developers name list. + +INSTALL How to build and install this package. + +doc/ All the relevant Internet Drafts and RFC's. + +doc/states.txt This is a detailed state table for SCTP. It makes a + pretty good index for RFC2960 too... + +man/ SCTP man pages + +src/ Implementation of the user space library, include files - + this should go, some day, into glibc - as well as a set + of SCTP test tools and test programs. + +src/apps SCTP test applications. + +src/func_tests SCTP functional tests. + +src/lib Sources for SCTP library libsctp.a. + +src/testlib Sources for SCTP test library libsctputil.a. + +src/include/netinet + Header files needed for user space development. + +bin/ Scripts for lksctp build, installation and execution. + +test/ Testframe functional and unit tests. These tests use a + framework which enables running lksctp code in userspace. + +test/linux/include + This include heirarchy includes special versions of + kernel include files needed by the user-space test + frame. diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..2adf993 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,7514 @@ +# generated automatically by aclocal 1.9.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- + +# serial 52 Debian 1.5.26-1ubuntu1 AC_PROG_LIBTOOL + + +# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) +# ----------------------------------------------------------- +# If this macro is not defined by Autoconf, define it here. +m4_ifdef([AC_PROVIDE_IFELSE], + [], + [m4_define([AC_PROVIDE_IFELSE], + [m4_ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + + +# AC_PROG_LIBTOOL +# --------------- +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX + ])]) +dnl And a similar setup for Fortran 77 support + AC_PROVIDE_IFELSE([AC_PROG_F77], + [AC_LIBTOOL_F77], + [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], + defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) +])])# AC_PROG_LIBTOOL + + +# _AC_PROG_LIBTOOL +# ---------------- +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +])# _AC_PROG_LIBTOOL + + +# AC_LIBTOOL_SETUP +# ---------------- +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.50)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl +AC_LIBTOOL_SYS_MAX_CMD_LEN +AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +AC_LIBTOOL_OBJDIR + +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +_LT_AC_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] + +# Same as above, but do not quote variable references. +[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +AC_CHECK_TOOL(AR, ar, false) +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +_LT_REQUIRED_DARWIN_CHECKS + +AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +AC_ARG_WITH([pic], + [AC_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +AC_LIBTOOL_LANG_C_CONFIG +_LT_AC_TAGCONFIG +])# AC_LIBTOOL_SETUP + + +# _LT_AC_SYS_COMPILER +# ------------------- +AC_DEFUN([_LT_AC_SYS_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_AC_SYS_COMPILER + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +AC_DEFUN([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` +]) + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +AC_DEFUN([_LT_COMPILER_BOILERPLATE], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +AC_DEFUN([_LT_LINKER_BOILERPLATE], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# -------------------------- +# Check for some things on darwin +AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + echo "int foo(void){return 1;}" > conftest.c + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib ${wl}-single_module conftest.c + if test -f libconftest.dylib; then + lt_cv_apple_cc_single_mod=yes + rm -rf libconftest.dylib* + fi + rm conftest.c + fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + case $host_os in + rhapsody* | darwin1.[[0123]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms="~$NMEDIT -s \$output_objdir/\${libname}-symbols.expsym \${lib}" + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil="~$DSYMUTIL \$lib || :" + else + _lt_dsymutil= + fi + ;; + esac +]) + +# _LT_AC_SYS_LIBPATH_AIX +# ---------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_AC_SYS_LIBPATH_AIX + + +# _LT_AC_SHELL_INIT(ARG) +# ---------------------- +AC_DEFUN([_LT_AC_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_AC_SHELL_INIT + + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[_LT_AC_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +])])# _LT_AC_PROG_ECHO_BACKSLASH + + +# _LT_AC_LOCK +# ----------- +AC_DEFUN([_LT_AC_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; + ]) +esac + +need_locks="$enable_libtool_lock" + +])# _LT_AC_LOCK + + +# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], +[AC_REQUIRE([LT_AC_PROG_SED]) +AC_CACHE_CHECK([$1], [$2], + [$2=no + ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $rm conftest* +]) + +if test x"[$]$2" = xyes; then + ifelse([$5], , :, [$5]) +else + ifelse([$6], , :, [$6]) +fi +])# AC_LIBTOOL_COMPILER_OPTION + + +# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ------------------------------------------------------------ +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $rm -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + ifelse([$4], , :, [$4]) +else + ifelse([$5], , :, [$5]) +fi +])# AC_LIBTOOL_LINKER_OPTION + + +# AC_LIBTOOL_SYS_MAX_CMD_LEN +# -------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], +[# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +])# AC_LIBTOOL_SYS_MAX_CMD_LEN + + +# _LT_AC_CHECK_DLFCN +# ------------------ +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h)dnl +])# _LT_AC_CHECK_DLFCN + + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# --------------------------------------------------------------------- +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + + +# AC_LIBTOOL_DLOPEN_SELF +# ---------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + + +# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) +# --------------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler +AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* +]) +])# AC_LIBTOOL_PROG_CC_C_O + + +# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) +# ----------------------------------------- +# Check to see if we can do hard links to lock some files if needed +AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], +[AC_REQUIRE([_LT_AC_LOCK])dnl + +hard_links="nottested" +if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS + + +# AC_LIBTOOL_OBJDIR +# ----------------- +AC_DEFUN([AC_LIBTOOL_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +])# AC_LIBTOOL_OBJDIR + + +# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) +# ---------------------------------------------- +# Check hardcoding attributes. +AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_AC_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ + test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ + test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_AC_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_AC_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_AC_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH + + +# AC_LIBTOOL_SYS_LIB_STRIP +# ------------------------ +AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], +[striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) +fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +])# AC_LIBTOOL_SYS_LIB_STRIP + + +# AC_LIBTOOL_SYS_DYNAMIC_LINKER +# ----------------------------- +# PORTME Fill in your ld.so characteristics +AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +m4_if($1,[],[ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$lt_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e 's/;/ /g'` + else + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`echo $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`echo $lt_search_path_spec` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[[3-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +AC_CACHE_VAL([lt_cv_sys_lib_search_path_spec], +[lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec"]) +sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +AC_CACHE_VAL([lt_cv_sys_lib_dlsearch_path_spec], +[lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec"]) +sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi +])# AC_LIBTOOL_SYS_DYNAMIC_LINKER + + +# _LT_AC_TAGCONFIG +# ---------------- +AC_DEFUN([_LT_AC_TAGCONFIG], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_ARG_WITH([tags], + [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], + [include additional configurations @<:@automatic@:>@])], + [tagnames="$withval"]) + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + AC_MSG_WARN([output file `$ofile' does not exist]) + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) + else + AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) + fi + fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in + "") ;; + *) AC_MSG_ERROR([invalid tag name: $tagname]) + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + AC_MSG_ERROR([tag name \"$tagname\" already exists]) + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_LIBTOOL_LANG_CXX_CONFIG + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + AC_LIBTOOL_LANG_F77_CONFIG + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + AC_LIBTOOL_LANG_GCJ_CONFIG + else + tagname="" + fi + ;; + + RC) + AC_LIBTOOL_LANG_RC_CONFIG + ;; + + *) + AC_MSG_ERROR([Unsupported tag name: $tagname]) + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + AC_MSG_ERROR([unable to update list of available tagged configurations.]) + fi +fi +])# _LT_AC_TAGCONFIG + + +# AC_LIBTOOL_DLOPEN +# ----------------- +# enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], + [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_DLOPEN + + +# AC_LIBTOOL_WIN32_DLL +# -------------------- +# declare package support for building win32 DLLs +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_WIN32_DLL + + +# AC_ENABLE_SHARED([DEFAULT]) +# --------------------------- +# implement the --enable-shared flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([shared], + [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]AC_ENABLE_SHARED_DEFAULT) +])# AC_ENABLE_SHARED + + +# AC_DISABLE_SHARED +# ----------------- +# set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no) +])# AC_DISABLE_SHARED + + +# AC_ENABLE_STATIC([DEFAULT]) +# --------------------------- +# implement the --enable-static flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([static], + [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]AC_ENABLE_STATIC_DEFAULT) +])# AC_ENABLE_STATIC + + +# AC_DISABLE_STATIC +# ----------------- +# set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no) +])# AC_DISABLE_STATIC + + +# AC_ENABLE_FAST_INSTALL([DEFAULT]) +# --------------------------------- +# implement the --enable-fast-install flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([fast-install], + [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) +])# AC_ENABLE_FAST_INSTALL + + +# AC_DISABLE_FAST_INSTALL +# ----------------------- +# set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no) +])# AC_DISABLE_FAST_INSTALL + + +# AC_LIBTOOL_PICMODE([MODE]) +# -------------------------- +# implement the --with-pic flag +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default) +])# AC_LIBTOOL_PICMODE + + +# AC_PROG_EGREP +# ------------- +# This is predefined starting with Autoconf 2.54, so this conditional +# definition can be removed once we require Autoconf 2.54 or later. +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], +[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], + [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi]) + EGREP=$ac_cv_prog_egrep + AC_SUBST([EGREP]) +])]) + + +# AC_PATH_TOOL_PREFIX +# ------------------- +# find a file program which can recognize shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +])# AC_PATH_TOOL_PREFIX + + +# AC_PATH_MAGIC +# ------------- +# find a file program which can recognize a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# AC_PATH_MAGIC + + +# AC_PROG_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no]) +AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown +])# AC_DEPLIBS_CHECK_METHOD + + +# AC_PROG_NM +# ---------- +# find the pathname to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +])# AC_PROG_NM + + +# AC_CHECK_LIBM +# ------------- +# check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +])# AC_CHECK_LIBM + + +# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl convenience library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-convenience to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# it is assumed to be `libltdl'. LIBLTDL will be prefixed with +# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/' +# (note the single quotes!). If your package is not flat and you're not +# using automake, define top_builddir and top_srcdir appropriately in +# the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_CONVENIENCE + + +# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl installable library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-install to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# and an installed libltdl is not found, it is assumed to be `libltdl'. +# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and top_srcdir +# appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, lt_dlinit, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_INSTALLABLE + + +# AC_LIBTOOL_CXX +# -------------- +# enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], +[AC_REQUIRE([_LT_AC_LANG_CXX]) +])# AC_LIBTOOL_CXX + + +# _LT_AC_LANG_CXX +# --------------- +AC_DEFUN([_LT_AC_LANG_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) +])# _LT_AC_LANG_CXX + +# _LT_AC_PROG_CXXCPP +# ------------------ +AC_DEFUN([_LT_AC_PROG_CXXCPP], +[ +AC_REQUIRE([AC_PROG_CXX]) +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +fi +])# _LT_AC_PROG_CXXCPP + +# AC_LIBTOOL_F77 +# -------------- +# enable support for Fortran 77 libraries +AC_DEFUN([AC_LIBTOOL_F77], +[AC_REQUIRE([_LT_AC_LANG_F77]) +])# AC_LIBTOOL_F77 + + +# _LT_AC_LANG_F77 +# --------------- +AC_DEFUN([_LT_AC_LANG_F77], +[AC_REQUIRE([AC_PROG_F77]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) +])# _LT_AC_LANG_F77 + + +# AC_LIBTOOL_GCJ +# -------------- +# enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ], +[AC_REQUIRE([_LT_AC_LANG_GCJ]) +])# AC_LIBTOOL_GCJ + + +# _LT_AC_LANG_GCJ +# --------------- +AC_DEFUN([_LT_AC_LANG_GCJ], +[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) +])# _LT_AC_LANG_GCJ + + +# AC_LIBTOOL_RC +# ------------- +# enable support for Windows resource files +AC_DEFUN([AC_LIBTOOL_RC], +[AC_REQUIRE([LT_AC_PROG_RC]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) +])# AC_LIBTOOL_RC + + +# AC_LIBTOOL_LANG_C_CONFIG +# ------------------------ +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) +AC_DEFUN([_LT_AC_LANG_C_CONFIG], +[lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF + +# Report which library types will actually be built +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_C_CONFIG + + +# AC_LIBTOOL_LANG_CXX_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) +AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], +[AC_LANG_PUSH(C++) +AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Dependencies to place before and after the object being linked: +_LT_AC_TAGVAR(predep_objects, $1)= +_LT_AC_TAGVAR(postdep_objects, $1)= +_LT_AC_TAGVAR(predeps, $1)= +_LT_AC_TAGVAR(postdeps, $1)= +_LT_AC_TAGVAR(compiler_lib_search_path, $1)= +_LT_AC_TAGVAR(compiler_lib_search_dirs, $1)= + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + $as_unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + $as_unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' +else + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + AC_PROG_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +_LT_AC_TAGVAR(ld_shlibs, $1)=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + if test "$GXX" = yes ; then + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_AC_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_AC_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + freebsd-elf*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + ;; + gnu*) + ;; + hpux9*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) ;; + *) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + interix[[3-9]]*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc*) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + m88k*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + osf3*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ + $rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; +esac +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_AC_TAGVAR(GCC, $1)="$GXX" +_LT_AC_TAGVAR(LD, $1)="$LD" + +AC_LIBTOOL_POSTDEP_PREDEP($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +])# AC_LIBTOOL_LANG_CXX_CONFIG + +# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) +# ------------------------------------ +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + # + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + if test "$solaris_use_stlport4" != yes; then + _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) +case " $_LT_AC_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac +])# AC_LIBTOOL_POSTDEP_PREDEP + +# AC_LIBTOOL_LANG_F77_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)]) +AC_DEFUN([_LT_AC_LANG_F77_CONFIG], +[AC_REQUIRE([AC_PROG_F77]) +AC_LANG_PUSH(Fortran 77) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="\ + subroutine t + return + end +" + +# Code to be used in simple link tests +lt_simple_link_test_code="\ + program t + end +" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${F77-"f77"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; +aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +_LT_AC_TAGVAR(GCC, $1)="$G77" +_LT_AC_TAGVAR(LD, $1)="$LD" + +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_F77_CONFIG + + +# AC_LIBTOOL_LANG_GCJ_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)]) +AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG], +[AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${GCJ-"gcj"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds + +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_RESTORE +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_GCJ_CONFIG + + +# AC_LIBTOOL_LANG_RC_CONFIG +# ------------------------- +# Ensure that the configuration vars for the Windows resource compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)]) +AC_DEFUN([_LT_AC_LANG_RC_CONFIG], +[AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${RC-"windres"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_RESTORE +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_RC_CONFIG + + +# AC_LIBTOOL_CONFIG([TAGNAME]) +# ---------------------------- +# If TAGNAME is not passed, then create an initial libtool script +# with a default configuration from the untagged config vars. Otherwise +# add code to config.status for appending the configuration named by +# TAGNAME from the matching tagged config vars. +AC_DEFUN([AC_LIBTOOL_CONFIG], +[# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + _LT_AC_TAGVAR(compiler, $1) \ + _LT_AC_TAGVAR(CC, $1) \ + _LT_AC_TAGVAR(LD, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \ + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \ + _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \ + _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \ + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \ + _LT_AC_TAGVAR(old_archive_cmds, $1) \ + _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \ + _LT_AC_TAGVAR(predep_objects, $1) \ + _LT_AC_TAGVAR(postdep_objects, $1) \ + _LT_AC_TAGVAR(predeps, $1) \ + _LT_AC_TAGVAR(postdeps, $1) \ + _LT_AC_TAGVAR(compiler_lib_search_path, $1) \ + _LT_AC_TAGVAR(compiler_lib_search_dirs, $1) \ + _LT_AC_TAGVAR(archive_cmds, $1) \ + _LT_AC_TAGVAR(archive_expsym_cmds, $1) \ + _LT_AC_TAGVAR(postinstall_cmds, $1) \ + _LT_AC_TAGVAR(postuninstall_cmds, $1) \ + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \ + _LT_AC_TAGVAR(allow_undefined_flag, $1) \ + _LT_AC_TAGVAR(no_undefined_flag, $1) \ + _LT_AC_TAGVAR(export_symbols_cmds, $1) \ + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \ + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \ + _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \ + _LT_AC_TAGVAR(hardcode_automatic, $1) \ + _LT_AC_TAGVAR(module_cmds, $1) \ + _LT_AC_TAGVAR(module_expsym_cmds, $1) \ + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \ + _LT_AC_TAGVAR(fix_srcfile_path, $1) \ + _LT_AC_TAGVAR(exclude_expsyms, $1) \ + _LT_AC_TAGVAR(include_expsyms, $1); do + + case $var in + _LT_AC_TAGVAR(old_archive_cmds, $1) | \ + _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \ + _LT_AC_TAGVAR(archive_cmds, $1) | \ + _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \ + _LT_AC_TAGVAR(module_cmds, $1) | \ + _LT_AC_TAGVAR(module_expsym_cmds, $1) | \ + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \ + _LT_AC_TAGVAR(export_symbols_cmds, $1) | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\[$]0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'` + ;; + esac + +ifelse([$1], [], + [cfgfile="${ofile}T" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + $rm -f "$cfgfile" + AC_MSG_NOTICE([creating $ofile])], + [cfgfile="$ofile"]) + + cat <<__EOF__ >> "$cfgfile" +ifelse([$1], [], +[#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG], +[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) + +# Is the compiler the GNU C compiler? +with_gcc=$_LT_AC_TAGVAR(GCC, $1) + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_[]_LT_AC_TAGVAR(LD, $1) + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) + +# Commands used to build and install a shared archive. +archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) +archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) +module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) + +# The directories searched by this compiler when creating a shared +# library +compiler_lib_search_dirs=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_dirs, $1) + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to yes if exported symbols are required. +always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) + +# The commands to list exported symbols. +export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) + +# Symbols that must always be exported. +include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) + +ifelse([$1],[], +[# ### END LIBTOOL CONFIG], +[# ### END LIBTOOL TAG CONFIG: $tagname]) + +__EOF__ + +ifelse([$1],[], [ + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +]) +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi +])# AC_LIBTOOL_CONFIG + + +# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl + +_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI + + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([LT_AC_PROG_SED]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux* | k*bsd*-gnu) + if test "$host_cpu" = ia64; then + symcode='[[ABCDGIRSTW]]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[[]] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + + +# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) +# --------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], +[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) + ifelse([$1],[CXX],[ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + icpc* | ecpc*) + # Intel C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler. + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + newsos6) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + icc* | ecc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + esac + ;; + esac + ;; + + osf3* | osf4* | osf5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then + AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], + _LT_AC_TAGVAR(lt_cv_prog_compiler_pic_works, $1), + [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\" +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_AC_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) +]) + + +# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) +# ------------------------------------ +# See if the linker supports building shared libraries. +AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +ifelse([$1],[CXX],[ + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + ;; + linux* | k*bsd*-gnu) + _LT_AC_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + _LT_AC_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] +],[ + runpath_var= + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)= + _LT_AC_TAGVAR(archive_expsym_cmds, $1)= + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown + _LT_AC_TAGVAR(hardcode_automatic, $1)=no + _LT_AC_TAGVAR(module_cmds, $1)= + _LT_AC_TAGVAR(module_expsym_cmds, $1)= + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_AC_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_AC_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + _LT_CC_BASENAME([$compiler]) + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + interix[[3-9]]*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | k*bsd*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + *) + tmp_sharedflag='-shared' ;; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=no + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + # see comment about different semantics on the GNU ld section + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + bsdi[[45]]*) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_AC_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_AC_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_AC_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $rm conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac +])# AC_LIBTOOL_PROG_LD_SHLIBS + + +# _LT_AC_FILE_LTDLL_C +# ------------------- +# Be careful that the start marker always follows a newline. +AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ +])# _LT_AC_FILE_LTDLL_C + + +# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) +# --------------------------------- +AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) + + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + +AC_DEFUN([LT_AC_PROG_RC], +[AC_CHECK_TOOL(RC, windres, no) +]) + + +# Cheap backport of AS_EXECUTABLE_P and required macros +# from Autoconf 2.59; we should not use $as_executable_p directly. + +# _AS_TEST_PREPARE +# ---------------- +m4_ifndef([_AS_TEST_PREPARE], +[m4_defun([_AS_TEST_PREPARE], +[if test -x / >/dev/null 2>&1; then + as_executable_p='test -x' +else + as_executable_p='test -f' +fi +])])# _AS_TEST_PREPARE + +# AS_EXECUTABLE_P +# --------------- +# Check whether a file is executable. +m4_ifndef([AS_EXECUTABLE_P], +[m4_defun([AS_EXECUTABLE_P], +[AS_REQUIRE([_AS_TEST_PREPARE])dnl +$as_executable_p $1[]dnl +])])# AS_EXECUTABLE_P + +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if AS_EXECUTABLE_P(["$as_dir/$lt_ac_prog$ac_exec_ext"]); then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +]) + +# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9.6])]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 7 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 3 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. +# +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/bin/Makefile.am b/bin/Makefile.am new file mode 100644 index 0000000..50985cb --- /dev/null +++ b/bin/Makefile.am @@ -0,0 +1,8 @@ + +include $(top_srcdir)/Makefile.vars +include $(top_srcdir)/Makefile.rules + +noinst_SCRIPTS = aaaa + +EXTRA_DIST += $(noinst_SCRIPTS) + diff --git a/bin/Makefile.in b/bin/Makefile.in new file mode 100644 index 0000000..39d7d0f --- /dev/null +++ b/bin/Makefile.in @@ -0,0 +1,357 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*-makefile-*- +# +# type: deep, strictness: gnu + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.rules $(top_srcdir)/Makefile.vars \ + compile config.guess config.sub depcomp install-sh ltmain.sh \ + missing +subdir = bin +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SCRIPTS = $(noinst_SCRIPTS) +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +MAINTAINERCLEANFILES = Makefile.in +DISTCLEANFILES = \\\#*\\\# Makefile +CLEANFILES = +MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io +EXTRA_DIST = $(noinst_SCRIPTS) +LATEX = @LATEX@ +DVIPS = @DVIPS@ +DVIPDFM = @DVIPDFM@ +ENSCRIPTBIN = @ENSCRIPTBIN@ +PS2PDF = @PS2PDF@ +edit = @sed \ + -e "s|\@bindir\@|$(bindir)|" \ + -e "s|\@libdir\@|$(libdir)|" \ + -e "s|\@PACKAGE\@|$(PACKAGE)|" + +noinst_SCRIPTS = aaaa +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.vars $(top_srcdir)/Makefile.rules $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bin/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign bin/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(SCRIPTS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + + +# -*-makefile-*- +# +# Generate pre-parsed C code. +%.i: %.c + $(COMPILE) -E -c $^ -o $@ + +.PRECIOUS: %.i +%.ci: %.i + -grep -v -e "^#" -e "^ *$$" $^ | indent > $@ + mv -f $@ $^ +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/bin/aaaa b/bin/aaaa new file mode 100755 index 0000000..f4982de --- /dev/null +++ b/bin/aaaa @@ -0,0 +1,20 @@ +#! /bin/sh +# +# Run all the stuff we need to generate the configure and Makefile.in +# in the automake process. +# +# The order needs to be that. If autoheader does not run after +# autoconf, it doesn't get all the symbols right. As automake requires +# config.h.in, created by autoheader, it needs to run after it. +# +# $Id: aaaa,v 1.1.1.1 2002/08/06 22:31:05 inaky Exp $ + + +set -ex + +aclocal +autoconf +autoheader +# Set GNU strictness +#automake --foreign +automake --gnu diff --git a/bin/compile b/bin/compile new file mode 100755 index 0000000..1b1d232 --- /dev/null +++ b/bin/compile @@ -0,0 +1,142 @@ +#! /bin/sh +# Wrapper for compilers which do not understand `-c -o'. + +scriptversion=2005-05-14.22 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand `-c -o'. +Remove `-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file `INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; +esac + +ofile= +cfile= +eat= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as `compile cc -o foo foo.c'. + # So we strip `-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no `-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # `.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'` + +# Create the lock directory. +# Note: use `[/.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/bin/config.guess b/bin/config.guess new file mode 100755 index 0000000..278f9e9 --- /dev/null +++ b/bin/config.guess @@ -0,0 +1,1516 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2007-07-22' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa:Linux:*:*) + echo xtensa-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/bin/config.sub b/bin/config.sub new file mode 100755 index 0000000..1761d8b --- /dev/null +++ b/bin/config.sub @@ -0,0 +1,1626 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2007-06-28' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/bin/depcomp b/bin/depcomp new file mode 100755 index 0000000..04701da --- /dev/null +++ b/bin/depcomp @@ -0,0 +1,530 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2005-07-09.11 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mecanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/bin/install-sh b/bin/install-sh new file mode 100755 index 0000000..4d4a951 --- /dev/null +++ b/bin/install-sh @@ -0,0 +1,323 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-05-14.22 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + shift + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit 1; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit 0 +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/bin/ltmain.sh b/bin/ltmain.sh new file mode 100644 index 0000000..e420fac --- /dev/null +++ b/bin/ltmain.sh @@ -0,0 +1,6964 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +basename="s,^.*/,,g" + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +progname=`echo "$progpath" | $SED $basename` +modename="$progname" + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION="1.5.26 Debian 1.5.26-1ubuntu1" +TIMESTAMP=" (1.1220.2.493 2008/02/01 16:58:18)" + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +duplicate_deps=no +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +##################################### +# Shell function definitions: +# This seems to be the best place for them + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $mkdir "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || { + $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2 + exit $EXIT_FAILURE + } + fi + + $echo "X$my_tmpdir" | $Xsed +} + + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ + $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | \ + $SED -n -e '1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $echo $win32_libid_type +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case "$@ " in + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit $EXIT_FAILURE +# else +# $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + + $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" + $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 + exit $EXIT_FAILURE + fi +} + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + my_status="" + + $show "${rm}r $my_gentop" + $run ${rm}r "$my_gentop" + $show "$mkdir $my_gentop" + $run $mkdir "$my_gentop" + my_status=$? + if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then + exit $my_status + fi + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + extracted_serial=`expr $extracted_serial + 1` + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + $show "${rm}r $my_xdir" + $run ${rm}r "$my_xdir" + $show "$mkdir $my_xdir" + $run $mkdir "$my_xdir" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then + exit $exit_status + fi + case $host in + *-darwin*) + $show "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + if test -z "$run"; then + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` + darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` + if test -n "$darwin_arches"; then + darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + $show "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we have a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + lipo -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + ${rm}r unfat-$$ + cd "$darwin_orig_dir" + else + cd "$darwin_orig_dir" + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + fi # $run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + func_extract_archives_result="$my_oldobjs" +} +# End of Shell function definitions +##################################### + +# Darwin sucks +eval std_shrext=\"$shrext_cmds\" + +disable_libs=no + +# Parse our command line options once, thoroughly. +while test "$#" -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + tag) + tagname="$arg" + preserve_args="${preserve_args}=$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + $echo "$progname: invalid tag name: $tagname" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + ;; + *) + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" + else + $echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + echo "\ +$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP + +Copyright (C) 2008 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + exit $? + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath + # Now print the configurations for the tags. + for tagname in $taglist; do + ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" + done + exit $? + ;; + + --debug) + $echo "$progname: enabling shell trace mode" + set -x + preserve_args="$preserve_args $arg" + ;; + + --dry-run | -n) + run=: + ;; + + --features) + $echo "host: $host" + if test "$build_libtool_libs" = yes; then + $echo "enable shared libraries" + else + $echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + $echo "enable static libraries" + else + $echo "disable static libraries" + fi + exit $? + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + preserve_args="$preserve_args $arg" + ;; + + --tag) + prevopt="--tag" + prev=tag + preserve_args="$preserve_args --tag" + ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + preserve_args="$preserve_args --tag" + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE +fi + +case $disable_libs in +no) + ;; +shared) + build_libtool_libs=no + build_old_libs=yes + ;; +static) + build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` + ;; +esac + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 + $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 + case $nonopt in + *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + if test -n "$libobj" ; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit $EXIT_FAILURE + fi + arg_mode=target + continue + ;; + + -static | -prefer-pic | -prefer-non-pic) + later="$later $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + base_compile="$base_compile $lastarg" + continue + ;; + + * ) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + case $lastarg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, and some SunOS ksh mistreat backslash-escaping + # in scan sets (worked around with variable expansion), + # and furthermore cannot handle '|' '&' '(' ')' in scan sets + # at all, so we specify them separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + base_compile="$base_compile $lastarg" + done # for arg + + case $arg_mode in + arg) + $echo "$modename: you must specify an argument for -Xcompile" + exit $EXIT_FAILURE + ;; + target) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit $EXIT_FAILURE + ;; + *) + # Get the name of the library object. + [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSifmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.ii) xform=ii ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.[fF][09]?) xform=[fF][09]. ;; + *.for) xform=for ;; + *.java) xform=java ;; + *.obj) xform=obj ;; + *.sx) xform=sx ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` + case $qlibobj in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qlibobj="\"$qlibobj\"" ;; + esac + test "X$libobj" != "X$qlibobj" \ + && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$progpath" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + $echo "$srcfile" > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` + case $qsrcfile in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qsrcfile="\"$qsrcfile\"" ;; + esac + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit $EXIT_FAILURE + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit $EXIT_FAILURE + fi + arg=$save_arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + darwin_framework|darwin_framework_skip) + test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit $EXIT_FAILURE + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework|-arch|-isysroot) + case " $CC " in + *" ${arg} ${1} "* | *" ${arg} ${1} "*) + prev=darwin_framework_skip ;; + *) compiler_flags="$compiler_flags $arg" + prev=darwin_framework ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + notinst_path="$notinst_path $dir" + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs -framework System" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + -model) + compile_command="$compile_command $arg" + compiler_flags="$compiler_flags $arg" + finalize_command="$finalize_command $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -module) + module=yes + continue + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m* pass through architecture-specific compiler args for GCC + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC + # -F/path gives path to uninstalled frameworks, gcc on darwin + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) + + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d "$output_objdir"; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then + exit $exit_status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + case $host in + *cygwin* | *mingw* | *pw32*) + # don't eliminate duplications in $postdeps and $predeps + duplicate_compiler_generated_deps=yes + ;; + *) + duplicate_compiler_generated_deps=$duplicate_deps + ;; + esac + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if (${SED} -e '2q' $lib | + grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + library_names= + old_library= + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + if eval $echo \"$deplib\" 2>/dev/null \ + | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $echo + $echo "*** Warning: Trying to link with static lib archive $deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because the file extensions .$libext of this argument makes me believe" + $echo "*** that it is just a static archive that I should not used here." + else + $echo + $echo "*** Warning: Linking the shared library $output against the" + $echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test "$found" = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2 + exit $EXIT_FAILURE + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit $EXIT_FAILURE + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $absdir" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes ; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + # This is a shared library + + # Warn about portability, can't link against -module's on + # some systems (darwin) + if test "$shouldnotlink" = yes && test "$pass" = link ; then + $echo + if test "$linkmode" = prog; then + $echo "*** Warning: Linking the executable $output against the loadable module" + else + $echo "*** Warning: Linking the shared library $output against the loadable module" + fi + $echo "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`$echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$extract_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$old_archive_from_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a module then we can not link against + # it, someone is ignoring the new warnings I added + if /usr/bin/file -L $add 2> /dev/null | + $EGREP ": [^:]* bundle" >/dev/null ; then + $echo "** Warning, lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $echo + $echo "** And there doesn't seem to be a static archive available" + $echo "** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit $EXIT_FAILURE + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $echo + $echo "*** Warning: This system can not link to static lib archive $lib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $echo "*** But as you try to build a module library, libtool will still create " + $echo "*** a static module, that should work as long as the dlopening application" + $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="$absdir" + fi + depdepl= + case $host in + *-*-darwin*) + # we do not want to link against static libs, + # but need to link against shared + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + eval deplibdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$deplibdir/$depdepl" ; then + depdepl="$deplibdir/$depdepl" + elif test -f "$path/$depdepl" ; then + depdepl="$path/$depdepl" + else + # Can't find it, oh well... + depdepl= + fi + # do not add paths which are already there + case " $newlib_search_path " in + *" $path "*) ;; + *) newlib_search_path="$newlib_search_path $path";; + esac + fi + path="" + ;; + *) + path="-L$path" + ;; + esac + ;; + -l*) + case $host in + *-*-darwin*) + # Again, we only want to link against shared libraries + eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` + for tmp in $newlib_search_path ; do + if test -f "$tmp/lib$tmp_libs.dylib" ; then + eval depdepl="$tmp/lib$tmp_libs.dylib" + break + fi + done + path="" + ;; + *) continue ;; + esac + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + case " $deplibs " in + *" $depdepl "*) ;; + *) deplibs="$depdepl $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + case " $deplibs" in + *\ -l* | *\ -L*) + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 ;; + esac + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit $EXIT_FAILURE + else + $echo + $echo "*** Warning: Linking the shared library $output against the non-libtool" + $echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test "$#" -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$2" + number_minor="$3" + number_revision="$4" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE + ;; + esac + ;; + no) + current="$2" + revision="$3" + age="$4" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test "$age" -gt "$current"; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + major=`expr $current - $age` + else + major=`expr $current - $age + 1` + fi + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$echo "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"` + # deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"` + # dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for file magic test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name=`expr $a_deplib : '-l\(.*\)'` + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval $echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` + done + fi + if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ + | grep . >/dev/null; then + $echo + if test "X$deplibs_check_method" = "Xnone"; then + $echo "*** Warning: inter-library dependencies are not supported in this platform." + else + $echo "*** Warning: inter-library dependencies are not known to be supported." + fi + $echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $echo + $echo "*** Warning: libtool could not satisfy all declared inter-library" + $echo "*** dependencies of module $libname. Therefore, libtool will create" + $echo "*** a static module, that should work as long as the dlopening" + $echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $echo "*** The inter-library dependencies that have been dropped here will be" + $echo "*** automatically added whenever a program is linked with this library" + $echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $echo + $echo "*** Since this library must not contain undefined symbols," + $echo "*** because either the platform does not support them or" + $echo "*** it was explicitly requested with -no-undefined," + $echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + case $archive_cmds in + *\$LD*) eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" ;; + *) eval dep_rpath=\"$hardcode_libdir_flag_spec\" ;; + esac + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + if len=`expr "X$cmd" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + $show "$cmd" + $run eval "$cmd" || exit $? + skipped_export=false + else + # The command line is too long to execute in one step. + $show "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$echo "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$output_la-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + len=1 + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + if ${skipped_export-false}; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + libobjs=$output + # Append the command to create the export file. + eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" + fi + + # Set up a command to remove the reloadable object files + # after they are used. + i=0 + while test "$i" -lt "$k" + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" + done + + $echo "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~\$rm $delfiles\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + case " $deplibs" in + *\ -l* | *\ -L*) + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 ;; + esac + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit $EXIT_FAILURE + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $run eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + if test "$tagname" = CXX ; then + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + fi + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + else + $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval '$echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + $echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +" + + case $host in + *cygwin* | *mingw* ) + $echo >> "$output_objdir/$dlsyms" "\ +/* DATA imports from DLLs on WIN32 can't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs */ +struct { +" + ;; + * ) + $echo >> "$output_objdir/$dlsyms" "\ +const struct { +" + ;; + esac + + + $echo >> "$output_objdir/$dlsyms" "\ + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + case $host in + *cygwin* | *mingw* ) + if test -f "$output_objdir/${outputname}.def" ; then + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + else + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + fi + ;; + * ) + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + ;; + esac + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + fi + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + exit_status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $exit_status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + output_name=`basename $output` + output_path=`dirname $output` + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $rm $cwrappersource $cwrapper + trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + cat > $cwrappersource <> $cwrappersource<<"EOF" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +/* -DDEBUG is fairly common in CFLAGS. */ +#undef DEBUG +#if defined DEBUGWRAPPER +# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) +#else +# define DEBUG(format, ...) +#endif + +const char *program_name = NULL; + +void * xmalloc (size_t num); +char * xstrdup (const char *string); +const char * base_name (const char *name); +char * find_executable(const char *wrapper); +int check_executable(const char *path); +char * strendzap(char *str, const char *pat); +void lt_fatal (const char *message, ...); + +int +main (int argc, char *argv[]) +{ + char **newargz; + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + DEBUG("(main) argv[0] : %s\n",argv[0]); + DEBUG("(main) program_name : %s\n",program_name); + newargz = XMALLOC(char *, argc+2); +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" + newargz[1] = find_executable(argv[0]); + if (newargz[1] == NULL) + lt_fatal("Couldn't find %s", argv[0]); + DEBUG("(main) found exe at : %s\n",newargz[1]); + /* we know the script has the same name, without the .exe */ + /* so make sure newargz[1] doesn't end in .exe */ + strendzap(newargz[1],".exe"); + for (i = 1; i < argc; i++) + newargz[i+1] = xstrdup(argv[i]); + newargz[argc+1] = NULL; + + for (i=0; i> $cwrappersource <> $cwrappersource <> $cwrappersource <<"EOF" + return 127; +} + +void * +xmalloc (size_t num) +{ + void * p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL +; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char)name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable(const char * path) +{ + struct stat st; + + DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!"); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) && + ( + /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */ +#if defined (S_IXOTH) + ((st.st_mode & S_IXOTH) == S_IXOTH) || +#endif +#if defined (S_IXGRP) + ((st.st_mode & S_IXGRP) == S_IXGRP) || +#endif + ((st.st_mode & S_IXUSR) == S_IXUSR)) + ) + return 1; + else + return 0; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise */ +char * +find_executable (const char* wrapper) +{ + int has_slash = 0; + const char* p; + const char* p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char* concat_name; + + DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char* path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char* q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR(*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + return NULL; +} + +char * +strendzap(char *str, const char *pat) +{ + size_t len, patlen; + + assert(str != NULL); + assert(pat != NULL); + + len = strlen(str); + patlen = strlen(pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp(str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char * mode, + const char * message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} +EOF + # we should really use a build-platform specific compiler + # here, but OTOH, the wrappers (shell script and this C one) + # are only useful if you want to execute the "real" binary. + # Since the "real" binary is built for $host, then this + # wrapper might as well be built for $host, too. + $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource + ;; + esac + $rm $output + trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + $echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit $EXIT_FAILURE + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + $echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \$*\" + exit $EXIT_FAILURE + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + $echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit $EXIT_FAILURE + fi +fi\ +" + chmod +x $output + fi + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "copying selected object files to avoid basename conflicts..." + + if test -z "$gentop"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$gentop"; then + exit $exit_status + fi + fi + + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + counter=`expr $counter + 1` + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + $run ln "$obj" "$gentop/$newobj" || + $run cp "$obj" "$gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + eval cmd=\"$cmd\" + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit $EXIT_SUCCESS + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) prev=$arg ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test "$#" -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP` + else + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit $EXIT_FAILURE + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + cmds=$postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + file=`$echo $file|${SED} 's,.exe$,,'` + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit $EXIT_FAILURE + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir=`func_mktempdir` + file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$old_striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + cmds=$old_postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + cmds=$finish_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit $EXIT_SUCCESS + + $echo "X----------------------------------------------------------------------" | $Xsed + $echo "Libraries have been installed in:" + for libdir in $libdirs; do + $echo " $libdir" + done + $echo + $echo "If you ever happen to want to link against installed libraries" + $echo "in a given directory, LIBDIR, you must either use libtool, and" + $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + $echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + $echo " during execution" + fi + if test -n "$runpath_var"; then + $echo " - add LIBDIR to the \`$runpath_var' environment variable" + $echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $echo + $echo "See any operating system documentation about shared libraries for" + $echo "more information, such as the ld(1) and ld.so(8) manual pages." + $echo "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit $EXIT_FAILURE + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + if test ! -f "$dir/$dlname"; then + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit $EXIT_FAILURE + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit $EXIT_SUCCESS + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + cmds=$postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + cmds=$old_postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + file=`$echo $file|${SED} 's,.exe$,,'` + noexename=`$echo $name|${SED} 's,.exe$,,'` + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$noexename + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit $EXIT_FAILURE +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE. + +Report bugs to ." + exit $EXIT_SUCCESS + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; +esac + +$echo +$echo "Try \`$modename --help' for more information about other modes." + +exit $? + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +disable_libs=shared +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +disable_libs=static +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/bin/missing b/bin/missing new file mode 100755 index 0000000..894e786 --- /dev/null +++ b/bin/missing @@ -0,0 +1,360 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2005-06-08.21 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case "$1" in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..6cb4d5f --- /dev/null +++ b/config.h.in @@ -0,0 +1,183 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the `bzero' function. */ +#undef HAVE_BZERO + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `gethostbyname' function. */ +#undef HAVE_GETHOSTBYNAME + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if your system has a GNU libc compatible `realloc' function, + and to 0 otherwise. */ +#undef HAVE_REALLOC + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the `strtoul' function. */ +#undef HAVE_STRTOUL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if the C compiler supports function prototypes. */ +#undef PROTOTYPES + +/* Define to the type of arg 1 for `select'. */ +#undef SELECT_TYPE_ARG1 + +/* Define to the type of args 2, 3 and 4 for `select'. */ +#undef SELECT_TYPE_ARG234 + +/* Define to the type of arg 5 for `select'. */ +#undef SELECT_TYPE_ARG5 + +/* Define to 1 if the `setvbuf' function takes the buffering type as its + second argument and the buffer pointer as the third, as on System V before + release 3. */ +#undef SETVBUF_REVERSED + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define like PROTOTYPES; this can be used by system headers. */ +#undef __PROTOTYPES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc + +/* Define to rpl_realloc if the replacement function should be used. */ +#undef realloc + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* Define to empty if the keyword `volatile' does not work. Warning: valid + code using `volatile' can become incorrect without. Disable with care. */ +#undef volatile diff --git a/configure b/configure new file mode 100755 index 0000000..c4f2935 --- /dev/null +++ b/configure @@ -0,0 +1,23411 @@ +#! /bin/sh +# From configure.in Revision: 1.1.1.2 . +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +echo=${ECHO-echo} +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + + +tagnames=${tagnames+${tagnames},}CXX + +tagnames=${tagnames+${tagnames},}F77 + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="src/apps/sctp_darn.c" +ac_unique_file="config.h.in" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +CYGPATH_W +PACKAGE +VERSION +ACLOCAL +AUTOCONF +AUTOMAKE +AUTOHEADER +MAKEINFO +install_sh +STRIP +INSTALL_STRIP_PROGRAM +mkdir_p +AWK +SET_MAKE +am__leading_dot +AMTAR +am__tar +am__untar +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +DEPDIR +am__include +am__quote +AMDEP_TRUE +AMDEP_FALSE +AMDEPBACKSLASH +CCDEPMODE +am__fastdepCC_TRUE +am__fastdepCC_FALSE +LN_S +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +SED +GREP +EGREP +ECHO +AR +RANLIB +DSYMUTIL +NMEDIT +CPP +CXX +CXXFLAGS +ac_ct_CXX +CXXDEPMODE +am__fastdepCXX_TRUE +am__fastdepCXX_FALSE +CXXCPP +F77 +FFLAGS +ac_ct_F77 +LIBTOOL +LIBTOOL_DEPS +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +CXX +CXXFLAGS +CCC +CXXCPP +F77 +FFLAGS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-tags[=TAGS] include additional configurations [automatic] + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CXXCPP C++ preprocessor + F77 Fortran 77 compiler command + FFLAGS Fortran 77 compiler flags + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_aux_dir= +for ac_dir in bin "$srcdir"/bin; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in bin \"$srcdir\"/bin" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in bin \"$srcdir\"/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +am__api_version="1.9" +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm -f conftest.sed + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=lksctp-tools + VERSION=1.0.10 + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +install_sh=${install_sh-"$am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + + +ac_config_headers="$ac_config_headers config.h" + + + + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$AWK" && break +done + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +{ echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + + +if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + + +depcc="$CC" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ echo "$as_me:$LINENO: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6; } +fi + + +{ echo "$as_me:$LINENO: checking for library containing strerror" >&5 +echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6; } +if test "${ac_cv_search_strerror+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char strerror (); +int +main () +{ +return strerror (); + ; + return 0; +} +_ACEOF +for ac_lib in '' cposix; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_strerror=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_strerror+set}" = set; then + break +fi +done +if test "${ac_cv_search_strerror+set}" = set; then + : +else + ac_cv_search_strerror=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5 +echo "${ECHO_T}$ac_cv_search_strerror" >&6; } +ac_res=$ac_cv_search_strerror +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + + + +# Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + +# Check whether --enable-static was given. +if test "${enable_static+set}" = set; then + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + +# Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6; } +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6; } +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 +echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6; } +if test "${lt_cv_path_SED+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$lt_ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$lt_ac_prog$ac_exec_ext"; }; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done + +fi + +SED=$lt_cv_path_SED + +{ echo "$as_me:$LINENO: result: $SED" >&5 +echo "${ECHO_T}$SED" >&6; } + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; } +else + { echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; } +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +echo "${ECHO_T}$LD" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; } +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + +{ echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 +echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6; } +if test "${lt_cv_ld_reload_flag+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 +echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + +{ echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 +echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6; } +if test "${lt_cv_path_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi +fi +{ echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 +echo "${ECHO_T}$lt_cv_path_NM" >&6; } +NM="$lt_cv_path_NM" + +{ echo "$as_me:$LINENO: checking how to recognize dependent libraries" >&5 +echo $ECHO_N "checking how to recognize dependent libraries... $ECHO_C" >&6; } +if test "${lt_cv_deplibs_check_method+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 +echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6; } +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 4502 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 +echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6; } +if test "${lt_cv_cc_needs_belf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + lt_cv_cc_needs_belf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + lt_cv_cc_needs_belf=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 +echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + + +esac + +need_locks="$enable_libtool_lock" + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in dlfcn.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXXFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + + +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 +echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; } +if test -z "$CXXCPP"; then + if test "${ac_cv_prog_CXXCPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ echo "$as_me:$LINENO: result: $CXXCPP" >&5 +echo "${ECHO_T}$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +fi + + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$F77"; then + ac_cv_prog_F77="$F77" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_F77="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +F77=$ac_cv_prog_F77 +if test -n "$F77"; then + { echo "$as_me:$LINENO: result: $F77" >&5 +echo "${ECHO_T}$F77" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$F77" && break + done +fi +if test -z "$F77"; then + ac_ct_F77=$F77 + for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_F77"; then + ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_F77="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_F77=$ac_cv_prog_ac_ct_F77 +if test -n "$ac_ct_F77"; then + { echo "$as_me:$LINENO: result: $ac_ct_F77" >&5 +echo "${ECHO_T}$ac_ct_F77" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_F77" && break +done + + if test "x$ac_ct_F77" = x; then + F77="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + F77=$ac_ct_F77 + fi +fi + + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for Fortran 77 compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +rm -f a.out + +# If we don't use `.F' as extension, the preprocessor is not run on the +# input file. (Note that this only needs to work for GNU compilers.) +ac_save_ext=$ac_ext +ac_ext=F +{ echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6; } +if test "${ac_cv_f77_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF + program main +#ifndef __GNUC__ + choke me +#endif + + end +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_f77_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_f77_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6; } +ac_ext=$ac_save_ext +ac_test_FFLAGS=${FFLAGS+set} +ac_save_FFLAGS=$FFLAGS +FFLAGS= +{ echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5 +echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_f77_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + FFLAGS=-g +cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_f77_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_f77_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_prog_f77_g=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5 +echo "${ECHO_T}$ac_cv_prog_f77_g" >&6; } +if test "$ac_test_FFLAGS" = set; then + FFLAGS=$ac_save_FFLAGS +elif test $ac_cv_prog_f77_g = yes; then + if test "x$ac_cv_f77_compiler_gnu" = xyes; then + FFLAGS="-g -O2" + else + FFLAGS="-g" + fi +else + if test "x$ac_cv_f77_compiler_gnu" = xyes; then + FFLAGS="-O2" + else + FFLAGS= + fi +fi + +G77=`test $ac_compiler_gnu = yes && echo yes` +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +# find the maximum length of command line arguments +{ echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 +echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6; } +if test "${lt_cv_sys_max_cmd_len+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 +echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6; } +else + { echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6; } +fi + + + + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 +echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6; } +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux* | k*bsd*-gnu) + if test "$host_cpu" = ia64; then + symcode='[ABCDGIRSTW]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { echo "$as_me:$LINENO: result: failed" >&5 +echo "${ECHO_T}failed" >&6; } +else + { echo "$as_me:$LINENO: result: ok" >&5 +echo "${ECHO_T}ok" >&6; } +fi + +{ echo "$as_me:$LINENO: checking for objdir" >&5 +echo $ECHO_N "checking for objdir... $ECHO_C" >&6; } +if test "${lt_cv_objdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 +echo "${ECHO_T}$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { echo "$as_me:$LINENO: result: $AR" >&5 +echo "${ECHO_T}$AR" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 +echo "${ECHO_T}$ac_ct_AR" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 +echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { echo "$as_me:$LINENO: checking for file" >&5 +echo $ECHO_N "checking for file... $ECHO_C" >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_DSYMUTIL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { echo "$as_me:$LINENO: result: $DSYMUTIL" >&5 +echo "${ECHO_T}$DSYMUTIL" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { echo "$as_me:$LINENO: result: $ac_ct_DSYMUTIL" >&5 +echo "${ECHO_T}$ac_ct_DSYMUTIL" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_NMEDIT+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { echo "$as_me:$LINENO: result: $NMEDIT" >&5 +echo "${ECHO_T}$NMEDIT" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { echo "$as_me:$LINENO: result: $ac_ct_NMEDIT" >&5 +echo "${ECHO_T}$ac_ct_NMEDIT" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + + { echo "$as_me:$LINENO: checking for -single_module linker flag" >&5 +echo $ECHO_N "checking for -single_module linker flag... $ECHO_C" >&6; } +if test "${lt_cv_apple_cc_single_mod+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + echo "int foo(void){return 1;}" > conftest.c + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib ${wl}-single_module conftest.c + if test -f libconftest.dylib; then + lt_cv_apple_cc_single_mod=yes + rm -rf libconftest.dylib* + fi + rm conftest.c + fi +fi +{ echo "$as_me:$LINENO: result: $lt_cv_apple_cc_single_mod" >&5 +echo "${ECHO_T}$lt_cv_apple_cc_single_mod" >&6; } + { echo "$as_me:$LINENO: checking for -exported_symbols_list linker flag" >&5 +echo $ECHO_N "checking for -exported_symbols_list linker flag... $ECHO_C" >&6; } +if test "${lt_cv_ld_exported_symbols_list+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + lt_cv_ld_exported_symbols_list=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + lt_cv_ld_exported_symbols_list=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_ld_exported_symbols_list" >&5 +echo "${ECHO_T}$lt_cv_ld_exported_symbols_list" >&6; } + case $host_os in + rhapsody* | darwin1.[0123]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms="~$NMEDIT -s \$output_objdir/\${libname}-symbols.expsym \${lib}" + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil="~$DSYMUTIL \$lib || :" + else + _lt_dsymutil= + fi + ;; + esac + + +enable_dlopen=yes +enable_win32_dll=no + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm -r conftest* + + + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + +{ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:7555: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:7559: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + +lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic='-qnocommon' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + esac + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic" >&6; } + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + +{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_pic_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:7845: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:7849: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_static_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $rm -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + +{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:7949: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:7953: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6; } + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6; } + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } + + runpath_var= + allow_undefined_flag= + enable_shared_with_static_runtimes=no + archive_cmds= + archive_expsym_cmds= + old_archive_From_new_cmds= + old_archive_from_expsyms_cmds= + export_dynamic_flag_spec= + whole_archive_flag_spec= + thread_safe_flag_spec= + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_direct=no + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + link_all_deplibs=unknown + hardcode_automatic=no + module_cmds= + module_expsym_cmds= + always_export_symbols=no + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | k*bsd*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + *) + tmp_sharedflag='-shared' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + link_all_deplibs=no + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + whole_archive_flag_spec='' + link_all_deplibs=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' + module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + hardcode_direct=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld='-rpath $libdir' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $ld_shlibs" >&5 +echo "${ECHO_T}$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } + $rm conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc=no + else + archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + { echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 +echo "${ECHO_T}$archive_cmds_need_lc" >&6; } + ;; + esac + fi + ;; +esac + +{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$lt_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e 's/;/ /g'` + else + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`echo $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`echo $lt_search_path_spec` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec" +fi + +sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec" +fi + +sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var" || \ + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ echo "$as_me:$LINENO: result: $hardcode_action" >&5 +echo "${ECHO_T}$hardcode_action" >&6; } + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +striplib= +old_striplib= +{ echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 +echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + ;; + *) + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + ;; + esac +fi + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dl_dlopen=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + { echo "$as_me:$LINENO: checking for shl_load" >&5 +echo $ECHO_N "checking for shl_load... $ECHO_C" >&6; } +if test "${ac_cv_func_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case declares shl_load. + For example, HP-UX 11i declares gettimeofday. */ +#define shl_load innocuous_shl_load + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef shl_load + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_shl_load || defined __stub___shl_load +choke me +#endif + +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_shl_load=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +echo "${ECHO_T}$ac_cv_func_shl_load" >&6; } +if test $ac_cv_func_shl_load = yes; then + lt_cv_dlopen="shl_load" +else + { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; } +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dld_shl_load=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; } +if test $ac_cv_lib_dld_shl_load = yes; then + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + { echo "$as_me:$LINENO: checking for dlopen" >&5 +echo $ECHO_N "checking for dlopen... $ECHO_C" >&6; } +if test "${ac_cv_func_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define dlopen to an innocuous variant, in case declares dlopen. + For example, HP-UX 11i declares gettimeofday. */ +#define dlopen innocuous_dlopen + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char dlopen (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef dlopen + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_dlopen || defined __stub___dlopen +choke me +#endif + +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_dlopen=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 +echo "${ECHO_T}$ac_cv_func_dlopen" >&6; } +if test $ac_cv_func_dlopen = yes; then + lt_cv_dlopen="dlopen" +else + { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dl_dlopen=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 +echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6; } +if test "${ac_cv_lib_svld_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_svld_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_svld_dlopen=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6; } +if test $ac_cv_lib_svld_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 +echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6; } +if test "${ac_cv_lib_dld_dld_link+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dld_dld_link=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dld_dld_link=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; } +if test $ac_cv_lib_dld_dld_link = yes; then + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 +echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6; } +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 +echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6; } +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + +# Report which library types will actually be built +{ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6; } + +{ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; } +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +{ echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6; } + +{ echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; } +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +{ echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6; } + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler \ + CC \ + LD \ + lt_prog_compiler_wl \ + lt_prog_compiler_pic \ + lt_prog_compiler_static \ + lt_prog_compiler_no_builtin_flag \ + export_dynamic_flag_spec \ + thread_safe_flag_spec \ + whole_archive_flag_spec \ + enable_shared_with_static_runtimes \ + old_archive_cmds \ + old_archive_from_new_cmds \ + predep_objects \ + postdep_objects \ + predeps \ + postdeps \ + compiler_lib_search_path \ + compiler_lib_search_dirs \ + archive_cmds \ + archive_expsym_cmds \ + postinstall_cmds \ + postuninstall_cmds \ + old_archive_from_expsyms_cmds \ + allow_undefined_flag \ + no_undefined_flag \ + export_symbols_cmds \ + hardcode_libdir_flag_spec \ + hardcode_libdir_flag_spec_ld \ + hardcode_libdir_separator \ + hardcode_automatic \ + module_cmds \ + module_expsym_cmds \ + lt_cv_prog_compiler_c_o \ + fix_srcfile_path \ + exclude_expsyms \ + include_expsyms; do + + case $var in + old_archive_cmds | \ + old_archive_from_new_cmds | \ + archive_cmds | \ + archive_expsym_cmds | \ + module_cmds | \ + module_expsym_cmds | \ + old_archive_from_expsyms_cmds | \ + export_symbols_cmds | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="${ofile}T" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + $rm -f "$cfgfile" + { echo "$as_me:$LINENO: creating $ofile" >&5 +echo "$as_me: creating $ofile" >&6;} + + cat <<__EOF__ >> "$cfgfile" +#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps + +# The directories searched by this compiler when creating a shared +# library +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + +# Check whether --with-tags was given. +if test "${with_tags+set}" = set; then + withval=$with_tags; tagnames="$withval" +fi + + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5 +echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;} + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5 +echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;} + else + { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5 +echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;} + fi + fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in + "") ;; + *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5 +echo "$as_me: error: invalid tag name: $tagname" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5 +echo "$as_me: error: tag name \"$tagname\" already exists" >&2;} + { (exit 1); exit 1; }; } + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= +compiler_lib_search_dirs_CXX= + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm -r conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + $as_unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + $as_unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +compiler_CXX=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' +else + lt_prog_compiler_no_builtin_flag_CXX= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; } +else + { echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; } +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +echo "${ECHO_T}$LD" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; } +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } +ld_shlibs_CXX=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + darwin* | rhapsody*) + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + whole_archive_flag_spec_CXX='' + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + if test "$GXX" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' + module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_CXX=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + ld_shlibs_CXX=no + ;; + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + gnu*) + ;; + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc*) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + else + ld_shlibs_CXX=no + fi + ;; + osf3*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ + $rm $lib.exp' + + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; +esac +{ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +echo "${ECHO_T}$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +GCC_CXX="$GXX" +LD_CXX="$LD" + +cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + # The `*' in the case matches for architectures that use `case' in + # $output_verbose_cmd can trigger glob expansion during the loop + # eval without this substitution. + output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` + + for p in `eval $output_verbose_link_cmd`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" \ + || test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$rm -f confest.$objext + +compiler_lib_search_dirs_CXX= +if test -n "$compiler_lib_search_path_CXX"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + # + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + +lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + +{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_CXX='-qnocommon' + lt_prog_compiler_wl_CXX='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + icpc* | ecpc*) + # Intel C++ + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6; } + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + +{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:12827: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:12831: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $rm -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + +{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:12931: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:12935: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6; } + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6; } + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw*) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + ;; + linux* | k*bsd*-gnu) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + +{ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +echo "${ECHO_T}$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } + $rm conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_CXX=no + else + archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6; } + ;; + esac + fi + ;; +esac + +{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" + +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec" +fi + +sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec" +fi + +sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || \ + test -n "$runpath_var_CXX" || \ + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5 +echo "${ECHO_T}$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_CXX \ + CC_CXX \ + LD_CXX \ + lt_prog_compiler_wl_CXX \ + lt_prog_compiler_pic_CXX \ + lt_prog_compiler_static_CXX \ + lt_prog_compiler_no_builtin_flag_CXX \ + export_dynamic_flag_spec_CXX \ + thread_safe_flag_spec_CXX \ + whole_archive_flag_spec_CXX \ + enable_shared_with_static_runtimes_CXX \ + old_archive_cmds_CXX \ + old_archive_from_new_cmds_CXX \ + predep_objects_CXX \ + postdep_objects_CXX \ + predeps_CXX \ + postdeps_CXX \ + compiler_lib_search_path_CXX \ + compiler_lib_search_dirs_CXX \ + archive_cmds_CXX \ + archive_expsym_cmds_CXX \ + postinstall_cmds_CXX \ + postuninstall_cmds_CXX \ + old_archive_from_expsyms_cmds_CXX \ + allow_undefined_flag_CXX \ + no_undefined_flag_CXX \ + export_symbols_cmds_CXX \ + hardcode_libdir_flag_spec_CXX \ + hardcode_libdir_flag_spec_ld_CXX \ + hardcode_libdir_separator_CXX \ + hardcode_automatic_CXX \ + module_cmds_CXX \ + module_expsym_cmds_CXX \ + lt_cv_prog_compiler_c_o_CXX \ + fix_srcfile_path_CXX \ + exclude_expsyms_CXX \ + include_expsyms_CXX; do + + case $var in + old_archive_cmds_CXX | \ + old_archive_from_new_cmds_CXX | \ + archive_cmds_CXX | \ + archive_expsym_cmds_CXX | \ + module_cmds_CXX | \ + module_expsym_cmds_CXX | \ + old_archive_from_expsyms_cmds_CXX | \ + export_symbols_cmds_CXX | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_CXX + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_CXX +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects_CXX + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects_CXX + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_CXX + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_CXX + +# The directories searched by this compiler when creating a shared +# library +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld + + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu + + +archive_cmds_need_lc_F77=no +allow_undefined_flag_F77= +always_export_symbols_F77=no +archive_expsym_cmds_F77= +export_dynamic_flag_spec_F77= +hardcode_direct_F77=no +hardcode_libdir_flag_spec_F77= +hardcode_libdir_flag_spec_ld_F77= +hardcode_libdir_separator_F77= +hardcode_minus_L_F77=no +hardcode_automatic_F77=no +module_cmds_F77= +module_expsym_cmds_F77= +link_all_deplibs_F77=unknown +old_archive_cmds_F77=$old_archive_cmds +no_undefined_flag_F77= +whole_archive_flag_spec_F77= +enable_shared_with_static_runtimes_F77=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +objext_F77=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="\ + subroutine t + return + end +" + +# Code to be used in simple link tests +lt_simple_link_test_code="\ + program t + end +" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm -r conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${F77-"f77"} +compiler=$CC +compiler_F77=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +{ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6; } + +{ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; } +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; +aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +{ echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6; } + +{ echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; } +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +{ echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6; } + +GCC_F77="$G77" +LD_F77="$LD" + +lt_prog_compiler_wl_F77= +lt_prog_compiler_pic_F77= +lt_prog_compiler_static_F77= + +{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } + + if test "$GCC" = yes; then + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_static_F77='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_F77='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_F77='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_F77='-fno-common' + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared_F77=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_F77=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_F77='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic_F77='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl_F77='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_F77='-Bstatic' + else + lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_F77='-qnocommon' + lt_prog_compiler_wl_F77='-Wl,' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_F77='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl_F77='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_F77='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static_F77='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl_F77='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static_F77='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-fpic' + lt_prog_compiler_static_F77='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl_F77='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static_F77='-non_shared' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + lt_prog_compiler_wl_F77='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + lt_prog_compiler_wl_F77='' + ;; + esac + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl_F77='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static_F77='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static_F77='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl_F77='-Qoption ld ';; + *) + lt_prog_compiler_wl_F77='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl_F77='-Qoption ld ' + lt_prog_compiler_pic_F77='-PIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic_F77='-Kconform_pic' + lt_prog_compiler_static_F77='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_can_build_shared_F77=no + ;; + + uts4*) + lt_prog_compiler_pic_F77='-pic' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared_F77=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6; } + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_F77"; then + +{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_pic_works_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_pic_works_F77=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_F77" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:14529: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:14533: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_F77=yes + fi + fi + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works_F77" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_pic_works_F77" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_F77" = xyes; then + case $lt_prog_compiler_pic_F77 in + "" | " "*) ;; + *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; + esac +else + lt_prog_compiler_pic_F77= + lt_prog_compiler_can_build_shared_F77=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_F77= + ;; + *) + lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\" +{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_static_works_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_static_works_F77=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_F77=yes + fi + else + lt_cv_prog_compiler_static_works_F77=yes + fi + fi + $rm -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works_F77" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_static_works_F77" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_F77" = xyes; then + : +else + lt_prog_compiler_static_F77= +fi + + +{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_F77=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:14633: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:14637: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_F77=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6; } + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6; } + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } + + runpath_var= + allow_undefined_flag_F77= + enable_shared_with_static_runtimes_F77=no + archive_cmds_F77= + archive_expsym_cmds_F77= + old_archive_From_new_cmds_F77= + old_archive_from_expsyms_cmds_F77= + export_dynamic_flag_spec_F77= + whole_archive_flag_spec_F77= + thread_safe_flag_spec_F77= + hardcode_libdir_flag_spec_F77= + hardcode_libdir_flag_spec_ld_F77= + hardcode_libdir_separator_F77= + hardcode_direct_F77=no + hardcode_minus_L_F77=no + hardcode_shlibpath_var_F77=unsupported + link_all_deplibs_F77=unknown + hardcode_automatic_F77=no + module_cmds_F77= + module_expsym_cmds_F77= + always_export_symbols_F77=no + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms_F77= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms_F77='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs_F77=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_F77='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_F77= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs_F77=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs_F77=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_F77=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_F77=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_F77='-L$libdir' + allow_undefined_flag_F77=unsupported + always_export_symbols_F77=no + enable_shared_with_static_runtimes_F77=yes + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_F77=no + fi + ;; + + interix[3-9]*) + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | k*bsd*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec_F77='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + *) + tmp_sharedflag='-shared' ;; + esac + archive_cmds_F77='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + link_all_deplibs_F77=no + else + ld_shlibs_F77=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs_F77=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_F77=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + esac + + if test "$ld_shlibs_F77" = no; then + runpath_var= + hardcode_libdir_flag_spec_F77= + export_dynamic_flag_spec_F77= + whole_archive_flag_spec_F77= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag_F77=unsupported + always_export_symbols_F77=yes + archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L_F77=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct_F77=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_F77='' + hardcode_direct_F77=yes + hardcode_libdir_separator_F77=':' + link_all_deplibs_F77=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_F77=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_F77=yes + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_libdir_separator_F77= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_F77=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_F77='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_f77_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_F77="-z nodefs" + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_f77_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_F77=' ${wl}-bernotok' + allow_undefined_flag_F77=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_F77='$convenience' + archive_cmds_need_lc_F77=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + # see comment about different semantics on the GNU ld section + ld_shlibs_F77=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec_F77=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_F77=' ' + allow_undefined_flag_F77=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds_F77='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds_F77='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path_F77='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes_F77=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_F77='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_F77=no + hardcode_direct_F77=no + hardcode_automatic_F77=yes + hardcode_shlibpath_var_F77=unsupported + whole_archive_flag_spec_F77='' + link_all_deplibs_F77=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_F77="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_F77="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_F77="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_F77="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' + module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_F77=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_shlibpath_var_F77=no + ;; + + freebsd1*) + ld_shlibs_F77=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes + hardcode_minus_L_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + hardcode_direct_F77=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + + hardcode_direct_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_F77='+b $libdir' + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + ;; + *) + hardcode_direct_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld_F77='-rpath $libdir' + fi + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + link_all_deplibs_F77=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + newsos6) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + hardcode_shlibpath_var_F77=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-R$libdir' + ;; + *) + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs_F77=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + allow_undefined_flag_F77=unsupported + archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag_F77=' -expect_unresolved \*' + archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag_F77=' -expect_unresolved \*' + archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec_F77='-rpath $libdir' + fi + hardcode_libdir_separator_F77=: + ;; + + solaris*) + no_undefined_flag_F77=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_shlibpath_var_F77=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec_F77='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs_F77=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_direct_F77=yes + hardcode_minus_L_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds_F77='$CC -r -o $output$reload_objs' + hardcode_direct_F77=no + ;; + motorola) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_F77=no + ;; + + sysv4.3*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_F77=no + export_dynamic_flag_spec_F77='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_F77=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs_F77=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_F77='${wl}-z,text' + archive_cmds_need_lc_F77=no + hardcode_shlibpath_var_F77=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_F77='${wl}-z,text' + allow_undefined_flag_F77='${wl}-z,nodefs' + archive_cmds_need_lc_F77=no + hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_F77=':' + link_all_deplibs_F77=yes + export_dynamic_flag_spec_F77='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_shlibpath_var_F77=no + ;; + + *) + ld_shlibs_F77=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5 +echo "${ECHO_T}$ld_shlibs_F77" >&6; } +test "$ld_shlibs_F77" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_F77" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_F77=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_F77 in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } + $rm conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_F77 + pic_flag=$lt_prog_compiler_pic_F77 + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_F77 + allow_undefined_flag_F77= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_F77=no + else + archive_cmds_need_lc_F77=yes + fi + allow_undefined_flag_F77=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6; } + ;; + esac + fi + ;; +esac + +{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" + +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec" +fi + +sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec" +fi + +sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } +hardcode_action_F77= +if test -n "$hardcode_libdir_flag_spec_F77" || \ + test -n "$runpath_var_F77" || \ + test "X$hardcode_automatic_F77" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_F77" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no && + test "$hardcode_minus_L_F77" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_F77=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_F77=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_F77=unsupported +fi +{ echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5 +echo "${ECHO_T}$hardcode_action_F77" >&6; } + +if test "$hardcode_action_F77" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_F77 \ + CC_F77 \ + LD_F77 \ + lt_prog_compiler_wl_F77 \ + lt_prog_compiler_pic_F77 \ + lt_prog_compiler_static_F77 \ + lt_prog_compiler_no_builtin_flag_F77 \ + export_dynamic_flag_spec_F77 \ + thread_safe_flag_spec_F77 \ + whole_archive_flag_spec_F77 \ + enable_shared_with_static_runtimes_F77 \ + old_archive_cmds_F77 \ + old_archive_from_new_cmds_F77 \ + predep_objects_F77 \ + postdep_objects_F77 \ + predeps_F77 \ + postdeps_F77 \ + compiler_lib_search_path_F77 \ + compiler_lib_search_dirs_F77 \ + archive_cmds_F77 \ + archive_expsym_cmds_F77 \ + postinstall_cmds_F77 \ + postuninstall_cmds_F77 \ + old_archive_from_expsyms_cmds_F77 \ + allow_undefined_flag_F77 \ + no_undefined_flag_F77 \ + export_symbols_cmds_F77 \ + hardcode_libdir_flag_spec_F77 \ + hardcode_libdir_flag_spec_ld_F77 \ + hardcode_libdir_separator_F77 \ + hardcode_automatic_F77 \ + module_cmds_F77 \ + module_expsym_cmds_F77 \ + lt_cv_prog_compiler_c_o_F77 \ + fix_srcfile_path_F77 \ + exclude_expsyms_F77 \ + include_expsyms_F77; do + + case $var in + old_archive_cmds_F77 | \ + old_archive_from_new_cmds_F77 | \ + archive_cmds_F77 | \ + archive_expsym_cmds_F77 | \ + module_cmds_F77 | \ + module_expsym_cmds_F77 | \ + old_archive_from_expsyms_cmds_F77 | \ + export_symbols_cmds_F77 | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_F77 + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_F77 + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_F77 + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_F77 + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_F77 + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_F77 +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_F77 + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77 + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_F77 +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_F77 +archive_expsym_cmds=$lt_archive_expsym_cmds_F77 +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_F77 +module_expsym_cmds=$lt_module_expsym_cmds_F77 + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects_F77 + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects_F77 + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_F77 + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_F77 + +# The directories searched by this compiler when creating a shared +# library +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_F77 + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_F77 + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_F77 + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_F77 + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_F77 + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_F77 + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_F77 + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_F77 + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_F77 + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_F77 + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_F77 + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_F77 + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_F77 + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +objext_GCJ=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm -r conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${GCJ-"gcj"} +compiler=$CC +compiler_GCJ=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +archive_cmds_need_lc_GCJ=no + +old_archive_cmds_GCJ=$old_archive_cmds + + +lt_prog_compiler_no_builtin_flag_GCJ= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin' + + +{ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:16853: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:16857: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions" +else + : +fi + +fi + +lt_prog_compiler_wl_GCJ= +lt_prog_compiler_pic_GCJ= +lt_prog_compiler_static_GCJ= + +{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } + + if test "$GCC" = yes; then + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_static_GCJ='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_GCJ='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_GCJ='-fno-common' + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared_GCJ=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_GCJ=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_GCJ='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic_GCJ='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl_GCJ='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_GCJ='-Bstatic' + else + lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_GCJ='-qnocommon' + lt_prog_compiler_wl_GCJ='-Wl,' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl_GCJ='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_GCJ='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl_GCJ='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-fpic' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl_GCJ='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + lt_prog_compiler_wl_GCJ='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + lt_prog_compiler_wl_GCJ='' + ;; + esac + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl_GCJ='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl_GCJ='-Qoption ld ';; + *) + lt_prog_compiler_wl_GCJ='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl_GCJ='-Qoption ld ' + lt_prog_compiler_pic_GCJ='-PIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic_GCJ='-Kconform_pic' + lt_prog_compiler_static_GCJ='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_can_build_shared_GCJ=no + ;; + + uts4*) + lt_prog_compiler_pic_GCJ='-pic' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared_GCJ=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6; } + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_GCJ"; then + +{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_pic_works_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_pic_works_GCJ=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_GCJ" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:17143: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:17147: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_GCJ=yes + fi + fi + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works_GCJ" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_pic_works_GCJ" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_GCJ" = xyes; then + case $lt_prog_compiler_pic_GCJ in + "" | " "*) ;; + *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;; + esac +else + lt_prog_compiler_pic_GCJ= + lt_prog_compiler_can_build_shared_GCJ=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_GCJ= + ;; + *) + lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\" +{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_static_works_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_static_works_GCJ=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_GCJ=yes + fi + else + lt_cv_prog_compiler_static_works_GCJ=yes + fi + fi + $rm -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works_GCJ" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_static_works_GCJ" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_GCJ" = xyes; then + : +else + lt_prog_compiler_static_GCJ= +fi + + +{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_GCJ=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:17247: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:17251: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_GCJ=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6; } + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6; } + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } + + runpath_var= + allow_undefined_flag_GCJ= + enable_shared_with_static_runtimes_GCJ=no + archive_cmds_GCJ= + archive_expsym_cmds_GCJ= + old_archive_From_new_cmds_GCJ= + old_archive_from_expsyms_cmds_GCJ= + export_dynamic_flag_spec_GCJ= + whole_archive_flag_spec_GCJ= + thread_safe_flag_spec_GCJ= + hardcode_libdir_flag_spec_GCJ= + hardcode_libdir_flag_spec_ld_GCJ= + hardcode_libdir_separator_GCJ= + hardcode_direct_GCJ=no + hardcode_minus_L_GCJ=no + hardcode_shlibpath_var_GCJ=unsupported + link_all_deplibs_GCJ=unknown + hardcode_automatic_GCJ=no + module_cmds_GCJ= + module_expsym_cmds_GCJ= + always_export_symbols_GCJ=no + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms_GCJ= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms_GCJ='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs_GCJ=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_GCJ= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs_GCJ=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs_GCJ=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_GCJ=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_GCJ='-L$libdir' + allow_undefined_flag_GCJ=unsupported + always_export_symbols_GCJ=no + enable_shared_with_static_runtimes_GCJ=yes + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + interix[3-9]*) + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | k*bsd*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec_GCJ='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + *) + tmp_sharedflag='-shared' ;; + esac + archive_cmds_GCJ='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + link_all_deplibs_GCJ=no + else + ld_shlibs_GCJ=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs_GCJ=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_GCJ=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + esac + + if test "$ld_shlibs_GCJ" = no; then + runpath_var= + hardcode_libdir_flag_spec_GCJ= + export_dynamic_flag_spec_GCJ= + whole_archive_flag_spec_GCJ= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag_GCJ=unsupported + always_export_symbols_GCJ=yes + archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L_GCJ=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct_GCJ=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_GCJ='' + hardcode_direct_GCJ=yes + hardcode_libdir_separator_GCJ=':' + link_all_deplibs_GCJ=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_GCJ=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_GCJ=yes + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_libdir_separator_GCJ= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_GCJ=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_GCJ='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_GCJ="-z nodefs" + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_GCJ=' ${wl}-bernotok' + allow_undefined_flag_GCJ=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_GCJ='$convenience' + archive_cmds_need_lc_GCJ=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + # see comment about different semantics on the GNU ld section + ld_shlibs_GCJ=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec_GCJ=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_GCJ=' ' + allow_undefined_flag_GCJ=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds_GCJ='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds_GCJ='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes_GCJ=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_GCJ=no + hardcode_direct_GCJ=no + hardcode_automatic_GCJ=yes + hardcode_shlibpath_var_GCJ=unsupported + whole_archive_flag_spec_GCJ='' + link_all_deplibs_GCJ=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_GCJ="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_GCJ="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_GCJ="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_GCJ="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' + module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_GCJ=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_shlibpath_var_GCJ=no + ;; + + freebsd1*) + ld_shlibs_GCJ=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes + hardcode_minus_L_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + hardcode_direct_GCJ=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + + hardcode_direct_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + ;; + *) + hardcode_direct_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir' + fi + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + link_all_deplibs_GCJ=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + newsos6) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + hardcode_shlibpath_var_GCJ=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + ;; + *) + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs_GCJ=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + allow_undefined_flag_GCJ=unsupported + archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag_GCJ=' -expect_unresolved \*' + archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag_GCJ=' -expect_unresolved \*' + archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec_GCJ='-rpath $libdir' + fi + hardcode_libdir_separator_GCJ=: + ;; + + solaris*) + no_undefined_flag_GCJ=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_shlibpath_var_GCJ=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs_GCJ=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_direct_GCJ=yes + hardcode_minus_L_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds_GCJ='$CC -r -o $output$reload_objs' + hardcode_direct_GCJ=no + ;; + motorola) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_GCJ=no + ;; + + sysv4.3*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_GCJ=no + export_dynamic_flag_spec_GCJ='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_GCJ=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs_GCJ=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_GCJ='${wl}-z,text' + archive_cmds_need_lc_GCJ=no + hardcode_shlibpath_var_GCJ=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_GCJ='${wl}-z,text' + allow_undefined_flag_GCJ='${wl}-z,nodefs' + archive_cmds_need_lc_GCJ=no + hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_GCJ=':' + link_all_deplibs_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_shlibpath_var_GCJ=no + ;; + + *) + ld_shlibs_GCJ=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5 +echo "${ECHO_T}$ld_shlibs_GCJ" >&6; } +test "$ld_shlibs_GCJ" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_GCJ" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_GCJ=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_GCJ in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } + $rm conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_GCJ + pic_flag=$lt_prog_compiler_pic_GCJ + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ + allow_undefined_flag_GCJ= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_GCJ=no + else + archive_cmds_need_lc_GCJ=yes + fi + allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6; } + ;; + esac + fi + ;; +esac + +{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" + +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec" +fi + +sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec" +fi + +sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } +hardcode_action_GCJ= +if test -n "$hardcode_libdir_flag_spec_GCJ" || \ + test -n "$runpath_var_GCJ" || \ + test "X$hardcode_automatic_GCJ" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_GCJ" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no && + test "$hardcode_minus_L_GCJ" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_GCJ=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_GCJ=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_GCJ=unsupported +fi +{ echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5 +echo "${ECHO_T}$hardcode_action_GCJ" >&6; } + +if test "$hardcode_action_GCJ" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_GCJ \ + CC_GCJ \ + LD_GCJ \ + lt_prog_compiler_wl_GCJ \ + lt_prog_compiler_pic_GCJ \ + lt_prog_compiler_static_GCJ \ + lt_prog_compiler_no_builtin_flag_GCJ \ + export_dynamic_flag_spec_GCJ \ + thread_safe_flag_spec_GCJ \ + whole_archive_flag_spec_GCJ \ + enable_shared_with_static_runtimes_GCJ \ + old_archive_cmds_GCJ \ + old_archive_from_new_cmds_GCJ \ + predep_objects_GCJ \ + postdep_objects_GCJ \ + predeps_GCJ \ + postdeps_GCJ \ + compiler_lib_search_path_GCJ \ + compiler_lib_search_dirs_GCJ \ + archive_cmds_GCJ \ + archive_expsym_cmds_GCJ \ + postinstall_cmds_GCJ \ + postuninstall_cmds_GCJ \ + old_archive_from_expsyms_cmds_GCJ \ + allow_undefined_flag_GCJ \ + no_undefined_flag_GCJ \ + export_symbols_cmds_GCJ \ + hardcode_libdir_flag_spec_GCJ \ + hardcode_libdir_flag_spec_ld_GCJ \ + hardcode_libdir_separator_GCJ \ + hardcode_automatic_GCJ \ + module_cmds_GCJ \ + module_expsym_cmds_GCJ \ + lt_cv_prog_compiler_c_o_GCJ \ + fix_srcfile_path_GCJ \ + exclude_expsyms_GCJ \ + include_expsyms_GCJ; do + + case $var in + old_archive_cmds_GCJ | \ + old_archive_from_new_cmds_GCJ | \ + archive_cmds_GCJ | \ + archive_expsym_cmds_GCJ | \ + module_cmds_GCJ | \ + module_expsym_cmds_GCJ | \ + old_archive_from_expsyms_cmds_GCJ | \ + export_symbols_cmds_GCJ | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_GCJ + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_GCJ + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_GCJ + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_GCJ + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_GCJ + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_GCJ +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_GCJ + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_GCJ +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_GCJ +archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_GCJ +module_expsym_cmds=$lt_module_expsym_cmds_GCJ + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects_GCJ + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects_GCJ + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_GCJ + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_GCJ + +# The directories searched by this compiler when creating a shared +# library +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_GCJ + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_GCJ + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_GCJ + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_GCJ + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_GCJ + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_GCJ + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_GCJ + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_GCJ + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_GCJ + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_GCJ + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_GCJ + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_GCJ + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + else + tagname="" + fi + ;; + + RC) + + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +objext_RC=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm -r conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${RC-"windres"} +compiler=$CC +compiler_RC=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + +lt_cv_prog_compiler_c_o_RC=yes + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_RC \ + CC_RC \ + LD_RC \ + lt_prog_compiler_wl_RC \ + lt_prog_compiler_pic_RC \ + lt_prog_compiler_static_RC \ + lt_prog_compiler_no_builtin_flag_RC \ + export_dynamic_flag_spec_RC \ + thread_safe_flag_spec_RC \ + whole_archive_flag_spec_RC \ + enable_shared_with_static_runtimes_RC \ + old_archive_cmds_RC \ + old_archive_from_new_cmds_RC \ + predep_objects_RC \ + postdep_objects_RC \ + predeps_RC \ + postdeps_RC \ + compiler_lib_search_path_RC \ + compiler_lib_search_dirs_RC \ + archive_cmds_RC \ + archive_expsym_cmds_RC \ + postinstall_cmds_RC \ + postuninstall_cmds_RC \ + old_archive_from_expsyms_cmds_RC \ + allow_undefined_flag_RC \ + no_undefined_flag_RC \ + export_symbols_cmds_RC \ + hardcode_libdir_flag_spec_RC \ + hardcode_libdir_flag_spec_ld_RC \ + hardcode_libdir_separator_RC \ + hardcode_automatic_RC \ + module_cmds_RC \ + module_expsym_cmds_RC \ + lt_cv_prog_compiler_c_o_RC \ + fix_srcfile_path_RC \ + exclude_expsyms_RC \ + include_expsyms_RC; do + + case $var in + old_archive_cmds_RC | \ + old_archive_from_new_cmds_RC | \ + archive_cmds_RC | \ + archive_expsym_cmds_RC | \ + module_cmds_RC | \ + module_expsym_cmds_RC | \ + old_archive_from_expsyms_cmds_RC | \ + export_symbols_cmds_RC | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_RC + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_RC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_RC + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_RC + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_RC + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_RC +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_RC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_RC +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_RC +archive_expsym_cmds=$lt_archive_expsym_cmds_RC +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_RC +module_expsym_cmds=$lt_module_expsym_cmds_RC + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects_RC + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects_RC + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_RC + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_RC + +# The directories searched by this compiler when creating a shared +# library +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_RC + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_RC + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_RC + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_RC + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_RC + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_RC + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_RC + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_RC + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_RC + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_RC + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_RC + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_RC + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_RC + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_RC + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + ;; + + *) + { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5 +echo "$as_me: error: Unsupported tag name: $tagname" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5 +echo "$as_me: error: unable to update list of available tagged configurations." >&2;} + { (exit 1); exit 1; }; } + fi +fi + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Prevent multiple expansion + + + + + + + + + + + + + + + + + + + + + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_wait_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +int +main () +{ + int s; + wait (&s); + s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_sys_wait_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_sys_wait_h=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; } +if test $ac_cv_header_sys_wait_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_WAIT_H 1 +_ACEOF + +fi + + + + + + + + + + + + + + +for ac_header in arpa/inet.h fcntl.h malloc.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6; } +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_inline=$ac_kw +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$ac_cv_c_inline" >&6; } + + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +{ echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef size_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_size_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6; } +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; } +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_time=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5 +echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6; } +if test "${ac_cv_struct_tm+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +struct tm tm; + int *p = &tm.tm_sec; + return !p; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_struct_tm=time.h +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_struct_tm=sys/time.h +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 +echo "${ECHO_T}$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then + +cat >>confdefs.h <<\_ACEOF +#define TM_IN_SYS_TIME 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for working volatile" >&5 +echo $ECHO_N "checking for working volatile... $ECHO_C" >&6; } +if test "${ac_cv_c_volatile+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + +volatile int x; +int * volatile y = (int *) 0; +return !x && !y; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_volatile=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_volatile=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_volatile" >&5 +echo "${ECHO_T}$ac_cv_c_volatile" >&6; } +if test $ac_cv_c_volatile = no; then + +cat >>confdefs.h <<\_ACEOF +#define volatile +_ACEOF + +fi + + +# Checks for library functions. + +for ac_header in stdlib.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5 +echo $ECHO_N "checking for GNU libc compatible malloc... $ECHO_C" >&6; } +if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_malloc_0_nonnull=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if defined STDC_HEADERS || defined HAVE_STDLIB_H +# include +#else +char *malloc (); +#endif + +int +main () +{ +return ! malloc (0); + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_malloc_0_nonnull=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_malloc_0_nonnull=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5 +echo "${ECHO_T}$ac_cv_func_malloc_0_nonnull" >&6; } +if test $ac_cv_func_malloc_0_nonnull = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_MALLOC 1 +_ACEOF + +else + cat >>confdefs.h <<\_ACEOF +#define HAVE_MALLOC 0 +_ACEOF + + case " $LIBOBJS " in + *" malloc.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS malloc.$ac_objext" + ;; +esac + + +cat >>confdefs.h <<\_ACEOF +#define malloc rpl_malloc +_ACEOF + +fi + + + +{ echo "$as_me:$LINENO: checking for working memcmp" >&5 +echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6; } +if test "${ac_cv_func_memcmp_working+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_memcmp_working=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Some versions of memcmp are not 8-bit clean. */ + char c0 = '\100', c1 = '\200', c2 = '\201'; + if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) + return 1; + + /* The Next x86 OpenStep bug shows up only when comparing 16 bytes + or more and with at least one buffer not starting on a 4-byte boundary. + William Lewis provided this test program. */ + { + char foo[21]; + char bar[21]; + int i; + for (i = 0; i < 4; i++) + { + char *a = foo + i; + char *b = bar + i; + strcpy (a, "--------01111111"); + strcpy (b, "--------10000000"); + if (memcmp (a, b, 16) >= 0) + return 1; + } + return 0; + } + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_memcmp_working=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_memcmp_working=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5 +echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6; } +test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in + *" memcmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" + ;; +esac + + + +for ac_header in stdlib.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ echo "$as_me:$LINENO: checking for GNU libc compatible realloc" >&5 +echo $ECHO_N "checking for GNU libc compatible realloc... $ECHO_C" >&6; } +if test "${ac_cv_func_realloc_0_nonnull+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_realloc_0_nonnull=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if defined STDC_HEADERS || defined HAVE_STDLIB_H +# include +#else +char *realloc (); +#endif + +int +main () +{ +return ! realloc (0, 0); + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_realloc_0_nonnull=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_realloc_0_nonnull=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_realloc_0_nonnull" >&5 +echo "${ECHO_T}$ac_cv_func_realloc_0_nonnull" >&6; } +if test $ac_cv_func_realloc_0_nonnull = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_REALLOC 1 +_ACEOF + +else + cat >>confdefs.h <<\_ACEOF +#define HAVE_REALLOC 0 +_ACEOF + + case " $LIBOBJS " in + *" realloc.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS realloc.$ac_objext" + ;; +esac + + +cat >>confdefs.h <<\_ACEOF +#define realloc rpl_realloc +_ACEOF + +fi + + + + + +for ac_header in sys/select.h sys/socket.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ echo "$as_me:$LINENO: checking types of arguments for select" >&5 +echo $ECHO_N "checking types of arguments for select... $ECHO_C" >&6; } +if test "${ac_cv_func_select_args+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + for ac_arg234 in 'fd_set *' 'int *' 'void *'; do + for ac_arg1 in 'int' 'size_t' 'unsigned long int' 'unsigned int'; do + for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +int +main () +{ +extern int select ($ac_arg1, + $ac_arg234, $ac_arg234, $ac_arg234, + $ac_arg5); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done + done +done +# Provide a safe default value. +: ${ac_cv_func_select_args='int,int *,struct timeval *'} + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_select_args" >&5 +echo "${ECHO_T}$ac_cv_func_select_args" >&6; } +ac_save_IFS=$IFS; IFS=',' +set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'` +IFS=$ac_save_IFS +shift + +cat >>confdefs.h <<_ACEOF +#define SELECT_TYPE_ARG1 $1 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define SELECT_TYPE_ARG234 ($2) +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define SELECT_TYPE_ARG5 ($3) +_ACEOF + +rm -f conftest* + +{ echo "$as_me:$LINENO: checking for function prototypes" >&5 +echo $ECHO_N "checking for function prototypes... $ECHO_C" >&6; } +if test "$ac_cv_prog_cc_c89" != no; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define PROTOTYPES 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define __PROTOTYPES 1 +_ACEOF + +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +{ echo "$as_me:$LINENO: checking whether setvbuf arguments are reversed" >&5 +echo $ECHO_N "checking whether setvbuf arguments are reversed... $ECHO_C" >&6; } +if test "${ac_cv_func_setvbuf_reversed+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_func_setvbuf_reversed=no + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +# ifdef PROTOTYPES + int (setvbuf) (FILE *, int, char *, size_t); +# endif +int +main () +{ +char buf; return setvbuf (stdout, _IOLBF, &buf, 1); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +# ifdef PROTOTYPES + int (setvbuf) (FILE *, int, char *, size_t); +# endif +int +main () +{ +char buf; return setvbuf (stdout, &buf, _IOLBF, 1); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + # It compiles and links either way, so it must not be declared + # with a prototype and most likely this is a K&R C compiler. + # Try running it. + if test "$cross_compiling" = yes; then + : # Assume setvbuf is not reversed when cross-compiling. +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +/* This call has the arguments reversed. + A reversed system may check and see that the address of buf + is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */ + char buf; + if (setvbuf (stdout, _IOLBF, &buf, 1) != 0) + return 1; + putchar ('\r'); + return 0; /* Non-reversed systems SEGV here. */ + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_setvbuf_reversed=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + ac_cv_func_setvbuf_reversed=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_setvbuf_reversed" >&5 +echo "${ECHO_T}$ac_cv_func_setvbuf_reversed" >&6; } +if test $ac_cv_func_setvbuf_reversed = yes; then + +cat >>confdefs.h <<\_ACEOF +#define SETVBUF_REVERSED 1 +_ACEOF + +fi + + +for ac_func in vprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +{ echo "$as_me:$LINENO: checking for _doprnt" >&5 +echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6; } +if test "${ac_cv_func__doprnt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define _doprnt to an innocuous variant, in case declares _doprnt. + For example, HP-UX 11i declares gettimeofday. */ +#define _doprnt innocuous__doprnt + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char _doprnt (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef _doprnt + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char _doprnt (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub__doprnt || defined __stub____doprnt +choke me +#endif + +int +main () +{ +return _doprnt (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func__doprnt=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func__doprnt=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 +echo "${ECHO_T}$ac_cv_func__doprnt" >&6; } +if test $ac_cv_func__doprnt = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DOPRNT 1 +_ACEOF + +fi + +fi +done + + + + + + + + + + + + + +for ac_func in bzero gethostbyname gettimeofday memmove memset select socket strchr strerror strtol strtoul +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +ac_config_files="$ac_config_files lksctp-tools.spec Makefile bin/Makefile man/Makefile src/Makefile src/apps/Makefile src/func_tests/Makefile src/include/Makefile src/include/netinet/Makefile src/lib/Makefile src/testlib/Makefile src/withsctp/Makefile doc/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "lksctp-tools.spec") CONFIG_FILES="$CONFIG_FILES lksctp-tools.spec" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "bin/Makefile") CONFIG_FILES="$CONFIG_FILES bin/Makefile" ;; + "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "src/apps/Makefile") CONFIG_FILES="$CONFIG_FILES src/apps/Makefile" ;; + "src/func_tests/Makefile") CONFIG_FILES="$CONFIG_FILES src/func_tests/Makefile" ;; + "src/include/Makefile") CONFIG_FILES="$CONFIG_FILES src/include/Makefile" ;; + "src/include/netinet/Makefile") CONFIG_FILES="$CONFIG_FILES src/include/netinet/Makefile" ;; + "src/lib/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib/Makefile" ;; + "src/testlib/Makefile") CONFIG_FILES="$CONFIG_FILES src/testlib/Makefile" ;; + "src/withsctp/Makefile") CONFIG_FILES="$CONFIG_FILES src/withsctp/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +CYGPATH_W!$CYGPATH_W$ac_delim +PACKAGE!$PACKAGE$ac_delim +VERSION!$VERSION$ac_delim +ACLOCAL!$ACLOCAL$ac_delim +AUTOCONF!$AUTOCONF$ac_delim +AUTOMAKE!$AUTOMAKE$ac_delim +AUTOHEADER!$AUTOHEADER$ac_delim +MAKEINFO!$MAKEINFO$ac_delim +install_sh!$install_sh$ac_delim +STRIP!$STRIP$ac_delim +INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim +mkdir_p!$mkdir_p$ac_delim +AWK!$AWK$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +am__leading_dot!$am__leading_dot$ac_delim +AMTAR!$AMTAR$ac_delim +am__tar!$am__tar$ac_delim +am__untar!$am__untar$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +DEPDIR!$DEPDIR$ac_delim +am__include!$am__include$ac_delim +am__quote!$am__quote$ac_delim +AMDEP_TRUE!$AMDEP_TRUE$ac_delim +AMDEP_FALSE!$AMDEP_FALSE$ac_delim +AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim +CCDEPMODE!$CCDEPMODE$ac_delim +am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim +am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim +LN_S!$LN_S$ac_delim +build!$build$ac_delim +build_cpu!$build_cpu$ac_delim +build_vendor!$build_vendor$ac_delim +build_os!$build_os$ac_delim +host!$host$ac_delim +host_cpu!$host_cpu$ac_delim +host_vendor!$host_vendor$ac_delim +host_os!$host_os$ac_delim +SED!$SED$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +ECHO!$ECHO$ac_delim +AR!$AR$ac_delim +RANLIB!$RANLIB$ac_delim +DSYMUTIL!$DSYMUTIL$ac_delim +NMEDIT!$NMEDIT$ac_delim +CPP!$CPP$ac_delim +CXX!$CXX$ac_delim +CXXFLAGS!$CXXFLAGS$ac_delim +ac_ct_CXX!$ac_ct_CXX$ac_delim +CXXDEPMODE!$CXXDEPMODE$ac_delim +am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +CEOF$ac_eof +_ACEOF + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim +CXXCPP!$CXXCPP$ac_delim +F77!$F77$ac_delim +FFLAGS!$FFLAGS$ac_delim +ac_ct_F77!$ac_ct_F77$ac_delim +LIBTOOL!$LIBTOOL$ac_delim +LIBTOOL_DEPS!$LIBTOOL_DEPS$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 9; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" +# Compute $ac_file's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $ac_file | $ac_file:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $ac_file" >`$as_dirname -- $ac_file || +$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X$ac_file : 'X\(//\)[^/]' \| \ + X$ac_file : 'X\(//\)$' \| \ + X$ac_file : 'X\(/\)' \| . 2>/dev/null || +echo X$ac_file | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 +echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir=$dirpart/$fdir + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..780e33b --- /dev/null +++ b/configure.in @@ -0,0 +1,73 @@ +dnl -*-autoconf-*- + +dnl lksctp-tools: Autoconf script +dnl +dnl $Id: configure.in,v 1.1.1.2 2002/08/06 23:55:45 inaky Exp $ + +dnl (C) 2002 Intel Corporation +dnl Iñaky Pérez-González +dnl - Initial packaging + +dnl Package info +dnl (CONFIG_AUX_DIR is for putting stuff in $TOPSRCDIR/bin, so we +dnl reduce clutter in the root; if we put it below AM_INIT_AUTOMAKE, +dnl configure will fail ...) + +AC_INIT([src/apps/sctp_darn.c]) +AC_CONFIG_AUX_DIR(bin) +AM_INIT_AUTOMAKE(lksctp-tools,1.0.10) +AC_CONFIG_SRCDIR([config.h.in]) +AM_CONFIG_HEADER([config.h]) +AC_REVISION($Revision: 1.1.1.2 $) + +dnl Set defaults +dnl CFLAGS="$CFLAGS -g -Wall" + +dnl Checks for programs. +AC_PROG_AWK +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_LN_S +AC_ISC_POSIX + +dnl Checks for libraries. +AC_LIBTOOL_DLOPEN +AC_PROG_LIBTOOL +AC_SUBST(LIBTOOL_DEPS) + +dnl Checks for header files. +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS([arpa/inet.h fcntl.h malloc.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h unistd.h]) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_SIZE_T +AC_HEADER_TIME +AC_STRUCT_TM +AC_C_VOLATILE + +# Checks for library functions. +AC_FUNC_MALLOC +AC_FUNC_MEMCMP +AC_FUNC_REALLOC +AC_FUNC_SELECT_ARGTYPES +AC_FUNC_SETVBUF_REVERSED +AC_FUNC_VPRINTF +AC_CHECK_FUNCS([bzero gethostbyname gettimeofday memmove memset select socket strchr strerror strtol strtoul]) + +AC_CONFIG_FILES([lksctp-tools.spec + Makefile + bin/Makefile + man/Makefile + src/Makefile + src/apps/Makefile + src/func_tests/Makefile + src/include/Makefile + src/include/netinet/Makefile + src/lib/Makefile + src/testlib/Makefile + src/withsctp/Makefile + doc/Makefile]) +AC_OUTPUT diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..6e7c648 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,11 @@ +include $(top_srcdir)/Makefile.vars +include $(top_srcdir)/Makefile.rules + +internet_drafts = \ + draft-ietf-tsvwg-sctpsocket-14.txt \ + draft-ietf-tsvwg-addip-sctp-15.txt + +rfcs = rfc2960.txt rfc3309.txt rfc3257.txt rfc3286.txt rfc3758.txt \ + rfc3873.txt rfc4460.txt + +EXTRA_DIST += $(rfcs) $(internet_drafts) diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..ae60db9 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,359 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*-makefile-*- +# +# type: deep, strictness: gnu +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.rules $(top_srcdir)/Makefile.vars +subdir = doc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +MAINTAINERCLEANFILES = Makefile.in +DISTCLEANFILES = \\\#*\\\# Makefile +CLEANFILES = +MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io +EXTRA_DIST = $(rfcs) $(internet_drafts) +LATEX = @LATEX@ +DVIPS = @DVIPS@ +DVIPDFM = @DVIPDFM@ +ENSCRIPTBIN = @ENSCRIPTBIN@ +PS2PDF = @PS2PDF@ +edit = @sed \ + -e "s|\@bindir\@|$(bindir)|" \ + -e "s|\@libdir\@|$(libdir)|" \ + -e "s|\@PACKAGE\@|$(PACKAGE)|" + +internet_drafts = \ + draft-ietf-tsvwg-sctpsocket-14.txt \ + draft-ietf-tsvwg-addip-sctp-15.txt + +rfcs = rfc2960.txt rfc3309.txt rfc3257.txt rfc3286.txt rfc3758.txt \ + rfc3873.txt rfc4460.txt + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.vars $(top_srcdir)/Makefile.rules $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign doc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + + +# -*-makefile-*- +# +# Generate pre-parsed C code. +%.i: %.c + $(COMPILE) -E -c $^ -o $@ + +.PRECIOUS: %.i +%.ci: %.i + -grep -v -e "^#" -e "^ *$$" $^ | indent > $@ + mv -f $@ $^ +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/doc/draft-ietf-tsvwg-addip-sctp-15.txt b/doc/draft-ietf-tsvwg-addip-sctp-15.txt new file mode 100644 index 0000000..2e37ebb --- /dev/null +++ b/doc/draft-ietf-tsvwg-addip-sctp-15.txt @@ -0,0 +1,1962 @@ + + + + +Network Working Group R. Stewart +Internet-Draft M. Ramalho +Expires: December 2, 2006 Cisco Systems, Inc. + Q. Xie + Motorola, Inc. + M. Tuexen + Univ. of Applied Sciences Muenster + P. Conrad + University of Delaware + May 31, 2006 + + + Stream Control Transmission Protocol (SCTP) Dynamic Address + Reconfiguration + draft-ietf-tsvwg-addip-sctp-15.txt + +Status of this Memo + + By submitting this Internet-Draft, each author represents that any + applicable patent or other IPR claims of which he or she is aware + have been or will be disclosed, and any of which he or she becomes + aware will be disclosed, in accordance with Section 6 of BCP 79. + + 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 December 2, 2006. + +Copyright Notice + + Copyright (C) The Internet Society (2006). + +Abstract + + This document describes extensions to the Stream Control Transmission + + + +Stewart, et al. Expires December 2, 2006 [Page 1] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + Protocol (SCTP) [RFC2960] that provides a method to reconfigure IP + address information on an existing association. + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 + 2. Conventions . . . . . . . . . . . . . . . . . . . . . . . . . 4 + 3. Additional Chunks and Parameters . . . . . . . . . . . . . . . 4 + 3.1. New Chunk Types . . . . . . . . . . . . . . . . . . . . . 5 + 3.1.1. Address Configuration Change Chunk (ASCONF) . . . . . 5 + 3.1.2. Address Configuration Acknowledgment Chunk + (ASCONF-ACK) . . . . . . . . . . . . . . . . . . . . . 6 + 3.2. New Parameter Types . . . . . . . . . . . . . . . . . . . 7 + 3.2.1. Add IP Address . . . . . . . . . . . . . . . . . . . . 8 + 3.2.2. Delete IP Address . . . . . . . . . . . . . . . . . . 9 + 3.2.3. Error Cause Indication . . . . . . . . . . . . . . . . 10 + 3.2.4. Set Primary IP Address . . . . . . . . . . . . . . . . 11 + 3.2.5. Success Indication . . . . . . . . . . . . . . . . . . 12 + 3.2.6. Adaptation Layer Indication . . . . . . . . . . . . . 13 + 3.2.7. Supported Extensions Parameter . . . . . . . . . . . . 13 + 3.3. New Error Causes . . . . . . . . . . . . . . . . . . . . . 14 + 3.3.1. Error Cause: Request to Delete Last Remaining IP + Address . . . . . . . . . . . . . . . . . . . . . . . 14 + 3.3.2. Error Cause: Operation Refused Due to Resource + Shortage . . . . . . . . . . . . . . . . . . . . . . . 15 + 3.3.3. Error Cause: Request to Delete Source IP Address . . . 16 + 3.3.4. Error Cause: Association Aborted due to illegal + ASCONF-ACK . . . . . . . . . . . . . . . . . . . . . . 17 + 3.3.5. Error Cause: Request refused - no authorization. . . . 17 + 4. Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . 18 + 4.1. ASCONF Chunk Procedures . . . . . . . . . . . . . . . . . 18 + 4.1.1. Congestion Control of ASCONF Chunks . . . . . . . . . 19 + 4.2. Upon reception of an ASCONF Chunk. . . . . . . . . . . . . 20 + 4.3. General rules for address manipulation . . . . . . . . . . 22 + 4.3.1. A special case for OOTB ABORT chunks . . . . . . . . . 25 + 4.3.2. A special case for changing an address. . . . . . . . 26 + 4.4. Setting of the primary address . . . . . . . . . . . . . . 26 + 5. Security Considerations . . . . . . . . . . . . . . . . . . . 27 + 6. IANA considerations . . . . . . . . . . . . . . . . . . . . . 28 + 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 28 + 8. References . . . . . . . . . . . . . . . . . . . . . . . . . . 29 + Appendix A. Abstract Address Handling . . . . . . . . . . . . . . 29 + A.1. General remarks . . . . . . . . . . . . . . . . . . . . . 29 + A.2. Generalized endpoints . . . . . . . . . . . . . . . . . . 29 + A.3. Associations . . . . . . . . . . . . . . . . . . . . . . . 30 + A.4. Relationship with RFC 2960 . . . . . . . . . . . . . . . . 31 + A.5. Rules for address manipulation . . . . . . . . . . . . . . 31 + + + +Stewart, et al. Expires December 2, 2006 [Page 2] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 33 + Intellectual Property and Copyright Statements . . . . . . . . . . 35 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Expires December 2, 2006 [Page 3] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + +1. Introduction + + To extend the utility and application scenarios of SCTP, this + document introduces optional extensions that provide SCTP with the + ability to: + + 1. reconfigure IP address information on an existing association. + 2. set the remote primary path. + 3. exchange adaptation layer information during association setup. + + These extensions enable SCTP to be utilized in the following + applications: + + 1. For computational or networking platforms that allow addition/ + removal of physical interface cards this feature can provide a + graceful method to add to the interfaces of an existing + association. For IPv6 this feature allows renumbering of + existing associations. + 2. This provides a method for an endpoint to request that its peer + set its primary destination address. This can be useful when an + address is about to be deleted, or when an endpoint has some + predetermined knowledge about which is the preferred address to + receive SCTP packets upon. + 3. This feature can be used to extend the usability of SCTP without + modifying it by allowing endpoints to exchange some information + during association setup. + + +2. Conventions + + The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, + SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when + they appear in this document, are to be interpreted as described in + RFC2119 [RFC2119]. + + +3. Additional Chunks and Parameters + + This section describes the addition of two new chunks and, seven new + parameters to allow: + + o Dynamic addition of IP Addresses to an association. + o Dynamic deletion of IP Addresses from an association. + o A request to set the primary address the peer will use when + sending to an endpoint. + + Additionally, this section describes three new error causes that + support these new chunks and parameters. + + + +Stewart, et al. Expires December 2, 2006 [Page 4] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + +3.1. New Chunk Types + + This section defines two new chunk types that will be used to + transfer the control information reliably. Table 1 illustrates the + two new chunk types. + + Chunk Type Chunk Name + -------------------------------------------------------------- + 0xC1 Address Configuration Change Chunk (ASCONF) + 0x80 Address Configuration Acknowledgment (ASCONF-ACK) + + Table 1: Address Configuration Chunks + + It should be noted that the ASCONF Chunk format requires the receiver + to report to the sender if it does not understand the ASCONF Chunk. + This is accomplished by setting the upper bits in the chunk type as + described in RFC2960 [RFC2960] section 3.2. Note that the upper two + bits in the ASCONF Chunk are set to one. As defined in RFC2960 + [RFC2960] section 3.2, setting these upper bits in this manner will + cause the receiver that does not understand this chunk to skip the + chunk and continue processing, but report in an Operation Error Chunk + using the 'Unrecognized Chunk Type' cause of error. + +3.1.1. Address Configuration Change Chunk (ASCONF) + + This chunk is used to communicate to the remote endpoint one of the + configuration change requests that MUST be acknowledged. The + information carried in the ASCONF Chunk uses the form of a Type- + Length-Value (TLV), as described in "3.2.1 Optional/Variable-length + Parameter Format" in RFC2960 [RFC2960], for all variable parameters. + This chunk MUST be sent in an authenticated way by using the + mechanism defined in SCTP-AUTH [I-D.ietf-tsvwg-sctp-auth]. If this + chunk is received unauthenticated it MUST be silently discarded as + described in SCTP-AUTH [I-D.ietf-tsvwg-sctp-auth]. + + + + + + + + + + + + + + + + + +Stewart, et al. Expires December 2, 2006 [Page 5] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 0xC1 | Chunk Flags | Chunk Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Serial Number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Address Parameter | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ASCONF Parameter #1 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ \ + / .... / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ASCONF Parameter #N | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Serial Number : 32 bits (unsigned integer) + + This value represents a Serial Number for the ASCONF Chunk. The + valid range of Serial Number is from 0 to 4294967295 (2**32 - 1). + Serial Numbers wrap back to 0 after reaching 4294967295. + + Address Parameter : 8 or 20 bytes (depending on type) + + This field contains an address parameter, either IPv6 or IPv4, from + RFC2960 [RFC2960]. The address is an address of the sender of the + ASCONF chunk, the address MUST be considered part of the association + by the peer endpoint (the receiver of the ASCONF chunk). This field + may be used by the receiver of the ASCONF to help in finding the + association. If the address 0.0.0.0 or ::0 is provided the receiver + MAY lookup the association by other information provided in the + packet. This parameter MUST be present in every ASCONF message i.e. + it is a mandatory TLV parameter. + + Note the host name address parameter is NOT allowed and MUST be + ignored if received in any ASCONF message. + + ASCONF Parameter: TLV format + + Each Address configuration change is represented by a TLV parameter + as defined in Section 3.2. One or more requests may be present in an + ASCONF Chunk. + +3.1.2. Address Configuration Acknowledgment Chunk (ASCONF-ACK) + + This chunk is used by the receiver of an ASCONF Chunk to acknowledge + + + +Stewart, et al. Expires December 2, 2006 [Page 6] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + the reception. It carries zero or more results for any ASCONF + Parameters that were processed by the receiver. This chunk MUST be + sent in an authenticated way by using the mechanism defined in SCTP- + AUTH [I-D.ietf-tsvwg-sctp-auth]. If this chunk is received + unauthenticated it MUST be silently discarded as described in SCTP- + AUTH [I-D.ietf-tsvwg-sctp-auth]. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 0x80 | Chunk Flags | Chunk Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Serial Number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ASCONF Parameter Response#1 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ \ + / .... / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ASCONF Parameter Response#N | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Serial Number : 32 bits (unsigned integer) + + This value represents the Serial Number for the received ASCONF Chunk + that is acknowledged by this chunk. This value is copied from the + received ASCONF Chunk. + + ASCONF Parameter Response : TLV format + + The ASCONF Parameter Response is used in the ASCONF-ACK to report + status of ASCONF processing. By default, if a responding endpoint + does not include any Error Cause, a success is indicated. Thus a + sender of an ASCONF-ACK MAY indicate complete success of all TLVs in + an ASCONF by returning only the Chunk Type, Chunk Flags, Chunk Length + (set to 8) and the Serial Number. + +3.2. New Parameter Types + + The seven new parameters added follow the format defined in section + 3.2.1 of RFC2960 [RFC2960]. Table 2, 3 and 4 describes the + parameters. + + + + + + + + +Stewart, et al. Expires December 2, 2006 [Page 7] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + Address Configuration Parameters Parameter Type + ------------------------------------------------- + Set Primary Address 0xC004 + Adaptation Layer Indication 0xC006 + Supported Extensions 0x8008 + + Table 2: Parameters that can be used in INIT/INIT-ACK chunk + + + Address Configuration Parameters Parameter Type + ------------------------------------------------- + Add IP Address 0xC001 + Delete IP Address 0xC002 + Set Primary Address 0xC004 + + Table 3: Parameters used in ASCONF Parameter + + + Address Configuration Parameters Parameter Type + ------------------------------------------------- + Error Cause Indication 0xC003 + Success Indication 0xC005 + + Table 4: Parameters used in ASCONF Parameter Response + + + Any parameter that appears where it is not allowed (for example a + 0xC002 parameter appearing within an INIT or INIT-ACK) MAY be + responded to with an ABORT by the receiver of the invalid parameter. + +3.2.1. Add IP 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 0xC001 | Length = Variable | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ASCONF-Request Correlation ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Address Parameter | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + ASCONF-Request Correlation ID: 32 bits + + This is an opaque integer assigned by the sender to identify each + request parameter. It is in host byte order and is only meaningful + to the sender. The receiver of the ASCONF Chunk will copy this 32 + bit value into the ASCONF Response Correlation ID field of the + + + +Stewart, et al. Expires December 2, 2006 [Page 8] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + ASCONF-ACK response parameter. The sender of the ASCONF can use this + same value in the ASCONF-ACK to find which request the response is + for. + + Address Parameter: TLV + + This field contains an IPv4 or IPv6 address parameter as described in + 3.3.2.1 of RFC2960 [RFC2960]. The complete TLV is wrapped within + this parameter. It informs the receiver that the address specified + is to be added to the existing association. This parameter MUST NOT + contain a broadcast or multicast address. If the address 0.0.0.0 or + ::0 is provided, the source address of the packet MUST be added. + + An example TLV requesting that the IPv4 address 10.1.1.1 be added to + the association would look as follows: + + +--------------------------------+ + | Type=0xC001 | Length = 16 | + +--------------------------------+ + | C-ID = 0x01023474 | + +--------------------------------+ + | Type=5 | Length = 8 | + +----------------+---------------+ + | Value=0x0a010101 | + +----------------+---------------+ + + Valid Chunk Appearance + + The Add IP Address parameter may only appear in the ASCONF Chunk + type. + +3.2.2. Delete IP 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type =0xC002 | Length = Variable | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ASCONF-Request Correlation ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Address Parameter | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + ASCONF-Request Correlation ID: 32 bits + + This is an opaque integer assigned by the sender to identify each + request parameter. It is in host byte order and is only meaningful + to the sender. The receiver of the ASCONF Chunk will copy this 32 + + + +Stewart, et al. Expires December 2, 2006 [Page 9] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + bit value into the ASCONF Response Correlation ID field of the + ASCONF-ACK response parameter. The sender of the ASCONF can use this + same value in the ASCONF-ACK to find which request the response is + for. + + Address Parameter: TLV + + This field contains an IPv4 or IPv6 address parameter as described in + 3.3.2.1 of RFC2960 [RFC2960]. The complete TLV is wrapped within + this parameter. It informs the receiver that the address specified + is to be removed from the existing association. This parameter MUST + NOT contain a broadcast or multicast address. If the address 0.0.0.0 + or ::0 is provided, all addresses of the peer except the source + address of the packet MUST be deleted. + + An example TLV deleting the IPv4 address 10.1.1.1 from an existing + association would look as follows: + + +--------------------------------+ + | Type=0xC002 | Length = 16 | + +--------------------------------+ + | C-ID = 0x01023476 | + +--------------------------------+ + | Type=5 | Length = 8 | + +----------------+---------------+ + | Value=0x0a010101 | + +----------------+---------------+ + + Valid Chunk Appearance + + The Delete IP Address parameter may only appear in the ASCONF Chunk + type. + +3.2.3. Error Cause Indication + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 0xC003 | Length = Variable | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ASCONF-Response Correlation ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Error Cause(s) or Return Info on Success | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + ASCONF-Response Correlation ID: 32 bits + + This is an opaque integer assigned by the sender to identify each + + + +Stewart, et al. Expires December 2, 2006 [Page 10] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + request parameter. The receiver of the ASCONF Chunk will copy this + 32 bit value from the ASCONF-Request Correlation ID into the ASCONF + Response Correlation ID field so the peer can easily correlate the + request to this response. + + Error Cause(s): TLV(s) + + When reporting an error this response parameter is used to wrap one + or more standard error causes normally found within an SCTP + Operational Error or SCTP Abort (as defined in RFC2960 [RFC2960]). + The Error Cause(s) follow the format defined in section 3.3.10 of + RFC2960 [RFC2960]. + + Valid Chunk Appearance + + The Error Cause Indication parameter may only appear in the ASCONF- + ACK chunk type. + +3.2.4. Set Primary IP 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type =0xC004 | Length = Variable | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ASCONF-Request Correlation ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Address Parameter | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + ASCONF-Request Correlation ID: 32 bits + + This is an opaque integer assigned by the sender to identify each + request parameter. It is in host byte order and is only meaningful + to the sender. The receiver of the ASCONF Chunk will copy this 32 + bit value into the ASCONF Response Correlation ID field of the + ASCONF-ACK response parameter. The sender of the ASCONF can use this + same value in the ASCONF-ACK to find which request the response is + for. + + Address Parameter: TLV + + This field contains an IPv4 or IPv6 address parameter as described in + 3.3.2.1 of RFC2960 [RFC2960]. The complete TLV is wrapped within + this parameter. It requests the receiver to mark the specified + address as the primary address to send data to (see section 5.1.2 of + RFC2960 [RFC2960]). The receiver MAY mark this as its primary upon + receiving this request. If the address 0.0.0.0 or ::0 is provided, + + + +Stewart, et al. Expires December 2, 2006 [Page 11] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + the receiver MAY mark the source address of the packet as its + primary. + + An example TLV requesting that the IPv4 address 10.1.1.1 be made the + primary destination address would look as follows: + + +--------------------------------+ + | Type=0xC004 | Length = 16 | + +--------------------------------+ + | C-ID = 0x01023479 | + +--------------------------------+ + | Type=5 | Length = 8 | + +----------------+---------------+ + | Value=0x0a010101 | + +----------------+---------------+ + + Valid Chunk Appearance + + The Set Primary IP Address parameter may appear in the ASCONF Chunk, + the INIT, or the INIT-ACK chunk type. The inclusion of this + parameter in the INIT or INIT-ACK can be used to indicate an initial + preference of primary address. + +3.2.5. Success Indication + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 0xC005 | Length = 8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ASCONF-Response Correlation ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + By default if a responding endpoint does not report an error for any + requested TLV, a success is implicitly indicated. Thus a sender of a + ASCONF-ACK MAY indicate complete success of all TLVs in an ASCONF by + returning only the Chunk Type, Chunk Flags, Chunk Length (set to 8) + and the Serial Number. + + The responding endpoint MAY also choose to explicitly report a + success for a requested TLV, by returning a success report ASCONF + Parameter Response. + + ASCONF-Response Correlation ID: 32 bits + + This is an opaque integer assigned by the sender to identify each + request parameter. The receiver of the ASCONF Chunk will copy this + 32 bit value from the ASCONF-Request Correlation ID into the ASCONF + + + +Stewart, et al. Expires December 2, 2006 [Page 12] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + Response Correlation ID field so the peer can easily correlate the + request to this response. + + Valid Chunk Appearance + + The Success Indication parameter may only appear in the ASCONF-ACK + chunk type. + +3.2.6. Adaptation Layer Indication + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type =0xC006 | Length = 8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Adaptation Code point | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + This parameter is specified for the communication of peer upper layer + protocols. It is envisioned to be used for flow control and other + adaptation layers that require an indication to be carried in the + INIT and INIT-ACK. Each adaptation layer that is defined that wishes + to use this parameter MUST specify a an adaptation code point in an + appropriate RFC defining its use and meaning. This parameter SHOULD + NOT be examined by the receiving SCTP implementation and should be + passed opaquely to the upper layer protocol. + + Valid Chunk Appearance + + The Adaptation Layer Indication parameter may appear in INIT or INIT- + ACK chunk and SHOULD be passed to the receivers upper layer protocol. + This parameter MUST NOT appear in a ASCONF chunk. + +3.2.7. Supported Extensions Parameter + + This parameter is used at startup to identify any additional + extensions that the sender supports. The sender MUST support both + the sending and the receiving of any chunk types listed within the + Supported Extensions Parameter. + + + + + + + + + + + + +Stewart, et al. Expires December 2, 2006 [Page 13] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Parameter Type = 0x8008 | Parameter Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | CHUNK TYPE 1 | CHUNK TYPE 2 | CHUNK TYPE 3 | CHUNK TYPE 4 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | CHUNK TYPE N | PAD | PAD | PAD | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Parameter Type This field holds the IANA defined parameter type for + Supported Extensions Parameter. The suggested value of this field + for IANA is 0x8008. + Parameter Type Length This field holds the length of the parameter, + including the Parameter Type, Parameter Length and any addition + supported extensions. Note the length MUST NOT include any + padding. + CHUNK TYPE X This field(s) hold the chunk type of any SCTP + extension(s) that are currently supported by the sending SCTP. + Multiple chunk types may be defined listing each additional + feature that the sender supports. The sender MUST NOT include + multiple Supported Extensions Parameter within any chunk. + Parameter Appearance This parameter may appear in the INIT or INIT- + ACK chunk. This parameter MUST NOT appear in any other chunk. + +3.3. New Error Causes + + Five new Error Causes are added to the SCTP Operational Errors, + primarily for use in the ASCONF-ACK chunk. + + Cause Code + Value Cause Code + --------- ---------------- + 0x0100 Request to Delete Last Remaining IP Address. + 0x0101 Operation Refused Due to Resource Shortage. + 0x0102 Request to Delete Source IP Address. + 0x0103 Association Aborted due to illegal ASCONF-ACK + 0x0104 Request refused - no authorization. + + Table 5: New Error Causes + +3.3.1. Error Cause: Request to Delete Last Remaining IP Address + + Cause of error + + + + +Stewart, et al. Expires December 2, 2006 [Page 14] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + Request to Delete Last Remaining IP address: The receiver of this + error sent a request to delete the last IP address from its + association with its peer. This error indicates that the request is + rejected. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=0x0100 | Cause Length=Variable | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ TLV-Copied-From-ASCONF / + / \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + An example of a failed delete in an Error Cause TLV would look as + follows in the response ASCONF-ACK message: + + +--------------------------------+ + | Type = 0xC003 | Length = 28 | + +----------------+---------------+ + | C-ID = 0x01023476 | + +--------------------------------+ + | Cause=0x0100 | Length = 20 | + +----------------+---------------+ + | Type= 0xC002 | Length = 16 | + +----------------+---------------+ + | C-ID = 0x01023476 | + +--------------------------------+ + | Type=0x0005 | Length = 8 | + +----------------+---------------+ + | Value=0x0A010101 | + +----------------+---------------+ + +3.3.2. Error Cause: Operation Refused Due to Resource Shortage + + Cause of error + + This error cause is used to report a failure by the receiver to + perform the requested operation due to a lack of resources. The + entire TLV that is refused is copied from the ASCONF into the error + cause. + + + + + + + + + + +Stewart, et al. Expires December 2, 2006 [Page 15] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=0x0101 | Cause Length=Variable | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ TLV-Copied-From-ASCONF / + / \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + An example of a failed addition in an Error Cause TLV would look as + follows in the response ASCONF-ACK message: + + +--------------------------------+ + | Type = 0xC003 | Length = 28 | + +--------------------------------+ + | C-ID = 0x01023474 | + +--------------------------------+ + | Cause=0x0101 | Length = 20 | + +----------------+---------------+ + | Type=0xC001 | Length = 16 | + +--------------------------------+ + | C-ID = 0x01023474 | + +--------------------------------+ + | Type=0x0005 | Length = 8 | + +----------------+---------------+ + | Value=0x0A010101 | + +----------------+---------------+ + +3.3.3. Error Cause: Request to Delete Source IP Address + + Cause of error + + Request to Delete Source IP Address: The receiver of this error sent + a request to delete the source IP address of the ASCONF message. + This error indicates that the request is rejected. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=0x0102 | Cause Length=Variable | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ TLV-Copied-From-ASCONF / + / \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + An example of a failed delete in an Error Cause TLV would look as + follows in the response ASCONF-ACK message: + + + + +Stewart, et al. Expires December 2, 2006 [Page 16] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + +--------------------------------+ + | Type = 0xC003 | Length = 28 | + +--------------------------------+ + | C-ID = 0x01023476 | + +--------------------------------+ + | Cause=0x0102 | Length = 20 | + +----------------+---------------+ + | Type=0xC002 | Length = 16 | + +----------------+---------------+ + | C-ID = 0x01023476 | + +--------------------------------+ + | Type=0x0005 | Length = 8 | + +----------------+---------------+ + | Value=0x0A010101 | + +----------------+---------------+ + + IMPLEMENTATION NOTE: It is unlikely that an endpoint would source a + packet from the address being deleted, unless the endpoint does not + do proper source address selection. + +3.3.4. Error Cause: Association Aborted due to illegal ASCONF-ACK + + This error is to be included in an ABORT that is generated due to the + reception of an ASCONF-ACK that was not expected but is larger than + the current sequence number (see Section 4.3 Rule D0 ). Note that a + sequence number is larger than the last acked sequence number if it + is either the next sequence or no more than 2^^31-1 greater than the + current sequence number. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=0x0103 | Cause Length=4 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +3.3.5. Error Cause: Request refused - no authorization. + + Cause of error + + This error cause may be included to reject a request based on local + security policies. + + + + + + + + + + +Stewart, et al. Expires December 2, 2006 [Page 17] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=0x0104 | Cause Length=Variable | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ TLV-Copied-From-ASCONF / + / \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +4. Procedures + + This section will lay out the specific procedures for address + configuration change chunk type and its processing. + +4.1. ASCONF Chunk Procedures + + When an endpoint has an ASCONF signaled change to be sent to the + remote endpoint it should do the following: + + A1) Create an ASCONF Chunk as defined in Section 3.1.1. The chunk + should contain all of the TLV(s) of information necessary to be + sent to the remote endpoint, and unique correlation identities for + each request. + A2) A serial number should be assigned to the Chunk. The serial + number should be a monotonically increasing number. The serial + number MUST be initialized at the start of the association to the + same value as the Initial TSN and every time a new ASCONF chunk is + created it is incremented by one after assigning the serial number + to the newly created chunk . + A3) If no ASCONF Chunk is outstanding (un-acknowledged) with the + remote peer, send the chunk. + A4) Start a T-4 RTO timer, using the RTO value of the selected + destination address (normally the primary path; see RFC2960 + [RFC2960] section 6.4 for details). + A5) When the ASCONF-ACK that acknowledges the serial number last sent + arrives, stop the T-4 RTO timer, and clear the appropriate + association and destination error counters as defined in RFC2960 + [RFC2960] section 8.1 and 8.2. + A6) Process all of the TLVs within the ASCONF-ACK to find out + particular status information returned to the various requests + that were sent. Use the Correlation IDs to correlate the request + and the responses. + A7) If an error response is received for a TLV parameter, all TLVs + with no response before the failed TLV are considered successful + if not reported. All TLVs after the failed response are + considered unsuccessful unless a specific success indication is + present for the parameter. + + + +Stewart, et al. Expires December 2, 2006 [Page 18] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + A8) If there is no response(s) to specific TLV parameter(s), and no + failures are indicated, then all request(s) are considered + successful. + A9) If the peer responds to an ASCONF with an ERROR chunk reporting + that it did not recognize the ASCONF chunk type, the sender of the + ASCONF MUST NOT send any further ASCONF chunks and MUST stop its + T-4 timer. + + If the T-4 RTO timer expires the endpoint should do the following: + + B1) Increment the error counters and perform path failure detection + on the appropriate destination address as defined in RFC2960 + [RFC2960] section 8.1 and 8.2. + B2) Increment the association error counters and perform endpoint + failure detection on the association as defined in RFC2960 + [RFC2960] section 8.1 and 8.2. + B3) Back-off the destination address RTO value to which the ASCONF + chunk was sent by doubling the RTO timer value. + Note: The RTO value is used in the setting of all timer types for + SCTP. Each destination address has a single RTO estimate. + B4) Re-transmit the ASCONF Chunk last sent and if possible choose an + alternate destination address (please refer to RFC2960 [RFC2960] + section 6.4.1). An endpoint MUST NOT add new parameters to this + chunk, it MUST be the same (including its serial number) as the + last ASCONF sent. + B5) Restart the T-4 RTO timer. Note that if a different destination + is selected, then the RTO used will be that of the new destination + address. + + Note: the total number of re-transmissions is limited by B2 above. + If the maximum is reached, the association will fail and enter into + the CLOSED state (see RFC2960 [RFC2960] section 6.4.1 for details). + +4.1.1. Congestion Control of ASCONF Chunks + + In defining the ASCONF Chunk transfer procedures, it is essential + that these transfers MUST NOT cause congestion within the network. + To achieve this, we place these restrictions on the transfer of + ASCONF Chunks: + + R1) One and only one ASCONF Chunk MAY be in transit and + unacknowledged at any one time. If a sender, after sending an + ASCONF chunk, decides it needs to transfer another ASCONF Chunk, + it MUST wait until the ASCONF-ACK Chunk returns from the previous + ASCONF Chunk before sending a subsequent ASCONF. Note this + restriction binds each side, so at any time two ASCONF may be in- + transit on any given association (one sent from each endpoint). + + + + +Stewart, et al. Expires December 2, 2006 [Page 19] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + R2) An ASCONF may be bundled with any other chunk type (except other + ASCONF Chunks). + R3) An ASCONF-ACK may be bundled with any other chunk type except + other ASCONF-ACKs. + R4) Both ASCONF and ASCONF-ACK chunks MUST NOT be sent in any SCTP + state except ESTABLISHED, SHUTDOWN-PENDING, SHUTDOWN-RECEIVED and + SHUTDOWN-SENT. + R5) An ASCONF MUST NOT be larger than the path MTU of the + destination. + R6) An ASCONF-ACK SHOULD not be larger than the path MTU. In some + circumstances an ASCONF-ACK may exceed the path MTU and in such a + case IP fragmentation should be used to transmit the chunk. + + If the sender of an ASCONF Chunk receives an Operational Error + indicating that the ASCONF chunk type is not understood, then the + sender MUST NOT send subsequent ASCONF Chunks to the peer. The + endpoint should also inform the upper layer application that the peer + endpoint does not support any of the extensions detailed in this + document. + +4.2. Upon reception of an ASCONF Chunk. + + When an endpoint receives an ASCONF Chunk from the remote peer + special procedures MAY be needed to identify the association the + ASCONF Chunk is associated with. To properly find the association + the following procedures should be followed: + + L1) Use the source address and port number of the sender to attempt + to identify the association (i.e. use the same method defined in + RFC2960 [RFC2960] used for all other SCTP chunks). If found + proceed to rule L4. + L2) If the association is not found, use the address found in the + Address Parameter TLV combined with the port number found in the + SCTP common header. If found proceed to rule L4. + L3) If neither L1 or L2 locates the association, treat the chunk as + an Out Of The Blue chunk as defined in RFC2960 [RFC2960]. + L4) Follow the normal rules to validate the SCTP verification tag + found in RFC2960 [RFC2960]. + + After identification and verification of the association, the + following should be performed to properly process the ASCONF Chunk: + + C1) Compare the value of the serial number to the value the endpoint + stored in a new association variable 'Peer-Serial-Number'. This + value MUST be initialized to the Initial TSN value minus 1. + + + + + + +Stewart, et al. Expires December 2, 2006 [Page 20] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + C2) If the value found in the serial number is equal to the ('Peer- + Serial-Number' + 1), the endpoint MUST: + + V1) Process the TLVs contained within the Chunk performing the + appropriate actions as indicated by each TLV type. The TLVs + MUST be processed in order within the Chunk. For example, if + the sender puts 3 TLVs in one chunk, the first TLV (the one + closest to the Chunk Header) in the Chunk MUST be processed + first. The next TLV in the chunk (the middle one) MUST be + processed second and finally the last TLV in the Chunk MUST be + processed last. If the association was found via L2, the first + parameter MUST be an Add IP address parameter for the source + address of the packet. If it is not the case the ASCONF is + silently discarded. Please note that this new address can not + be deleted by a later parameter in the chunk because it is the + source address of the packet. + V2) In processing the chunk, the receiver should build a response + message with the appropriate error TLVs, as specified in the + Parameter type bits for any ASCONF Parameter it does not + understand. To indicate an unrecognized parameter, cause type + 8 as defined in the ERROR in 3.3.10.8 of RFC2960 [RFC2960] + should be used. The endpoint may also use the response to + carry rejections for other reasons such as resource shortages + etc, using the Error Cause TLV and an appropriate error + condition. + Note: a positive response is implied if no error is indicated + by the sender. + V3) All responses MUST copy the ASCONF-Request Correlation ID + field received in the ASCONF parameter, from the TLV being + responded to, into the ASCONF-Request Correlation ID field in + the response parameter. + V4) After processing the entire Chunk, the receiver of the ASCONF + MUST send all TLVs for both unrecognized parameters and any + other status TLVs inside the ASCONF-ACK chunk that acknowledges + the arrival and processing of the ASCONF Chunk. + V5) Update the 'Peer-Serial-Number' to the value found in the + serial number field. + C3) If the value found in the serial number is equal to the value + stored in the 'Peer-Serial-Number', the endpoint should: + + X1) Parse the ASCONF Chunk TLVs but the endpoint MUST NOT take any + action on the TLVs parsed (since it has already performed these + actions). + X2) Build a response message with the appropriate response TLVs as + specified in the ASCONF Parameter type bits, for any parameter + it does not understand or could not process. + + + + + +Stewart, et al. Expires December 2, 2006 [Page 21] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + X3) After parsing the entire Chunk, it MUST send any response TLV + errors and status with an ASCONF-ACK chunk acknowledging the + arrival and processing of the ASCONF Chunk. + X4) The endpoint MUST NOT update its 'Peer-Serial-Number'. + Note: the response to the retransmitted ASCONF MUST be the same as + the original response. This MAY mean an implementation must keep + state in order to respond with the same exact answer (including + resource considerations that may have made the implementation + refuse a request). + IMPLEMENTATION NOTE: As an optimization a receiver may wish to + save the last ASCONF-ACK for some predetermined period of time and + instead of re-processing the ASCONF (with the same serial number) + it may just re-transmit the ASCONF-ACK. It may wish to use the + arrival of a new serial number to discard the previously saved + ASCONF-ACK or any other means it may choose to expire the saved + ASCONF-ACK. + C4) Otherwise, the ASCONF Chunk is discarded since it must be either + a stale packet or from an attacker. A receiver of such a packet + MAY log the event for security purposes. + C5) In both cases C2 and C3 the ASCONF-ACK MUST be sent back to the + source address contained in the IP header of the ASCONF being + responded to. + +4.3. General rules for address manipulation + + When building TLV parameters for the ASCONF Chunk that will add or + delete IP addresses the following rules should be applied: + + D0) If an endpoint receives an ASCONF-ACK that is greater than or + equal to the next serial number to be used but no ASCONF chunk is + outstanding the endpoint MUST ABORT the association. Note that a + sequence number is greater than if it is no more than 2^^31-1 + larger than the current sequence number (using serial arithmetic). + D1) When adding an IP address to an association, the IP address is + NOT considered fully added to the association until the ASCONF-ACK + arrives. This means that until such time as the ASCONF containing + the add is acknowledged the sender MUST NOT use the new IP address + as a source for ANY SCTP packet except on carrying an ASCONF + chunk. The receiver of the add IP address request may use the + address as a destination immediately. The receiver MUST use the + path verification procedure for the added address before using + that address. The receiver MUST NOT send packets to the new + address except for the corresponding ASCONF-ACK chunk or HEARTBEAT + chunks for path verification before the new path is verified. If + the ASCONF-ACK is sent to the new address it MAY be bundled with + the HEARTBEAT chunk for path verification. + + + + + +Stewart, et al. Expires December 2, 2006 [Page 22] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + D2) After the ASCONF-ACK of an IP address add arrives, the endpoint + MAY begin using the added IP address as a source address for any + type of SCTP chunk. + D3a) If an endpoint receives an Error Cause TLV indicating that the + IP address Add or IP address Deletion parameters was not + understood, the endpoint MUST consider the operation failed and + MUST NOT attempt to send any subsequent Add or Delete requests to + the peer. + D3b) If an endpoint receives an Error Cause TLV indicating that the + IP address Set Primary IP Address parameter was not understood, + the endpoint MUST consider the operation failed and MUST NOT + attempt to send any subsequent Set Primary IP Address requests to + the peer. + D4) When deleting an IP address from an association, the IP address + MUST be considered a valid destination address for the reception + of SCTP packets until the ASCONF-ACK arrives and MUST NOT be used + as a source address for any subsequent packets. This means that + any datagrams that arrive before the ASCONF-ACK destined to the IP + address being deleted MUST be considered part of the current + association. One special consideration is that ABORT chunks + arriving destined to the IP address being deleted MUST be ignored + (see Section 4.3.1 for further details). + D5) An endpoint MUST NOT delete its last remaining IP address from an + association. In other words if an endpoint is NOT multi-homed it + MUST NOT use the delete IP address without an add IP address + preceding the delete parameter in the ASCONF chunk. Or if an + endpoint sends multiple requests to delete IP addresses it MUST + NOT delete all of the IP addresses that the peer has listed for + the requester. + D6) An endpoint MUST NOT set an IP header source address for an SCTP + packet holding the ASCONF Chunk to be the same as an address being + deleted by the ASCONF Chunk. + D7) If a request is received to delete the last remaining IP address + of a peer endpoint, the receiver MUST send an Error Cause TLV with + the error cause set to the new error code 'Request to Delete Last + Remaining IP Address'. The requested delete MUST NOT be performed + or acted upon, other than to send the ASCONF-ACK. + D8) If a request is received to delete an IP address which is also + the source address of the IP packet which contained the ASCONF + chunk, the receiver MUST reject this request. To reject the + request the receiver MUST send an Error Cause TLV set to the new + error code 'Request to Delete Source IP Address' (unless Rule D5 + has also been violated, in which case the error code 'Request to + Delete Last Remaining IP Address' is sent). + + + + + + + +Stewart, et al. Expires December 2, 2006 [Page 23] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + D9) If an endpoint receives an ADD IP address request and does not + have the local resources to add this new address to the + association, it MUST return an Error Cause TLV set to the new + error code 'Operation Refused Due to Resource Shortage'. + D10) If an endpoint receives an 'Out of Resource' error in response + to its request to ADD an IP address to an association, it must + either ABORT the association or not consider the address part of + the association. In other words if the endpoint does not ABORT + the association, it must consider the add attempt failed and NOT + use this address since its peer will treat SCTP packets destined + to the address as Out Of The Blue packets. + D11) When an endpoint receiving an ASCONF to add an IP address sends + an 'Out of Resource' in its response, it MUST also fail any + subsequent add or delete requests bundled in the ASCONF. The + receiver MUST NOT reject an ADD and then accept a subsequent + DELETE of an IP address in the same ASCONF Chunk. In other words, + once a receiver begins failing any ADD or DELETE request, it must + fail all subsequent ADD or DELETE requests contained in that + single ASCONF. + D12) When an endpoint receives a request to delete an IP address that + is the current primary address, it is an implementation decision + as to how that endpoint chooses the new primary address. + D13) When an endpoint receives a valid request to DELETE an IP + address the endpoint MUST consider the address no longer as part + of the association. It MUST NOT send SCTP packets for the + association to that address and it MUST treat subsequent packets + received from that address as Out Of The Blue. + During the time interval between sending out the ASCONF and + receiving the ASCONF-ACK it MAY be possible to receive DATA chunks + out of order. The following examples illustrate these problems: + + + + Endpoint-A Endpoint-Z + ---------- ---------- + ASCONF[Add-IP:X]------------------------------> + /--ASCONF-ACK + / + /--------/---New DATA: + / / Destination + <-------------------/ / IP:X + / + <--------------------------/ + + + In the above example we see a new IP address (X) being added to the + Endpoint-A. However due to packet re-ordering in the network a new + DATA chunk is sent and arrives at Endpoint-A before the ASCONF-ACK + + + +Stewart, et al. Expires December 2, 2006 [Page 24] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + confirming the add of the address to the association. + + A similar problem exists with the deletion of an IP address as + follows: + + + Endpoint-A Endpoint-Z + ---------- ---------- + /------------New DATA: + / Destination + / IP:X + ASCONF [DEL-IP:X]---------/----------------> + <-----------------/------------------ASCONF-ACK + / + / + <-------------/ + + In this example we see a DATA chunk destined to the IP:X (which is + about to be deleted) arriving after the deletion is complete. For + the ADD case an endpoint SHOULD consider the newly adding IP address + valid for the association to receive data from during the interval + when awaiting the ASCONF-ACK. The endpoint MUST NOT source data from + this new address until the ASCONF-ACK arrives but it may receive out + of order data as illustrated and MUST NOT treat this data as an OOTB + datagram (please see RFC2960 [RFC2960] section 8.4). It MAY drop the + data silently or it MAY consider it part of the association but it + MUST NOT respond with an ABORT. + + For the DELETE case, an endpoint MAY respond to the late arriving + DATA packet as an OOTB datagram or it MAY hold the deleting IP + address for a small period of time as still valid. If it treats the + DATA packet as an OOTB the peer will silently discard the ABORT + (since by the time the ABORT is sent the peer will have removed the + IP address from this association). If the endpoint elects to hold + the IP address valid for a period of time, it MUST NOT hold it valid + longer than 2 RTO intervals for the destination being removed. + +4.3.1. A special case for OOTB ABORT chunks + + Another case worth mentioning is illustrated below: + + + + + + + + + + + +Stewart, et al. Expires December 2, 2006 [Page 25] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + Endpoint-A Endpoint-Z + ---------- ---------- + + New DATA:------------\ + Source IP:X \ + \ + ASCONF-REQ[DEL-IP:X]----\------------------> + \ /---------ASCONF-ACK + \ / + \----/-----------> OOTB + (Ignored <---------------------/-------------ABORT + by rule D4) / + <---------------------/ + + + For this case, during the deletion of an IP address, an Abort MUST be + ignored if the destination address of the Abort message is that of a + destination being deleted. + +4.3.2. A special case for changing an address. + + In some instances the sender may only have one IP address in an + association that is being renumbered. When this occurs, the sender + may not be able to send to the peer the appropriate ADD/DELETE pair + and use the old address as a source in the IP header. For this + reason the sender MUST fill in the Address Parameter field with an + address that is part of the association (in this case the one being + deleted). This will allow the receiver to locate the association + without using the source address found in the IP header. + + The receiver of such a chunk MUST always first use the source address + found in the IP header in looking up the association. The receiver + should attempt to use the address found in the Address Bytes field + only if the lookup fails using the source address from the IP header. + The receiver MUST reply to the source address of the packet in this + case which is the new address that was added by the ASCONF (since the + old address is no longer a part of the association after processing). + +4.4. Setting of the primary address + + A sender of this option may elect to send this combined with a + deletion or addition of an address. A sender SHOULD only send a set + primary request to an address that is already considered part of the + association. In other words if a sender combines a set primary with + an add of a new IP address the set primary will be discarded unless + the add request is to be processed BEFORE the set primary (i.e. it + precedes the set primary). + + + + +Stewart, et al. Expires December 2, 2006 [Page 26] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + A request to set primary MAY also appear in an INIT or INIT-ACK + chunk. This can give advice to the peer endpoint as to which of its + addresses the sender of the INIT or INIT-ACK would prefer to be used + as the primary address. + + The request to set an address as the primary path is an option the + receiver SHOULD perform. It is considered advice to the receiver of + the best destination address to use in sending SCTP packets (in the + requesters view). If a request arrives that asks the receiver to set + an address as primary that does not exist, the receiver should NOT + honor the request, leaving its existing primary address unchanged. + + +5. Security Considerations + + The addition and or deletion of an IP address to an existing + association does provide an additional mechanism by which existing + associations can be hijacked. Therefore this document requires the + use of the authentication mechanism defined in SCTP-AUTH [I-D.ietf- + tsvwg-sctp-auth] to limit the ability of an attacker to hijack an + association. + + Hijacking an association by using the addition and deletion of an IP + address is only possible for an attacker who is able to intercept the + initial two packets of the association setup when the SCTP-AUTH + extension is used without pre-shared keys.. If such a threat is + considered a possibility, then the SCTP-AUTH [I-D.ietf-tsvwg-sctp- + auth] extension MUST be used with a preconfigured shared end-point + pair key to mitigate this threat. For a more detailed analysis see + SCTP-AUTH [I-D.ietf-tsvwg-sctp-auth]. + + If an SCTP endpoint that supports this extension receives an INIT + that indicates that the peer supports the ASCONF extension but does + NOT support the SCTP-AUTH [I-D.ietf-tsvwg-sctp-auth] extension, the + receiver of such an INIT MUST send an ABORT in response to such an + INIT. Note that an implementation is allowed to silently discard + such an INIT as an option as well but under NO circumstance is an + implementation allowed to proceed with the association setup by + sending an INIT-ACK in response. + + An implementation that receives an INIT-ACK that indicates that the + peer does not support the SCTP-AUTH [I-D.ietf-tsvwg-sctp-auth] + extension MUST NOT send the COOKIE-ECHO to establish the association. + Instead the implementation MUST discard the INIT-ACK and report to + the upper layer user that an association cannot be established + destroying the TCB. + + + + + +Stewart, et al. Expires December 2, 2006 [Page 27] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + +6. IANA considerations + + This document defines the following new SCTP parameters, chunks and + errors: + + o Two new chunk types, + o Seven parameter types, and + o Five new SCTP error causes. + + One of the two new chunk types must come from the range of chunk + types where the upper two bits are one, we recommend 0xC1 but any + other available code point with the upper bits set is also + acceptable. The second chunk type must come from the range where + only the upper bit is set to one. We recommend 0x80 but any other + available code point with the upper bit set is also acceptable. The + suggested chunk types are listed in Table 1. + + All but one of the parameter types must come from the range of types + where the upper two bits are set, we recommend 0xC001 - 0xC006, as + specified in this document. The other parameter type must come from + the 0x8000 range, we recommend 0x8008. Note that for any of these + values a different unique parameter type may be assigned by IANA as + long as the upper bits correspond to the ones specified in this + document. The suggested parameter types are listed in Table 2, Table + 3, and Table 4. + + The five new error causes can be any value, in this document we have + used 0x0100-0x0104 in an attempt to separate these from the common + ranges of error codes. Any other unassigned values are also + acceptable. The suggested error causes are listed in Table 5. + + This document also defines a Adaptation code point. The adaptation + code point is a 32 bit integer that is assigned by IANA through an + IETF Consensus action as defined in RFC2434 [RFC2434]. + + +7. Acknowledgments + + The authors wish to thank Jon Berger, Greg Kendall, Seok Koh, Peter + Lei, John Loughney, Ivan Arias Rodriguez, Renee Revis, Marshall Rose, + Chip Sharp, and Irene Ruengeler for their invaluable comments. + + The authors would also like to give special mention to Maria-Carmen + Belinchon and Ian Rytina for there early contributions to this + document and their thoughtful comments. + + + + + + +Stewart, et al. Expires December 2, 2006 [Page 28] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + +8. References + + [RFC2026] Bradner, S., "The Internet Standards Process -- Revision + 3", BCP 9, RFC 2026, October 1996. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC2402] Kent, S. and R. Atkinson, "IP Authentication Header", + RFC 2402, November 1998. + + [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an + IANA Considerations Section in RFCs", BCP 26, RFC 2434, + October 1998. + + [RFC2629] Rose, M., "Writing I-Ds and RFCs using XML", RFC 2629, + June 1999. + + [RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C., + Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M., + Zhang, L., and V. Paxson, "Stream Control Transmission + Protocol", RFC 2960, October 2000. + + [I-D.ietf-tsvwg-sctp-auth] + Tuexen, M., "Authenticated Chunks for Stream Control + Transmission Protocol (SCTP)", + draft-ietf-tsvwg-sctp-auth-02 (work in progress), + March 2006. + + +Appendix A. Abstract Address Handling + +A.1. General remarks + + The following text provides a working definition of the endpoint + notion to discuss address reconfiguration. It is not intended to + restrict implementations in any way, its goal is to provide as set of + definitions only. Using these definitions should make a discussion + about address issues easier. + +A.2. Generalized endpoints + + A generalized endpoint is a pair of a set of IP addresses and a port + number at any given point of time. The precise definition is as + follows: + + A generalized endpoint gE at time t is given by + + + + +Stewart, et al. Expires December 2, 2006 [Page 29] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + gE(t) = ({IP1, ..., IPn}, Port) + + where {IP1, ..., IPn} is a non empty set of IP addresses. + + Please note that the dynamic addition and deletion of IP-addresses + described in this document allows the set of IP-addresses of a + generalized endpoint to be changed at some point of time. The port + number can never be changed. + + The set of IP addresses of a generalized endpoint gE at a time t is + defined as + + Addr(gE)(t) = {IP1, ..., IPn} + + if gE(t) = ({IP1, ..., IPn}, Port) holds at time t. + + The port number of a generalized endpoint gE is defined as + + Port(gE) = Port + + if gE(t) = ({IP1, ..., IPn}, Port) holds at time t. + + There is one fundamental rule which restricts all generalized + endpoints: + + For two different generalized endpoints gE' and gE'' with the same + port number Port(gE') = Port(gE'') the address sets Addr(gE')(t) and + Addr(gE'')(t) must be disjoint at every point of time. + +A.3. Associations + + Associations consists of two generalized endpoints and the two + address sets known by the peer at any time. The precise definition + is as follows: + + An association A between to different generalized endpoints gE' and + gE'' is given by + + A = (gE', S', gE'', S'') + + where S'(t) and S''(t) are set of addresses at any time t such that + S'(t) is a non-empty subset of Addr(gE')(t) and S''(t) is a non-empty + subset of Addr(gE'')(t). + + If A = (gE', S', gE'', S'') is an association between the generalized + endpoints gE' and gE'' the following notion is used: + + Addr(A, gE') = S' and Addr(A, gE'') = S''. + + + +Stewart, et al. Expires December 2, 2006 [Page 30] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + If the dependency on time is important the notion Addr(A, gE')(t) = + S'(t) will be used. + + If A is an association between gE' and gE'' then Addr(A, gE') is the + subset of IP addresses of gE' which is known by gE'' and used by gE'. + + Association establishment between gE' and gE'' can be seen as: + + 1. gE' and gE'' do exist before the association. + 2. If an INIT has to be send from gE' to gE'' address scoping rules + and other limitations are applied to calculate the subset S' from + Addr(gE'). The addresses of S' are included in the INIT chunk. + 3. If an INIT-ACK has to be send from gE'' to gE' address scoping + rules and other limitations are applied to calculate the subset + S'' from Addr(gE''). The addresses of S'' are included in the + INIT-ACK chunk. + 4. After the handshake the association A = (gE', S', gE'', S'') has + been established. + 5. Right after the association establishment Addr(A, gE') and + Addr(A, gE'') are the addresses which have been seen on the wire + during the handshake. + +A.4. Relationship with RFC 2960 + + RFC2960 [RFC2960] defines the notion of an endpoint. This subsection + will show that these endpoints are also (special) generalized + endpoints. + + RFC2960 [RFC2960] has no notion of address scoping or other address + handling limitations and provides no mechanism to change the + addresses of an endpoint. + + This means that an endpoint is simply a generalized endpoint which + does not depend on the time. Neither the Port nor the address list + changes. + + During association setup no address scoping rules or other + limitations will be applied. This means that for an association A + between two endpoints gE' and gE'' the following is true: + + Addr(A, gE') = Addr(gE') and Addr(A, gE'') = Addr(gE''). + +A.5. Rules for address manipulation + + The rules for address manipulation can now be stated in a simple way: + 1. An address can be added to a generalized endpoint gE only if this + address is not an address of a different generalized endpoint + with the same port number. + + + +Stewart, et al. Expires December 2, 2006 [Page 31] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + 2. An address can be added to an association A with generalized + endpoint gE if it has been added to the generalized endpoint gE + first. This means that the address must be an element of + Addr(gE) first and then it can become an element of Addr(A, gE). + But this is not necessary. If the association does not allow the + reconfiguration of the addresses only Addr(gE) can be modified. + 3. An address can be deleted from an association A with generalized + endpoint gE as long as Addr(A, gE) stays non-empty. + 4. An address can be deleted from an generalized endpoint gE only if + it has been removed from all associations having gE as a + generalized endpoint. + + These rules simply make sure that the rules for the endpoints and + associations given above are always fulfilled. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Expires December 2, 2006 [Page 32] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + +Authors' Addresses + + Randall R. Stewart + Cisco Systems, Inc. + 4875 Forest Drive + Suite 200 + Columbia, SC 29206 + US + + Phone: + Email: rrs@cisco.com + + + Michael A. Ramalho + Cisco Systems, Inc. + 1802 Rue de la Porte + Wall Township, NJ 07719-3784 + USA + + Phone: +1.732.449.5762 + Email: mramalho@cisco.com + + + Qiaobing Xie + Motorola, Inc. + 1501 W. Shure Drive, #2309 + Arlington Heights, IL 60004 + USA + + Phone: +1-847-632-3028 + Email: qxie1@email.mot.com + + + Michael Tuexen + Univ. of Applied Sciences Muenster + Stegerwaldstr. 39 + 48565 Steinfurt + Germany + + Email: tuexen@fh-muenster.de + + + + + + + + + + + +Stewart, et al. Expires December 2, 2006 [Page 33] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + + Phillip T. Conrad + University of Delaware + Department of Computer and Information Sciences + Newark, DE 19716 + US + + Phone: +1 302 831 8622 + Email: conrad@acm.org + URI: http://www.cis.udel.edu/~pconrad + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Expires December 2, 2006 [Page 34] + +Internet-Draft SCTP Dynamic Address Reconfiguration May 2006 + + +Intellectual Property Statement + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at + ietf-ipr@ietf.org. + + +Disclaimer of Validity + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM 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. + + +Copyright Statement + + Copyright (C) The Internet Society (2006). This document is subject + to the rights, licenses and restrictions contained in BCP 78, and + except as set forth therein, the authors retain all their rights. + + +Acknowledgment + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + +Stewart, et al. Expires December 2, 2006 [Page 35] + + diff --git a/doc/draft-ietf-tsvwg-sctpsocket-14.txt b/doc/draft-ietf-tsvwg-sctpsocket-14.txt new file mode 100644 index 0000000..74ee668 --- /dev/null +++ b/doc/draft-ietf-tsvwg-sctpsocket-14.txt @@ -0,0 +1,4873 @@ + + + +Network Working Group R. Stewart +Internet-Draft Cisco Systems, Inc. +Expires: June 14, 2007 Q. Xie + Motorola, Inc. + L. Yarroll + TimeSys Corp + K. Poon + Sun Microsystems, Inc. + M. Tuexen + Univ. of Applied Sciences Muenster + December 11, 2006 + + + Sockets API Extensions for Stream Control Transmission Protocol (SCTP) + draft-ietf-tsvwg-sctpsocket-14.txt + +Status of this Memo + + By submitting this Internet-Draft, each author represents that any + applicable patent or other IPR claims of which he or she is aware + have been or will be disclosed, and any of which he or she becomes + aware will be disclosed, in accordance with Section 6 of BCP 79. + + 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 June 14, 2007. + +Copyright Notice + + Copyright (C) The IETF Trust (2006). + +Abstract + + This document describes a mapping of the Stream Control Transmission + + + +Stewart, et al. Expires June 14, 2007 [Page 1] + +Internet-Draft SCTP sockets API December 2006 + + + Protocol SCTP into a sockets API. The benefits of this mapping + include compatibility for TCP applications, access to new SCTP + features and a consolidated error and event notification scheme. + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 5 + 2. Conventions . . . . . . . . . . . . . . . . . . . . . . . . . 6 + 2.1. Data Types . . . . . . . . . . . . . . . . . . . . . . . . 6 + 3. one-to-many style Interface . . . . . . . . . . . . . . . . . 6 + 3.1. Basic Operation . . . . . . . . . . . . . . . . . . . . . 6 + 3.1.1. socket() - one-to-many style socket . . . . . . . . . 7 + 3.1.2. bind() - one-to-many style socket . . . . . . . . . . 8 + 3.1.3. listen() - One-to-many style socket . . . . . . . . . 9 + 3.1.4. sendmsg() and recvmsg() - one-to-many style socket . . 9 + 3.1.5. close() - one-to-many style socket . . . . . . . . . . 11 + 3.1.6. connect() - one-to-many style socket . . . . . . . . . 11 + 3.2. Implicit Association Setup . . . . . . . . . . . . . . . . 12 + 3.3. Non-blocking mode . . . . . . . . . . . . . . . . . . . . 13 + 3.4. Special considerations . . . . . . . . . . . . . . . . . . 13 + 4. one-to-one style Interface . . . . . . . . . . . . . . . . . . 15 + 4.1. Basic Operation . . . . . . . . . . . . . . . . . . . . . 15 + 4.1.1. socket() - one-to-one style socket . . . . . . . . . . 16 + 4.1.2. bind() - one-to-one style socket . . . . . . . . . . . 16 + 4.1.3. listen() - one-to-one style socket . . . . . . . . . . 17 + 4.1.4. accept() - one-to-one style socket . . . . . . . . . . 18 + 4.1.5. connect() - one-to-one style socket . . . . . . . . . 18 + 4.1.6. close() - one-to-one style socket . . . . . . . . . . 19 + 4.1.7. shutdown() - one-to-one style socket . . . . . . . . . 19 + 4.1.8. sendmsg() and recvmsg() - one-to-one style socket . . 20 + 4.1.9. getpeername() . . . . . . . . . . . . . . . . . . . . 20 + 5. Data Structures . . . . . . . . . . . . . . . . . . . . . . . 21 + 5.1. The msghdr and cmsghdr Structures . . . . . . . . . . . . 21 + 5.2. SCTP msg_control Structures . . . . . . . . . . . . . . . 22 + 5.2.1. SCTP Initiation Structure (SCTP_INIT) . . . . . . . . 23 + 5.2.2. SCTP Header Information Structure (SCTP_SNDRCV) . . . 24 + 5.2.3. Extended SCTP Header Information Structure + (SCTP_EXTRCV) . . . . . . . . . . . . . . . . . . . . 27 + 5.3. SCTP Events and Notifications . . . . . . . . . . . . . . 31 + 5.3.1. SCTP Notification Structure . . . . . . . . . . . . . 31 + 5.4. Ancillary Data Considerations and Semantics . . . . . . . 42 + 5.4.1. Multiple Items and Ordering . . . . . . . . . . . . . 42 + 5.4.2. Accessing and Manipulating Ancillary Data . . . . . . 42 + 5.4.3. Control Message Buffer Sizing . . . . . . . . . . . . 43 + 6. Common Operations for Both Styles . . . . . . . . . . . . . . 44 + 6.1. send(), recv(), sendto(), recvfrom() . . . . . . . . . . . 44 + 6.2. setsockopt(), getsockopt() . . . . . . . . . . . . . . . . 45 + + + +Stewart, et al. Expires June 14, 2007 [Page 2] + +Internet-Draft SCTP sockets API December 2006 + + + 6.3. read() and write() . . . . . . . . . . . . . . . . . . . . 46 + 6.4. getsockname() . . . . . . . . . . . . . . . . . . . . . . 46 + 7. Socket Options . . . . . . . . . . . . . . . . . . . . . . . . 47 + 7.1. Read / Write Options . . . . . . . . . . . . . . . . . . . 48 + 7.1.1. Retransmission Timeout Parameters (SCTP_RTOINFO) . . . 48 + 7.1.2. Association Parameters (SCTP_ASSOCINFO) . . . . . . . 49 + 7.1.3. Initialization Parameters (SCTP_INITMSG) . . . . . . . 51 + 7.1.4. SO_LINGER . . . . . . . . . . . . . . . . . . . . . . 51 + 7.1.5. SCTP_NODELAY . . . . . . . . . . . . . . . . . . . . . 51 + 7.1.6. SO_RCVBUF . . . . . . . . . . . . . . . . . . . . . . 51 + 7.1.7. SO_SNDBUF . . . . . . . . . . . . . . . . . . . . . . 52 + 7.1.8. Automatic Close of associations (SCTP_AUTOCLOSE) . . . 52 + 7.1.9. Set Peer Primary Address + (SCTP_SET_PEER_PRIMARY_ADDR) . . . . . . . . . . . . . 52 + 7.1.10. Set Primary Address (SCTP_PRIMARY_ADDR) . . . . . . . 53 + 7.1.11. Set Adaptation Layer Indicator + (SCTP_ADAPTATION_LAYER) . . . . . . . . . . . . . . . 53 + 7.1.12. Enable/Disable message fragmentation + (SCTP_DISABLE_FRAGMENTS) . . . . . . . . . . . . . . . 53 + 7.1.13. Peer Address Parameters (SCTP_PEER_ADDR_PARAMS) . . . 54 + 7.1.14. Set default send parameters + (SCTP_DEFAULT_SEND_PARAM) . . . . . . . . . . . . . . 56 + 7.1.15. Set notification and ancillary events (SCTP_EVENTS) . 57 + 7.1.16. Set/clear IPv4 mapped addresses + (SCTP_I_WANT_MAPPED_V4_ADDR) . . . . . . . . . . . . . 57 + 7.1.17. Set the maximum fragmentation size (SCTP_MAXSEG) . . . 57 + 7.1.18. Add a chunk that must be authenticated + (SCTP_AUTH_CHUNK) . . . . . . . . . . . . . . . . . . 57 + 7.1.19. Get or set the list of supported HMAC Identifiers + (SCTP_HMAC_IDENT) . . . . . . . . . . . . . . . . . . 58 + 7.1.20. Set a shared key (SCTP_AUTH_KEY) . . . . . . . . . . . 58 + 7.1.21. Get or set the active shared key + (SCTP_AUTH_ACTIVE_KEY) . . . . . . . . . . . . . . . . 59 + 7.1.22. Delete a shared key (SCTP_AUTH_DELETE_KEY) . . . . . . 59 + 7.1.23. Get or set delayed ack timer + (SCTP_DELAYED_ACK_TIME) . . . . . . . . . . . . . . . 60 + 7.1.24. Get or set fragmented interleave + (SCTP_FRAGMENT_INTERLEAVE) . . . . . . . . . . . . . . 60 + 7.1.25. Set or Get the sctp partial delivery point + (SCTP_PARTIAL_DELIVERY_POINT) . . . . . . . . . . . . 61 + 7.1.26. Set or Get the use of extended receive info + (SCTP_USE_EXT_RCVINFO) . . . . . . . . . . . . . . . . 61 + 7.1.27. Set or Get the auto asconf flag (SCTP_AUTO_ASCONF) . . 61 + 7.1.28. Set or Get the maximum burst (SCTP_MAX_BURST) . . . . 61 + 7.1.29. Set or Get the default context (SCTP_CONTEXT) . . . . 62 + 7.1.30. Enable or disable explicit EOR marking + (SCTP_EXPLICIT_EOR) . . . . . . . . . . . . . . . . . 62 + 7.2. Read-Only Options . . . . . . . . . . . . . . . . . . . . 62 + + + +Stewart, et al. Expires June 14, 2007 [Page 3] + +Internet-Draft SCTP sockets API December 2006 + + + 7.2.1. Association Status (SCTP_STATUS) . . . . . . . . . . . 62 + 7.2.2. Peer Address Information (SCTP_GET_PEER_ADDR_INFO) . . 64 + 7.2.3. Get the list of chunks the peer requires to be + authenticated (SCTP_PEER_AUTH_CHUNKS) . . . . . . . . 65 + 7.2.4. Get the list of chunks the local endpoint requires + to be authenticated (SCTP_LOCAL_AUTH_CHUNKS) . . . . . 65 + 7.2.5. Get the list of current associations + (SCTP_GET_ASOC_ID_LIST) . . . . . . . . . . . . . . . 65 + 7.3. Ancillary Data and Notification Interest Options . . . . . 66 + 8. New Interfaces . . . . . . . . . . . . . . . . . . . . . . . . 68 + 8.1. sctp_bindx() . . . . . . . . . . . . . . . . . . . . . . . 69 + 8.2. Branched-off Association . . . . . . . . . . . . . . . . . 70 + 8.3. sctp_getpaddrs() . . . . . . . . . . . . . . . . . . . . . 70 + 8.4. sctp_freepaddrs() . . . . . . . . . . . . . . . . . . . . 71 + 8.5. sctp_getladdrs() . . . . . . . . . . . . . . . . . . . . . 71 + 8.6. sctp_freeladdrs() . . . . . . . . . . . . . . . . . . . . 72 + 8.7. sctp_sendmsg() . . . . . . . . . . . . . . . . . . . . . . 72 + 8.8. sctp_recvmsg() . . . . . . . . . . . . . . . . . . . . . . 73 + 8.9. sctp_connectx() . . . . . . . . . . . . . . . . . . . . . 73 + 8.10. sctp_send() . . . . . . . . . . . . . . . . . . . . . . . 74 + 8.11. sctp_sendx() . . . . . . . . . . . . . . . . . . . . . . . 75 + 8.12. sctp_getaddrlen . . . . . . . . . . . . . . . . . . . . . 76 + 9. Preprocessor Constants . . . . . . . . . . . . . . . . . . . . 76 + 10. IANA considerations . . . . . . . . . . . . . . . . . . . . . 77 + 11. Security Considerations . . . . . . . . . . . . . . . . . . . 77 + 12. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 77 + 13. Normative references . . . . . . . . . . . . . . . . . . . . . 78 + Appendix A. one-to-one style Code Example . . . . . . . . . . . . 78 + Appendix B. one-to-many style Code Example . . . . . . . . . . . 84 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 85 + Intellectual Property and Copyright Statements . . . . . . . . . . 87 + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 4] + +Internet-Draft SCTP sockets API December 2006 + + +1. Introduction + + The sockets API has provided a standard mapping of the Internet + Protocol suite to many operating systems. Both TCP RFC793 [RFC0793] + and UDP RFC768 [RFC0768] have benefited from this standard + representation and access method across many diverse platforms. SCTP + is a new protocol that provides many of the characteristics of TCP + but also incorporates semantics more akin to UDP. This document + defines a method to map the existing sockets API for use with SCTP, + providing both a base for access to new features and compatibility so + that most existing TCP applications can be migrated to SCTP with few + (if any) changes. + + There are three basic design objectives: + + 1) Maintain consistency with existing sockets APIs: + We define a sockets mapping for SCTP that is consistent with other + sockets API protocol mappings (for instance, UDP, TCP, IPv4, and + IPv6). + 2) Support a one-to-many style interface + This set of semantics is similar to that defined for connection- + less protocols, such as UDP. A one-to-many style SCTP socket + should be able to control multiple SCTP associations. This is + similar to an UDP socket, which can communicate with many peer end + points. Each of these associations is assigned an association ID + so that an applications can use the ID to differentiate them. + Note that SCTP is connection-oriented in nature, and it does not + support broadcast or multicast communications, as UDP does. + 3) Support a one-to-one style interface + This interface supports a similar semantics as sockets for + connection-oriented protocols, such as TCP. A one-to-one style + SCTP socket should only control one SCTP association. + One purpose of defining this interface is to allow existing + applications built on other connection-oriented protocols be + ported to use SCTP with very little effort. And developers + familiar with those semantics can easily adapt to SCTP. Another + purpose is to make sure that existing mechanisms in most OSes to + deal with socket, such as select(), should continue to work with + this style of socket. + Extensions are added to this mapping to provide mechanisms to + exploit new features of SCTP. + + Goals 2 and 3 are not compatible, so in this document we define two + modes of mapping, namely the one-to-many style mapping and the one- + to-one style mapping. These two modes share some common data + structures and operations, but will require the use of two different + application programming styles. Note that all new SCTP features can + be used with both styles of socket. The decision on which one to use + + + +Stewart, et al. Expires June 14, 2007 [Page 5] + +Internet-Draft SCTP sockets API December 2006 + + + depends mainly on the nature of applications. + + A mechanism is defined to extract a one-to-many style SCTP + association into a one-to-one style socket. + + Some of the SCTP mechanisms cannot be adequately mapped to existing + socket interface. In some cases, it is more desirable to have new + interface instead of using existing socket calls. Section 8 of this + document describes those new interface. + + +2. Conventions + +2.1. Data Types + + Whenever possible, data types from Draft 6.6 (March 1997) of POSIX + 1003.1g are used: uintN_t means an unsigned integer of exactly N bits + (e.g., uint16_t). We also assume the argument data types from + 1003.1g when possible (e.g., the final argument to setsockopt() is a + size_t value). Whenever buffer sizes are specified, the POSIX 1003.1 + size_t data type is used. + + +3. one-to-many style Interface + + The one-to-many style interface has the following characteristics: + + A) Outbound association setup is implicit. + + B) Messages are delivered in complete messages (with one notable + exception). + + C) There is a 1 to MANY relationship between socket and association. + +3.1. Basic Operation + + A typical server in this style uses the following socket calls in + sequence to prepare an endpoint for servicing requests: + + 1. socket() + 2. bind() + 3. listen() + 4. recvmsg() + 5. sendmsg() + 6. close() + + A typical client uses the following calls in sequence to setup an + association with a server to request services: + + + +Stewart, et al. Expires June 14, 2007 [Page 6] + +Internet-Draft SCTP sockets API December 2006 + + + 1. socket() + 2. sendmsg() + 3. recvmsg() + 4. close() + + In this style, by default, all the associations connected to the + endpoint are represented with a single socket. Each associations is + assigned an association ID (type is sctp_assoc_t) so that an + application can use it to differentiate between them. In some + implementations, the peer endpoints addresses can also be used for + this purpose. But this is not required for performance reasons. If + an implementation does not support using addresses to differentiate + between different associations, the sendto() call can only be used to + setup an association implicitly. It cannot be used to send data to + an established association as the association ID cannot be specified. + + Once as association ID is assigned to an SCTP association, that ID + will not be reused until the application explicitly terminates the + association. The resources belonged to that association will not be + freed until that happens. This is similar to the close() operation + on a normal socket. The only exception is when the SCTP_AUTOCLOSE + option (section 7.1.8) is set. In this case, after the association + is terminated gracefully automatically, the association ID assigned + to it can be reused. All applications using this option should be + aware of this to avoid the possible problem of sending data to an + incorrect peer end point. + + If the server or client wishes to branch an existing association off + to a separate socket, it is required to call sctp_peeloff() and in + the parameter specifies the association identification. The + sctp_peeloff() call will return a new socket which can then be used + with recv() and send() functions for message passing. See + Section 8.2 for more on branched-off associations. + + Once an association is branched off to a separate socket, it becomes + completely separated from the original socket. All subsequent + control and data operations to that association must be done through + the new socket. For example, the close operation on the original + socket will not terminate any associations that have been branched + off to a different socket. + + We will discuss the one-to-many style socket calls in more details in + the following subsections. + +3.1.1. socket() - one-to-many style socket + + Applications use socket() to create a socket descriptor to represent + an SCTP endpoint. + + + +Stewart, et al. Expires June 14, 2007 [Page 7] + +Internet-Draft SCTP sockets API December 2006 + + + The syntax is, + + sd = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + + or, + + sd = socket(PF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP); + + Here, SOCK_SEQPACKET indicates the creation of a one-to-many style + socket. + + The first form creates an endpoint which can use only IPv4 addresses, + while, the second form creates an endpoint which can use both IPv6 + and IPv4 addresses. + +3.1.2. bind() - one-to-many style socket + + Applications use bind() to specify which local address the SCTP + endpoint should associate itself with. + + An SCTP endpoint can be associated with multiple addresses. To do + this, sctp_bindx() is introduced in section Section 8.1 to help + applications do the job of associating multiple addresses. + + These addresses associated with a socket are the eligible transport + addresses for the endpoint to send and receive data. The endpoint + will also present these addresses to its peers during the association + initialization process, see RFC2960 [RFC2960]. + + After calling bind(), if the endpoint wishes to accept new + associations on the socket, it must call listen() (see section + Section 3.1.3). + + The syntax of bind() is, + + ret = bind(int sd, struct sockaddr *addr, socklen_t addrlen); + + sd - the socket descriptor returned by socket(). + addr - the address structure (struct sockaddr_in or struct + sockaddr_in6 RFC2553 [RFC2553]). + addrlen - the size of the address structure. + + If sd is an IPv4 socket, the address passed must be an IPv4 address. + If the sd is an IPv6 socket, the address passed can either be an IPv4 + or an IPv6 address. + + Applications cannot call bind() multiple times to associate multiple + addresses to an endpoint. After the first call to bind(), all + + + +Stewart, et al. Expires June 14, 2007 [Page 8] + +Internet-Draft SCTP sockets API December 2006 + + + subsequent calls will return an error. + + If addr is specified as a wildcard (INADDR_ANY for an IPv4 address, + or as IN6ADDR_ANY_INIT or in6addr_any for an IPv6 address), the + operating system will associate the endpoint with an optimal address + set of the available interfaces. + + If a bind() is not called prior to a sendmsg() call that initiates a + new association, the system picks an ephemeral port and will choose + an address set equivalent to binding with a wildcard address. One of + those addresses will be the primary address for the association. + This automatically enables the multi-homing capability of SCTP. + +3.1.3. listen() - One-to-many style socket + + By default, new associations are not accepted for one-to-many style + sockets. An application uses listen() to mark a socket as being able + to accept new associations. The syntax is, + + + int listen(int sd, int backlog); + + + sd - the socket descriptor of the endpoint. + backlog - if backlog is non-zero, enable listening else disable + listening. + + Note that one-to-many style socket consumers do not need to call + accept to retrieve new associations. Calling accept() on a one-to- + many style socket should return EOPNOTSUPP. Rather, new associations + are accepted automatically, and notifications of the new associations + are delivered via recvmsg() with the SCTP_ASSOC_CHANGE event (if + these notifications are enabled). Clients will typically not call + listen(), so that they can be assured that the only associations on + the socket will be ones they actively initiated. Server or peer-to- + peer sockets, on the other hand, will always accept new associations, + so a well-written application using server one-to-many style sockets + must be prepared to handle new associations from unwanted peers. + + Also note that the SCTP_ASSOC_CHANGE event provides the association + ID for a new association, so if applications wish to use the + association ID as input to other socket calls, they should ensure + that the SCTP_ASSOC_CHANGE event is enabled. + +3.1.4. sendmsg() and recvmsg() - one-to-many style socket + + An application uses sendmsg() and recvmsg() call to transmit data to + and receive data from its peer. + + + +Stewart, et al. Expires June 14, 2007 [Page 9] + +Internet-Draft SCTP sockets API December 2006 + + + ssize_t sendmsg(int sd, const struct msghdr *message, int flags); + + ssize_t recvmsg(int sd, struct msghdr *message, int flags); + + sd - the socket descriptor of the endpoint. + message: pointer to the msghdr structure which contains a single + user message and possibly some ancillary data. See Section 5 for + complete description of the data structures. + flags - No new flags are defined for SCTP at this level. See + Section 5 for SCTP-specific flags used in the msghdr structure. + + As we will see in Section 5, along with the user data, the ancillary + data field is used to carry the sctp_sndrcvinfo and/or the + sctp_initmsg structures to perform various SCTP functions including + specifying options for sending each user message. Those options, + depending on whether sending or receiving, include stream number, + stream sequence number, various flags, context and payload protocol + Id, etc. + + When sending user data with sendmsg(), the msg_name field in msghdr + structure will be filled with one of the transport addresses of the + intended receiver. If there is no association existing between the + sender and the intended receiver, the sender's SCTP stack will set up + a new association and then send the user data (see Section 3.2 for + more on implicit association setup). + + If a peer sends a SHUTDOWN, a SCTP_SHUTDOWN_EVENT notification will + be delivered if that notification has been enabled, and no more data + can be sent to that association. Any attempt to send more data will + cause sendmsg() to return with an ESHUTDOWN error. Note that the + socket is still open for reading at this point so it is possible to + retrieve notifications. + + When receiving a user message with recvmsg(), the msg_name field in + msghdr structure will be populated with the source transport address + of the user data. The caller of recvmsg() can use this address + information to determine to which association the received user + message belongs. Note that if SCTP_ASSOC_CHANGE events are disabled, + applications must use the peer transport address provided in the + msg_name field by recvmsg() to perform correlation to an association, + since they will not have the association ID. + + If all data in a single message has been delivered, MSG_EOR will be + set in the msg_flags field of the msghdr structure (see section + Section 5.1). + + If the application does not provide enough buffer space to completely + receive a data message, MSG_EOR will not be set in msg_flags. + + + +Stewart, et al. Expires June 14, 2007 [Page 10] + +Internet-Draft SCTP sockets API December 2006 + + + Successive reads will consume more of the same message until the + entire message has been delivered, and MSG_EOR will be set. + + If the SCTP stack is running low on buffers, it may partially deliver + a message. In this case, MSG_EOR will not be set, and more calls to + recvmsg() will be necessary to completely consume the message. Only + one message at a time per stream can be partially delivered. + + Note, if the socket is a branched-off socket that only represents one + association (see Section 3.1), the msg_name field can be used to + override the primary address when sending data. + +3.1.5. close() - one-to-many style socket + + Applications use close() to perform graceful shutdown (as described + in Section 10.1 of RFC2960 [RFC2960]) on ALL the associations + currently represented by a one-to-many style socket. + + The syntax is: + + + ret = close(int sd); + + + sd - the socket descriptor of the associations to be closed. + + To gracefully shutdown a specific association represented by the one- + to-many style socket, an application should use the sendmsg() call, + and including the SCTP_EOF flag. A user may optionally terminate an + association non-gracefully by sending with the SCTP_ABORT flag and + possibly passing a user specified abort code in the data field. Both + flags SCTP_EOF and SCTP_ABORT are passed with ancillary data (see + Section 5.2.2) in the sendmsg call. + + If sd in the close() call is a branched-off socket representing only + one association, the shutdown is performed on that association only. + +3.1.6. connect() - one-to-many style socket + + An application may use the connect() call in the one-to-many style to + initiate an association without sending data. + + The syntax is: + + ret = connect(int sd, const struct sockaddr *nam, socklen_t len); + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 11] + +Internet-Draft SCTP sockets API December 2006 + + + sd - the socket descriptor to have a new association added to. + nam - the address structure (either struct sockaddr_in or struct + sockaddr_in6 defined in RFC2553 [RFC2553]). + len - the size of the address. + Multiple connect() calls can be made on the same socket to create + multiple associations. This is different from the semantics of + connect() on a UDP socket. + +3.2. Implicit Association Setup + + Once the bind() call is complete on a one-to-many style socket, the + application can begin sending and receiving data using the sendmsg()/ + recvmsg() or sendto()/recvfrom() calls, without going through any + explicit association setup procedures (i.e., no connect() calls + required). + + Whenever sendmsg() or sendto() is called and the SCTP stack at the + sender finds that there is no association existing between the sender + and the intended receiver (identified by the address passed either in + the msg_name field of msghdr structure in the sendmsg() call or the + dest_addr field in the sendto() call), the SCTP stack will + automatically setup an association to the intended receiver. + + Upon the successful association setup a SCTP_COMM_UP notification + will be dispatched to the socket at both the sender and receiver + side. This notification can be read by the recvmsg() system call + (see Section 3.1.3). + + Note, if the SCTP stack at the sender side supports bundling, the + first user message may be bundled with the COOKIE ECHO message + RFC2960 [RFC2960]. + + When the SCTP stack sets up a new association implicitly, it first + consults the sctp_initmsg structure, which is passed along within the + ancillary data in the sendmsg() call (see Section 5.2.1 for details + of the data structures), for any special options to be used on the + new association. + + If this information is not present in the sendmsg() call, or if the + implicit association setup is triggered by a sendto() call, the + default association initialization parameters will be used. These + default association parameters may be set with respective + setsockopt() calls or be left to the system defaults. + + Implicit association setup cannot be initiated by send()/recv() + calls. + + + + + +Stewart, et al. Expires June 14, 2007 [Page 12] + +Internet-Draft SCTP sockets API December 2006 + + +3.3. Non-blocking mode + + Some SCTP users might want to avoid blocking when they call socket + interface function. + + Once all bind() calls are complete on a one-to-many style socket, the + application must set the non-blocking option by a fcntl() (such as + O_NONBLOCK). After which the sendmsg() function returns immediately, + and the success or failure of the data message (and possible + SCTP_INITMSG parameters) will be signaled by the SCTP_ASSOC_CHANGE + event with SCTP_COMM_UP or CANT_START_ASSOC. If user data could not + be sent (due to a CANT_START_ASSOC), the sender will also receive a + SCTP_SEND_FAILED event. Those event(s) can be received by the user + calling of recvmsg(). A server (having called listen()) is also + notified of an association up event by the reception of a + SCTP_ASSOC_CHANGE with SCTP_COMM_UP via the calling of recvmsg() and + possibly the reception of the first data message. + + In order to shutdown the association gracefully, the user must call + sendmsg() with no data and with the SCTP_EOF flag set. The function + returns immediately, and completion of the graceful shutdown is + indicated by an SCTP_ASSOC_CHANGE notification of type + SHUTDOWN_COMPLETE (see Section 5.3.1.1). Note that this can also be + done using the sctp_send() call described in Section 8.10. + + An application is recommended to use caution when using select() (or + poll()) for writing on a one-to-many style socket. The reason being + that interpretation of select on write is implementation specific. + Generally a positive return on a select on write would only indicate + that one of the associations represented by the one-to-many socket is + writable. An application that writes after the select return may + still block since the association that was writeable is not the + destination association of the write call. Likewise select (or + poll()) for reading from a one-to-many socket will only return an + indication that one of the associations represented by the socket has + data to be read. + + An application that wishes to know that a particular association is + ready for reading or writing should either use the one-to-one style + or use the sctp_peeloff() (see Section 8.2) function to separate the + association of interest from the one-to-many socket. + +3.4. Special considerations + + The fact that a one-to-many style socket can provide access to many + SCTP associations through a single socket descriptor has important + implications for both application programmers and system programmers + implementing this API. A key issue is how buffer space inside the + + + +Stewart, et al. Expires June 14, 2007 [Page 13] + +Internet-Draft SCTP sockets API December 2006 + + + sockets layer is managed. Because this implementation detail + directly affects how application programmers must write their code to + ensure correct operation and portability, this section provides some + guidance to both implementors and application programmers. + + An important feature that SCTP shares with TCP is flow control: + specifically, a sender may not send data faster than the receiver can + consume it. + + For TCP, flow control is typically provided for in the sockets API as + follows. If the reader stops reading, the sender queues messages in + the socket layer until it uses all of its socket buffer space + allocation creating a "stalled connection". Further attempts to + write to the socket will block or return the error EAGAIN or + EWOULDBLOCK for a non-blocking socket. At some point, either the + connection is closed, or the receiver begins to read again freeing + space in the output queue. + + For one-to-one style SCTP sockets (this includes sockets descriptors + that were separated from a one-to-many style socket with + sctp_peeloff()) the behavior is identical. For one-to-many style + SCTP sockets, the fact that we have multiple associations on a single + socket makes the situation more complicated. If the implementation + uses a single buffer space allocation shared by all associations, a + single stalled association can prevent the further sending of data on + all associations active on a particular one-to-many style socket. + + For a blocking socket, it should be clear that a single stalled + association can block the entire socket. For this reason, + application programmers may want to use non-blocking one-to-many + style sockets. The application should at least be able to send + messages to the non-stalled associations. + + But a non-blocking socket is not sufficient if the API implementor + has chosen a single shared buffer allocation for the socket. A + single stalled association would eventually cause the shared + allocation to fill, and it would become impossible to send even to + non-stalled associations. + + The API implementor can solve this problem by providing each + association with its own allocation of outbound buffer space. Each + association should conceptually have as much buffer space as it would + have if it had its own socket. As a bonus, this simplifies the + implementation of sctp_peeloff(). + + To ensure that a given stalled association will not prevent other + non-stalled associations from being writable, application programmers + should either: + + + +Stewart, et al. Expires June 14, 2007 [Page 14] + +Internet-Draft SCTP sockets API December 2006 + + + (a) demand that the underlying implementation dedicates independent + buffer space allotments to each association (as suggested above), + or + (b) verify that their application layer protocol does not permit + large amounts of unread data at the receiver (this is true of some + request-response protocols, for example), or + (c) use one-to-one style sockets for association which may + potentially stall (either from the beginning, or by using + sctp_peeloff before sending large amounts of data that may cause a + stalled condition). + An implementation which dedicates independent buffer space for + each association should define HAVE_SCTP_MULTIBUF to 1. + + +4. one-to-one style Interface + + The goal of this style is to follow as closely as possible the + current practice of using the sockets interface for a connection + oriented protocol, such as TCP. This style enables existing + applications using connection oriented protocols to be ported to SCTP + with very little effort. + + Note that some new SCTP features and some new SCTP socket options can + only be utilized through the use of sendmsg() and recvmsg() calls, + see Section 4.1.8. Also note that some socket interfaces may not be + able to provide data on the third leg of the association set up with + this interface style. + +4.1. Basic Operation + + A typical server in one-to-one style uses the following system call + sequence to prepare an SCTP endpoint for servicing requests: + + 1. socket() + + 2. bind() + + 3. listen() + + 4. accept() + + The accept() call blocks until a new association is set up. It + returns with a new socket descriptor. The server then uses the new + socket descriptor to communicate with the client, using recv() and + send() calls to get requests and send back responses. + + Then it calls + + + + +Stewart, et al. Expires June 14, 2007 [Page 15] + +Internet-Draft SCTP sockets API December 2006 + + + 5. close() + + to terminate the association. + + A typical client uses the following system call sequence to setup an + association with a server to request services: + + 1. socket() + + 2. connect() + + After returning from connect(), the client uses send() and recv() + calls to send out requests and receive responses from the server. + + The client calls + + 3. close() + + to terminate this association when done. + +4.1.1. socket() - one-to-one style socket + + Applications calls socket() to create a socket descriptor to + represent an SCTP endpoint. + + The syntax is: + + int socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); + + or, + + int socket(PF_INET6, SOCK_STREAM, IPPROTO_SCTP); + + Here, SOCK_STREAM indicates the creation of a one-to-one style + socket. + + The first form creates an endpoint which can use only IPv4 addresses, + while the second form creates an endpoint which can use both IPv6 and + IPv4 addresses. + +4.1.2. bind() - one-to-one style socket + + Applications use bind() to pass an address to be associated with an + SCTP endpoint to the system. bind() allows only either a single + address or a IPv4 or IPv6 wildcard address to be bound. An SCTP + endpoint can be associated with multiple addresses. To do this, + sctp_bindx() is introduced in Section 8.1 to help applications do the + job of associating multiple addresses. + + + +Stewart, et al. Expires June 14, 2007 [Page 16] + +Internet-Draft SCTP sockets API December 2006 + + + These addresses associated with a socket are the eligible transport + addresses for the endpoint to send and receive data. The endpoint + will also present these addresses to its peers during the association + initialization process, see RFC2960 [RFC2960]. + + The syntax is: + + int bind(int sd, struct sockaddr *addr, socklen_t addrlen); + + sd: the socket descriptor returned by socket() call. + addr: the address structure (either struct sockaddr_in or struct + sockaddr_in6 defined in RFC2553 [RFC2553]). + addrlen: the size of the address structure. + + If sd is an IPv4 socket, the address passed must be an IPv4 address. + Otherwise, i.e., the sd is an IPv6 socket, the address passed can + either be an IPv4 or an IPv6 address. + + Applications cannot call bind() multiple times to associate multiple + addresses to the endpoint. After the first call to bind(), all + subsequent calls will return an error. + + If addr is specified as a wildcard (INADDR_ANY for an IPv4 address, + or as IN6ADDR_ANY_INIT or in6addr_any for an IPv6 address), the + operating system will associate the endpoint with an optimal address + set of the available interfaces. + + If a bind() is not called prior to the connect() call, the system + picks an ephemeral port and will choose an address set equivalent to + binding with a wildcard address. One of those addresses will be the + primary address for the association. This automatically enables the + multi-homing capability of SCTP. + + The completion of this bind() process does not ready the SCTP + endpoint to accept inbound SCTP association requests. Until a + listen() system call, described below, is performed on the socket, + the SCTP endpoint will promptly reject an inbound SCTP INIT request + with an SCTP ABORT. + +4.1.3. listen() - one-to-one style socket + + Applications use listen() to ready the SCTP endpoint for accepting + inbound associations. + + The syntax is: + + int listen(int sd, int backlog); + + + + +Stewart, et al. Expires June 14, 2007 [Page 17] + +Internet-Draft SCTP sockets API December 2006 + + + sd: the socket descriptor of the SCTP endpoint. + backlog: this specifies the max number of outstanding associations + allowed in the socket's accept queue. These are the associations + that have finished the four-way initiation handshake (see Section + 5 of RFC2960 [RFC2960]) and are in the ESTABLISHED state. Note, a + backlog of '0' indicates that the caller no longer wishes to + receive new associations. + +4.1.4. accept() - one-to-one style socket + + Applications use accept() call to remove an established SCTP + association from the accept queue of the endpoint. A new socket + descriptor will be returned from accept() to represent the newly + formed association. + + The syntax is: + + new_sd = accept(int sd, struct sockaddr *addr, socklen_t *addrlen); + + new_sd - the socket descriptor for the newly formed association. + sd - the listening socket descriptor. + addr - on return, will contain the primary address of the peer + endpoint. + addrlen - on return, will contain the size of addr. + +4.1.5. connect() - one-to-one style socket + + Applications use connect() to initiate an association to a peer. + + The syntax is: + + int connect(int sd, const struct sockaddr *addr, socklen_t addrlen); + + sd - the socket descriptor of the endpoint. + addr - the peer's address. + addrlen - the size of the address. + + This operation corresponds to the ASSOCIATE primitive described in + section 10.1 of RFC2960 [RFC2960]. + + By default, the new association created has only one outbound stream. + The SCTP_INITMSG option described in Section 7.1.3 should be used + before connecting to change the number of outbound streams. + + If a bind() is not called prior to the connect() call, the system + picks an ephemeral port and will choose an address set equivalent to + binding with INADDR_ANY and IN6ADDR_ANY for IPv4 and IPv6 socket + respectively. One of those addresses will be the primary address for + + + +Stewart, et al. Expires June 14, 2007 [Page 18] + +Internet-Draft SCTP sockets API December 2006 + + + the association. This automatically enables the multi-homing + capability of SCTP. + + Note that SCTP allows data exchange, similar to T/TCP RFC1644 + [RFC1644], during the association set up phase. If an application + wants to do this, it cannot use connect() call. Instead, it should + use sendto() or sendmsg() to initiate an association. If it uses + sendto() and it wants to change initialization behavior, it needs to + use the SCTP_INITMSG socket option before calling sendto(). Or it + can use SCTP_INIT type sendmsg() to initiate an association without + doing the setsockopt(). Note that some sockets implementations may + not support the sending of data to initiate an association with the + one-to-one style (implementations that do not support T/TCP normally + have this restriction). Implementations which allow sending of data + to initiate an association without calling connect() define the + preprocessor constant HAVE_SCTP_NOCONNECT to 1. + + SCTP does not support half close semantics. This means that unlike + T/TCP, MSG_EOF should not be set in the flags parameter when calling + sendto() or sendmsg() when the call is used to initiate a connection. + MSG_EOF is not an acceptable flag with SCTP socket. + +4.1.6. close() - one-to-one style socket + + Applications use close() to gracefully close down an association. + + The syntax is: + + int close(int sd); + + sd - the socket descriptor of the association to be closed. + + After an application calls close() on a socket descriptor, no further + socket operations will succeed on that descriptor. + +4.1.7. shutdown() - one-to-one style socket + + SCTP differs from TCP in that it does not have half closed semantics. + Hence the shutdown() call for SCTP is an approximation of the TCP + shutdown() call, and solves some different problems. Full TCP- + compatibility is not provided, so developers porting TCP applications + to SCTP may need to recode sections that use shutdown(). (Note that + it is possible to achieve the same results as half close in SCTP + using SCTP streams.) + + The syntax is: + + int shutdown(int sd, int how); + + + +Stewart, et al. Expires June 14, 2007 [Page 19] + +Internet-Draft SCTP sockets API December 2006 + + + sd - the socket descriptor of the association to be closed. + how - Specifies the type of shutdown. The values are as follows: + SHUT_RD - Disables further receive operations. No SCTP protocol + action is taken. + SHUT_WR - Disables further send operations, and initiates the + SCTP shutdown sequence. + SHUT_RDWR - Disables further send and receive operations and + initiates the SCTP shutdown sequence. + + The major difference between SCTP and TCP shutdown() is that SCTP + SHUT_WR initiates immediate and full protocol shutdown, whereas TCP + SHUT_WR causes TCP to go into the half closed state. SHUT_RD behaves + the same for SCTP as TCP. The purpose of SCTP SHUT_WR is to close + the SCTP association while still leaving the socket descriptor open, + so that the caller can receive back any data SCTP was unable to + deliver (see Section 5.3.1.4 for more information). + + To perform the ABORT operation described in RFC2960 [RFC2960] section + 10.1, an application can use the socket option SO_LINGER. It is + described in Section 7.1.4. + +4.1.8. sendmsg() and recvmsg() - one-to-one style socket + + With a one-to-one style socket, the application can also use + sendmsg() and recvmsg() to transmit data to and receive data from its + peer. The semantics is similar to those used in the one-to-many + style (section Section 3.1.3), with the following differences: + + 1) When sending, the msg_name field in the msghdr is not used to + specify the intended receiver, rather it is used to indicate a + preferred peer address if the sender wishes to discourage the stack + from sending the message to the primary address of the receiver. If + the transport address given is not part of the current association, + the data will not be sent and a SCTP_SEND_FAILED event will be + delivered to the application if send failure events are enabled. + +4.1.9. getpeername() + + Applications use getpeername() to retrieve the primary socket address + of the peer. This call is for TCP compatibility, and is not multi- + homed. It does not work with one-to-many style sockets. See + Section 8.3 for a multi-homed/one-to-many style version of the call. + + The syntax is: + + int getpeername(int sd, struct sockaddr *address, + socklen_t *len); + + + + +Stewart, et al. Expires June 14, 2007 [Page 20] + +Internet-Draft SCTP sockets API December 2006 + + + sd - the socket descriptor to be queried. + address - On return, the peer primary address is stored in this + buffer. If the socket is an IPv4 socket, the address will be + IPv4. If the socket is an IPv6 socket, the address will be either + an IPv6 or IPv4 address. + len - The caller should set the length of address here. On return, + this is set to the length of the returned address. + + If the actual length of the address is greater than the length of the + supplied sockaddr structure, the stored address will be truncated. + + +5. Data Structures + + We discuss in this section important data structures which are + specific to SCTP and are used with sendmsg() and recvmsg() calls to + control SCTP endpoint operations and to access ancillary information + and notifications. + +5.1. The msghdr and cmsghdr Structures + + The msghdr structure used in the sendmsg() and recvmsg() calls, as + well as the ancillary data carried in the structure, is the key for + the application to set and get various control information from the + SCTP endpoint. + + The msghdr and the related cmsghdr structures are defined and + discussed in details in RFC2292 [RFC2292]. Here we will cite their + definitions from RFC2292 [RFC2292]. + + The msghdr structure: + + struct msghdr { + void *msg_name; /* ptr to socket address structure */ + socklen_t msg_namelen; /* size of socket address structure */ + struct iovec *msg_iov; /* scatter/gather array */ + size_t msg_iovlen; /* # elements in msg_iov */ + void *msg_control; /* ancillary data */ + socklen_t msg_controllen; /* ancillary data buffer length */ + int msg_flags; /* flags on received message */ + }; + + The cmsghdr structure: + + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 21] + +Internet-Draft SCTP sockets API December 2006 + + + struct cmsghdr { + socklen_t cmsg_len; /* #bytes, including this header */ + int cmsg_level; /* originating protocol */ + int cmsg_type; /* protocol-specific type */ + /* followed by unsigned char cmsg_data[]; */ + }; + + In the msghdr structure, the usage of msg_name has been discussed in + previous sections (see Section 3.1.3 and Section 4.1.8). + + The scatter/gather buffers, or I/O vectors (pointed to by the msg_iov + field) are treated as a single SCTP data chunk, rather than multiple + chunks, for both sendmsg() and recvmsg(). + + The msg_flags are not used when sending a message with sendmsg(). + + If a notification has arrived, recvmsg() will return the notification + with the MSG_NOTIFICATION flag set in msg_flags. If the + MSG_NOTIFICATION flag is not set, recvmsg() will return data. See + Section 5.3 for more information about notifications. + + If all portions of a data frame or notification have been read, + recvmsg() will return with MSG_EOR set in msg_flags. + +5.2. SCTP msg_control Structures + + A key element of all SCTP-specific socket extensions is the use of + ancillary data to specify and access SCTP-specific data via the + struct msghdr's msg_control member used in sendmsg() and recvmsg(). + Fine-grained control over initialization and sending parameters are + handled with ancillary data. + + Each ancillary data item is proceeded by a struct cmsghdr (see + Section 5.1), which defines the function and purpose of the data + contained in in the cmsg_data[] member. + + There are two kinds of ancillary data used by SCTP: initialization + data, and, header information (SNDRCV). Initialization data (one-to- + many style only) sets protocol parameters for new associations. + Section 5.2.1 provides more details. Header information can set or + report parameters on individual messages in a stream. See + Section 5.2.2 for how to use SNDRCV ancillary data. + + By default on a one-to-one style socket, SCTP will pass no ancillary + data; on a one-to-many style socket, SCTP will only pass SCTP_SNDRCV + and SCTP_ASSOC_CHANGE information. Specific ancillary data items can + be enabled with socket options defined for SCTP; see Section 7.3. + + + + +Stewart, et al. Expires June 14, 2007 [Page 22] + +Internet-Draft SCTP sockets API December 2006 + + + Note that all ancillary types are fixed length; see Section 5.4 for + further discussion on this. These data structures use struct + sockaddr_storage (defined in RFC2553 [RFC2553]) as a portable, fixed + length address format. + + Other protocols may also provide ancillary data to the socket layer + consumer. These ancillary data items from other protocols may + intermingle with SCTP data. For example, the IPv6 socket API + definitions (RFC2292 [RFC2292] and RFC2553 [RFC2553]) define a number + of ancillary data items. If a socket API consumer enables delivery + of both SCTP and IPv6 ancillary data, they both may appear in the + same msg_control buffer in any order. An application may thus need + to handle other types of ancillary data besides that passed by SCTP. + + The sockets application must provide a buffer large enough to + accommodate all ancillary data provided via recvmsg(). If the buffer + is not large enough, the ancillary data will be truncated and the + msghdr's msg_flags will include MSG_CTRUNC. + +5.2.1. SCTP Initiation Structure (SCTP_INIT) + + This cmsghdr structure provides information for initializing new SCTP + associations with sendmsg(). The SCTP_INITMSG socket option uses + this same data structure. This structure is not used for recvmsg(). + + cmsg_level cmsg_type cmsg_data[] + ------------ ------------ ---------------------- + IPPROTO_SCTP SCTP_INIT struct sctp_initmsg + + Here is the definition of the sctp_initmsg structure: + + struct sctp_initmsg { + uint16_t sinit_num_ostreams; + uint16_t sinit_max_instreams; + uint16_t sinit_max_attempts; + uint16_t sinit_max_init_timeo; + }; + + sinit_num_ostreams: 16 bits (unsigned integer) + + This is an integer number representing the number of streams that the + application wishes to be able to send to. This number is confirmed + in the SCTP_COMM_UP notification and must be verified since it is a + negotiated number with the remote endpoint. The default value of 0 + indicates to use the endpoint default value. + + sinit_max_instreams: 16 bits (unsigned integer) + + + + +Stewart, et al. Expires June 14, 2007 [Page 23] + +Internet-Draft SCTP sockets API December 2006 + + + This value represents the maximum number of inbound streams the + application is prepared to support. This value is bounded by the + actual implementation. In other words the user MAY be able to + support more streams than the Operating System. In such a case, the + Operating System limit overrides the value requested by the user. + The default value of 0 indicates to use the endpoints default value. + + sinit_max_attempts: 16 bits (unsigned integer) + + This integer specifies how many attempts the SCTP endpoint should + make at resending the INIT. This value overrides the system SCTP + 'Max.Init.Retransmits' value. The default value of 0 indicates to + use the endpoints default value. This is normally set to the + system's default 'Max.Init.Retransmit' value. + + sinit_max_init_timeo: 16 bits (unsigned integer) + + This value represents the largest Time-Out or RTO value (in + milliseconds) to use in attempting an INIT. Normally the 'RTO.Max' + is used to limit the doubling of the RTO upon timeout. For the INIT + message this value MAY override 'RTO.Max'. This value MUST NOT + influence 'RTO.Max' during data transmission and is only used to + bound the initial setup time. A default value of 0 indicates to use + the endpoints default value. This is normally set to the system's + 'RTO.Max' value (60 seconds). + +5.2.2. SCTP Header Information Structure (SCTP_SNDRCV) + + This cmsghdr structure specifies SCTP options for sendmsg() and + describes SCTP header information about a received message through + recvmsg(). + + cmsg_level cmsg_type cmsg_data[] + ------------ ------------ ---------------------- + IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo + + Here is the definition of sctp_sndrcvinfo: + + struct sctp_sndrcvinfo { + uint16_t sinfo_stream; + uint16_t sinfo_ssn; + uint16_t sinfo_flags; + uint32_t sinfo_ppid; + uint32_t sinfo_context; + uint32_t sinfo_timetolive; + uint32_t sinfo_tsn; + uint32_t sinfo_cumtsn; + sctp_assoc_t sinfo_assoc_id; + + + +Stewart, et al. Expires June 14, 2007 [Page 24] + +Internet-Draft SCTP sockets API December 2006 + + + }; + + + sinfo_stream: 16 bits (unsigned integer) + + For recvmsg() the SCTP stack places the message's stream number in + this value. For sendmsg() this value holds the stream number that + the application wishes to send this message to. If a sender + specifies an invalid stream number an error indication is returned + and the call fails. + + sinfo_ssn: 16 bits (unsigned integer) + + For recvmsg() this value contains the stream sequence number that the + remote endpoint placed in the DATA chunk. For fragmented messages + this is the same number for all deliveries of the message (if more + than one recvmsg() is needed to read the message). The sendmsg() + call will ignore this parameter. + + sinfo_ppid: 32 bits (unsigned integer) + + This value in sendmsg() is an unsigned integer that is passed to the + remote end in each user message. In recvmsg() this value is the same + information that was passed by the upper layer in the peer + application. Please note that the SCTP stack performs no byte order + modification of this field. For example, if the DATA chunk has to + contain a given value in network byte order, the SCTP user has to + perform the htonl() computation. + + sinfo_context: 32 bits (unsigned integer) + + This value is an opaque 32 bit context datum that is used in the + sendmsg() function. This value is passed back to the upper layer if + a error occurs on the send of a message and is retrieved with each + undelivered message (Note: if a endpoint has done multiple sends, all + of which fail, multiple different sinfo_context values will be + returned. One with each user data message). + + sinfo_flags: 16 bits (unsigned integer) + + This field may contain any of the following flags and is composed of + a bitwise OR of these values. + + recvmsg() flags: + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 25] + +Internet-Draft SCTP sockets API December 2006 + + + SCTP_UNORDERED - This flag is present when the message was sent non- + ordered. + + + sendmsg() flags: + SCTP_UNORDERED - This flag requests the un-ordered delivery of the + message. If this flag is clear the datagram is considered an + ordered send. + + SCTP_ADDR_OVER - This flag, in the one-to-many style, requests the + SCTP stack to override the primary destination address with the + address found with the sendto/sendmsg call. + + SCTP_ABORT - Setting this flag causes the specified association to + abort by sending an ABORT message to the peer (one-to-many style + only). The ABORT chunk will contain an error cause 'User + Initiated Abort' with cause code 12. The cause specific + information of this error cause is provided in msg_iov. + + SCTP_EOF - Setting this flag invokes the SCTP graceful shutdown + procedures on the specified association. Graceful shutdown + assures that all data enqueued by both endpoints is successfully + transmitted before closing the association (one-to-many style + only). + + SCTP_SENDALL - This flag, if set, will cause a one-to-many model + socket to send the message to all associations that are currently + established on this socket. For the one-to-one socket, this flag + has no effect. + + + sinfo_timetolive: 32 bit (unsigned integer) + + For the sending side, this field contains the message time to live in + milliseconds. The sending side will expire the message within the + specified time period if the message as not been sent to the peer + within this time period. This value will override any default value + set using any socket option. Also note that the value of 0 is + special in that it indicates no timeout should occur on this message. + + sinfo_tsn: 32 bit (unsigned integer) + + For the receiving side, this field holds a TSN that was assigned to + one of the SCTP Data Chunks. + + sinfo_cumtsn: 32 bit (unsigned integer) + + This field will hold the current cumulative TSN as known by the + + + +Stewart, et al. Expires June 14, 2007 [Page 26] + +Internet-Draft SCTP sockets API December 2006 + + + underlying SCTP layer. Note this field is ignored when sending and + only valid for a receive operation when sinfo_flags are set to + SCTP_UNORDERED. + + sinfo_assoc_id: sizeof (sctp_assoc_t) + + The association handle field, sinfo_assoc_id, holds the identifier + for the association announced in the SCTP_COMM_UP notification. All + notifications for a given association have the same identifier. + Ignored for one-to-one style sockets. + + A sctp_sndrcvinfo item always corresponds to the data in msg_iov. + +5.2.3. Extended SCTP Header Information Structure (SCTP_EXTRCV) + + This cmsghdr structure specifies SCTP options for SCTP header + information about a received message via recvmsg(). Note that this + structure is an extended version of SCTP_SNDRCV and will only be + received if the user has set the socket option SCTP_USE_EXT_RCVINFO + to true in addition to any event subscription needed to receive + ancillary data.. + + cmsg_level cmsg_type cmsg_data[] + ------------ ------------ ---------------------- + IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo + + Here is the definition of sctp_sndrcvinfo: + + struct sctp_extrcvinfo { + uint16_t sinfo_stream; + uint16_t sinfo_ssn; + uint16_t sinfo_flags; + uint32_t sinfo_ppid; + uint32_t sinfo_context; + uint32_t sinfo_timetolive; + uint32_t sinfo_tsn; + uint32_t sinfo_cumtsn; + sctp_assoc_t sinfo_assoc_id; + uint16_t next_flags; + uint16_t next_stream; + uint32_t next_asocid; + uint32_t next_length; + uint32_t next_ppid; + }; + + + sinfo_stream: 16 bits (unsigned integer) + + + + +Stewart, et al. Expires June 14, 2007 [Page 27] + +Internet-Draft SCTP sockets API December 2006 + + + For recvmsg() the SCTP stack places the message's stream number in + this value. For sendmsg() this value holds the stream number that + the application wishes to send this message to. If a sender + specifies an invalid stream number an error indication is returned + and the call fails. + + sinfo_ssn: 16 bits (unsigned integer) + + For recvmsg() this value contains the stream sequence number that the + remote endpoint placed in the DATA chunk. For fragmented messages + this is the same number for all deliveries of the message (if more + than one recvmsg() is needed to read the message). The sendmsg() + call will ignore this parameter. + + sinfo_ppid: 32 bits (unsigned integer) + + This value in sendmsg() is an unsigned integer that is passed to the + remote end in each user message. In recvmsg() this value is the same + information that was passed by the upper layer in the peer + application. Please note that the SCTP stack performs no byte order + modification of this field. For example, if the DATA chunk has to + contain a given value in network byte order, the SCTP user has to + perform the htonl() computation. + + sinfo_context: 32 bits (unsigned integer) + + This value is an opaque 32 bit context datum that is used in the + sendmsg() function. This value is passed back to the upper layer if + a error occurs on the send of a message and is retrieved with each + undelivered message (Note: if a endpoint has done multiple sends, all + of which fail, multiple different sinfo_context values will be + returned. One with each user data message). + + sinfo_flags: 16 bits (unsigned integer) + + This field may contain any of the following flags and is composed of + a bitwise OR of these values. + + recvmsg() flags: + SCTP_UNORDERED - This flag is present when the message was sent non- + ordered. + + sendmsg() flags: + SCTP_UNORDERED - This flag requests the un-ordered delivery of the + message. If this flag is clear the datagram is considered an + ordered send. + + + + + +Stewart, et al. Expires June 14, 2007 [Page 28] + +Internet-Draft SCTP sockets API December 2006 + + + SCTP_ADDR_OVER - This flag, in the one-to-many style, requests the + SCTP stack to override the primary destination address with the + address found with the sendto/sendmsg call. + + SCTP_ABORT - Setting this flag causes the specified association to + abort by sending an ABORT message to the peer (one-to-many style + only). The ABORT chunk will contain an error cause 'User + Initiated Abort' with cause code 12. The cause specific + information of this error cause is provided in msg_iov. + + SCTP_EOF - Setting this flag invokes the SCTP graceful shutdown + procedures on the specified association. Graceful shutdown + assures that all data enqueued by both endpoints is successfully + transmitted before closing the association (one-to-many style + only). + + SCTP_SENDALL - This flag, if set, will cause a one-to-many model + socket to send the message to all associations that are currently + established on this socket. For the one-to-one socket, this flag + has no effect. + SCTP_EOR - This flag, if set, will indicate that this send + terminates the record. + + sinfo_timetolive: 32 bit (unsigned integer) + + For the sending side, this field contains the message time to live in + milliseconds. The sending side will expire the message within the + specified time period if the message as not been sent to the peer + within this time period. This value will override any default value + set using any socket option. Also note that the value of 0 is + special in that it indicates no timeout should occur on this message. + + sinfo_tsn: 32 bit (unsigned integer) + + For the receiving side, this field holds a TSN that was assigned to + one of the SCTP Data Chunks. + + sinfo_cumtsn: 32 bit (unsigned integer) + + This field will hold the current cumulative TSN as known by the + underlying SCTP layer. Note this field is ignored when sending and + only valid for a receive operation when sinfo_flags are set to + SCTP_UNORDERED. + + sinfo_assoc_id: sizeof (sctp_assoc_t) + + The association handle field, sinfo_assoc_id, holds the identifier + for the association announced in the SCTP_COMM_UP notification. All + + + +Stewart, et al. Expires June 14, 2007 [Page 29] + +Internet-Draft SCTP sockets API December 2006 + + + notifications for a given association have the same identifier. + Ignored for one-to-one style sockets. + + A sctp_sndrcvinfo item always corresponds to the data in msg_iov. + + next_flags: 16 bit (unsigned integer) + + This bitmask will hold one or more of the following values: + SCTP_NEXT_MSG_AVAIL - This bit, when set to 1, indicates that next + message information is available i.e.: next_stream, next_asocid, + next_length and next_ppid fields all have valid values. If this + bit is set to 0, then these fields are not valid and should be + ignored. + + SCTP_NEXT_MSG_ISCOMPLETE - This bit, when set, indicates that the + next message is completely in the receive buffer. The next_length + field thus contains the entire message size. If this flag is set + to 0, then the next_length field only contains part of the message + size since the message is still being received (it is being + partially delivered). + + SCTP_NEXT_MSG_IS_UNORDERED - This bit, when set, indicates that the + next message to be received was sent by the peer as unordered. If + this bit is not set (i.e the bit is 0) the next message to be read + is an ordered message in the stream specified. + + next_stream: 16 bit (unsigned integer) + + This value, when valid (see next_flags), contains the next stream + number that will be received on a subsequent call to one of the + receive message functions. + + next_asocid: 32 bit (unsigned integer) + + This value, when valid (see next_flags), contains the next + association identification that will be received on a subsequent call + to one of the receive message functions. + + next_length: 32 bit (unsigned integer) + + This value, when valid (see next_flags), contains the length of the + next message that will be received on a subsequent call to one of the + receive message functions. Note that this length may be a partial + length depending on the settings of next_flags. + + next_ppid: 32 bit (unsigned integer) + + This value, when valid (see next_flags), contains the ppid of the + + + +Stewart, et al. Expires June 14, 2007 [Page 30] + +Internet-Draft SCTP sockets API December 2006 + + + next message that will be received on a subsequent call to one of the + receive message functions. + +5.3. SCTP Events and Notifications + + An SCTP application may need to understand and process events and + errors that happen on the SCTP stack. These events include network + status changes, association startups, remote operational errors and + undeliverable messages. All of these can be essential for the + application. + + When an SCTP application layer does a recvmsg() the message read is + normally a data message from a peer endpoint. If the application + wishes to have the SCTP stack deliver notifications of non-data + events, it sets the appropriate socket option for the notifications + it wants. See Section 7.3 for these socket options. When a + notification arrives, recvmsg() returns the notification in the + application-supplied data buffer via msg_iov, and sets + MSG_NOTIFICATION in msg_flags. + + This section details the notification structures. Every notification + structure carries some common fields which provides general + information. + + A recvmsg() call will return only one notification at a time. Just + as when reading normal data, it may return part of a notification if + the msg_iov buffer is not large enough. If a single read is not + sufficient, msg_flags will have MSG_EOR clear. The user MUST finish + reading the notification before subsequent data can arrive. + +5.3.1. SCTP Notification Structure + + The notification structure is defined as the union of all + notification types. + + + + + + + + + + + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 31] + +Internet-Draft SCTP sockets API December 2006 + + + union sctp_notification { + struct { + uint16_t sn_type; /* Notification type. */ + uint16_t sn_flags; + uint32_t sn_length; + } sn_header; + struct sctp_assoc_change sn_assoc_change; + struct sctp_paddr_change sn_paddr_change; + struct sctp_remote_error sn_remote_error; + struct sctp_send_failed sn_send_failed; + struct sctp_shutdown_event sn_shutdown_event; + struct sctp_adaptation_event sn_adaptation_event; + struct sctp_pdapi_event sn_pdapi_event; + struct sctp_authkey_event sn_auth_event; + }; + + + sn_type: 16 bits (unsigned integer) + + The following list describes the SCTP notification and event types + for the field sn_type. + + SCTP_ASSOC_CHANGE: This tag indicates that an association has either + been opened or closed. Refer to Section 5.3.1.1 for details. + SCTP_PEER_ADDR_CHANGE: This tag indicates that an address that is + part of an existing association has experienced a change of state + (e.g. a failure or return to service of the reachability of a + endpoint via a specific transport address). Please see + Section 5.3.1.2 for data structure details. + SCTP_REMOTE_ERROR: The attached error message is an Operational + Error received from the remote peer. It includes the complete TLV + sent by the remote endpoint. See Section 5.3.1.3 for the detailed + format. + SCTP_SEND_FAILED: The attached datagram could not be sent to the + remote endpoint. This structure includes the original + SCTP_SNDRCVINFO that was used in sending this message i.e. this + structure uses the sctp_sndrecvinfo per Section 5.3.1.4. + SCTP_SHUTDOWN_EVENT: The peer has sent a SHUTDOWN. No further data + should be sent on this socket. + SCTP_ADAPTATION_INDICATION: This notification holds the peers + indicated adaptation layer. Please see Section 5.3.1.6. + SCTP_PARTIAL_DELIVERY_EVENT: This notification is used to tell a + receiver that the partial delivery has been aborted. This may + indicate the association is about to be aborted. Please see + Section 5.3.1.7 + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 32] + +Internet-Draft SCTP sockets API December 2006 + + + SCTP_AUTHENTICATION_EVENT: This notification is used to tell a + receiver that either an error occurred on authentication, or a new + key was made active. Section 5.3.1.8 + + All standard values for sn_type are greater than 2^15. Values from + 2^15 and down are reserved. + + sn_flags: 16 bits (unsigned integer) + + These are notification-specific flags. + + sn_length: 32 bits (unsigned integer) + + This is the length of the whole sctp_notification structure including + the sn_type, sn_flags, and sn_length fields. + +5.3.1.1. SCTP_ASSOC_CHANGE + + Communication notifications inform the ULP that an SCTP association + has either begun or ended. The identifier for a new association is + provided by this notification. The notification information has the + following format: + + struct sctp_assoc_change { + uint16_t sac_type; + uint16_t sac_flags; + uint32_t sac_length; + uint16_t sac_state; + uint16_t sac_error; + uint16_t sac_outbound_streams; + uint16_t sac_inbound_streams; + sctp_assoc_t sac_assoc_id; + uint8_t sac_info[0]; + }; + + sac_type: + + It should be SCTP_ASSOC_CHANGE. + + sac_flags: 16 bits (unsigned integer) + + Currently unused. + + sac_length: 32 bits (unsigned integer) + + This field is the total length of the notification data, including + the notification header. + + + + +Stewart, et al. Expires June 14, 2007 [Page 33] + +Internet-Draft SCTP sockets API December 2006 + + + sac_state: 16 bits (signed integer) + + This field holds one of a number of values that communicate the event + that happened to the association. They include: + + Event Name Description + + ---------------- --------------- + + SCTP_COMM_UP - A new association is now ready and data may be + exchanged with this peer. + SCTP_COMM_LOST - The association has failed. The association is now + in the closed state. If SEND FAILED notifications are turned on, + a SCTP_COMM_LOST is followed by a series of SCTP_SEND_FAILED + events, one for each outstanding message. + SCTP_RESTART - SCTP has detected that the peer has restarted. + SCTP_SHUTDOWN_COMP - The association has gracefully closed. + SCTP_CANT_STR_ASSOC - The association failed to setup. If non + blocking mode is set and data was sent (in the udp mode), a + SCTP_CANT_STR_ASSOC is followed by a series of SCTP_SEND_FAILED + events, one for each outstanding message. + + sac_error: 16 bits (signed integer) + + If the state was reached due to a error condition (e.g. + SCTP_COMM_LOST) any relevant error information is available in this + field. This corresponds to the protocol error codes defined in + RFC2960 [RFC2960]. + + sac_outbound_streams: 16 bits (unsigned integer) + + sac_inbound_streams: 16 bits (unsigned integer) + + The maximum number of streams allowed in each direction are available + in sac_outbound_streams and sac_inbound streams. + + sac_assoc_id: sizeof (sctp_assoc_t) + + The association id field, holds the identifier for the association. + All notifications for a given association have the same association + identifier. For one-to-one style socket, this field is ignored. + + sac_info: variable + + If the sac_state is SCTP_COMM_LOST and an ABORT chunk was received + for this association, sac_info[] contains the complete ABORT chunk as + defined in the SCTP specification RFC2960 [RFC2960] section 3.3.7. + + + + +Stewart, et al. Expires June 14, 2007 [Page 34] + +Internet-Draft SCTP sockets API December 2006 + + +5.3.1.2. SCTP_PEER_ADDR_CHANGE + + When a destination address on a multi-homed peer encounters a change + an interface details event is sent. The information has the + following structure: + + + struct sctp_paddr_change { + uint16_t spc_type; + uint16_t spc_flags; + uint32_t spc_length; + struct sockaddr_storage spc_aaddr; + uint32_t spc_state; + uint32_t spc_error; + sctp_assoc_t spc_assoc_id; + } + + spc_type: + + It should be SCTP_PEER_ADDR_CHANGE. + + spc_flags: 16 bits (unsigned integer) + + Currently unused. + + spc_length: 32 bits (unsigned integer) + + This field is the total length of the notification data, including + the notification header. + + spc_aaddr: sizeof (struct sockaddr_storage) + + The affected address field, holds the remote peer's address that is + encountering the change of state. + + spc_state: 32 bits (signed integer) + + This field holds one of a number of values that communicate the event + that happened to the address. They include: + + Event Name Description + + ---------------- --------------- + + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 35] + +Internet-Draft SCTP sockets API December 2006 + + + SCTP_ADDR_AVAILABLE - This address is now reachable. + SCTP_ADDR_UNREACHABLE - The address specified can no longer be + reached. Any data sent to this address is rerouted to an + alternate until this address becomes reachable. + SCTP_ADDR_REMOVED - The address is no longer part of the + association. + SCTP_ADDR_ADDED - The address is now part of the association. + SCTP_ADDR_MADE_PRIM - This address has now been made to be the + primary destination address. + SCTP_ADDR_CONFIRMED - This address has now been confirmed as a valid + address. + + spc_error: 32 bits (signed integer) + + If the state was reached due to any error condition (e.g. + SCTP_ADDR_UNREACHABLE) any relevant error information is available in + this field. + + spc_assoc_id: sizeof (sctp_assoc_t) + + The association id field, holds the identifier for the association. + All notifications for a given association have the same association + identifier. For one-to-one style socket, this field is ignored. + +5.3.1.3. SCTP_REMOTE_ERROR + + A remote peer may send an Operational Error message to its peer. + This message indicates a variety of error conditions on an + association. The entire ERROR chunk as it appears on the wire is + included in a SCTP_REMOTE_ERROR event. Please refer to the SCTP + specification RFC2960 [RFC2960] and any extensions for a list of + possible error formats. SCTP error notifications have the format: + + + struct sctp_remote_error { + uint16_t sre_type; + uint16_t sre_flags; + uint32_t sre_length; + uint16_t sre_error; + sctp_assoc_t sre_assoc_id; + uint8_t sre_data[0]; + }; + + + sre_type: + + It should be SCTP_REMOTE_ERROR. + + + + +Stewart, et al. Expires June 14, 2007 [Page 36] + +Internet-Draft SCTP sockets API December 2006 + + + sre_flags: 16 bits (unsigned integer) + + Currently unused. + + sre_length: 32 bits (unsigned integer) + + This field is the total length of the notification data, including + the notification header and the contents of sre_data. + + sre_error: 16 bits (unsigned integer) + + This value represents one of the Operational Error causes defined in + the SCTP specification, in network byte order. + + sre_assoc_id: sizeof (sctp_assoc_t) + + The association id field, holds the identifier for the association. + All notifications for a given association have the same association + identifier. For one-to-one style socket, this field is ignored. + + sre_data: variable + + This contains the ERROR chunk as defined in the SCTP specification + RFC2960 [RFC2960] section 3.3.10. + +5.3.1.4. SCTP_SEND_FAILED + + If SCTP cannot deliver a message it may return the message as a + notification. + + + struct sctp_send_failed { + uint16_t ssf_type; + uint16_t ssf_flags; + uint32_t ssf_length; + uint32_t ssf_error; + struct sctp_sndrcvinfo ssf_info; + sctp_assoc_t ssf_assoc_id; + uint8_t ssf_data[0]; + }; + + + ssf_type: + + It should be SCTP_SEND_FAILED. + + ssf_flags: 16 bits (unsigned integer) + + + + +Stewart, et al. Expires June 14, 2007 [Page 37] + +Internet-Draft SCTP sockets API December 2006 + + + The flag value will take one of the following values: + + SCTP_DATA_UNSENT - Indicates that the data was never put on the + wire. + SCTP_DATA_SENT - Indicates that the data was put on the wire. Note + that this does not necessarily mean that the data was (or was not) + successfully delivered. + + ssf_length: 32 bits (unsigned integer) + + This field is the total length of the notification data, including + the notification header and the payload in ssf_data. + + ssf_error: 16 bits (unsigned integer) + + This value represents the reason why the send failed, and if set, + will be a SCTP protocol error code as defined in RFC2960 [RFC2960] + section 3.3.10. + + ssf_info: sizeof (struct sctp_sndrcvinfo) + + The original send information associated with the undelivered + message. + + ssf_assoc_id: sizeof (sctp_assoc_t) + + The association id field, sf_assoc_id, holds the identifier for the + association. All notifications for a given association have the same + association identifier. For one-to-one style socket, this field is + ignored. + + ssf_data: variable length + + The undelivered message, exactly as delivered by the caller to the + original send*() call. + +5.3.1.5. SCTP_SHUTDOWN_EVENT + + When a peer sends a SHUTDOWN, SCTP delivers this notification to + inform the application that it should cease sending data. + + struct sctp_shutdown_event { + uint16_t sse_type; + uint16_t sse_flags; + uint32_t sse_length; + sctp_assoc_t sse_assoc_id; + }; + + + + +Stewart, et al. Expires June 14, 2007 [Page 38] + +Internet-Draft SCTP sockets API December 2006 + + + sse_type + + It should be SCTP_SHUTDOWN_EVENT + + sse_flags: 16 bits (unsigned integer) + + Currently unused. + + sse_length: 32 bits (unsigned integer) + + This field is the total length of the notification data, including + the notification header. It will generally be sizeof (struct + sctp_shutdown_event). + + sse_flags: 16 bits (unsigned integer) + + Currently unused. + + sse_assoc_id: sizeof (sctp_assoc_t) + + The association id field, holds the identifier for the association. + All notifications for a given association have the same association + identifier. For one-to-one style socket, this field is ignored. + +5.3.1.6. SCTP_ADAPTATION_INDICATION + + When a peer sends a Adaptation Layer Indication parameter , SCTP + delivers this notification to inform the application that of the + peers requested adaptation layer. + + struct sctp_adaptation_event { + uint16_t sai_type; + uint16_t sai_flags; + uint32_t sai_length; + uint32_t sai_adaptation_ind; + sctp_assoc_t sai_assoc_id; + }; + + sai_type + + It should be SCTP_ADAPTATION_INDICATION + + sai_flags: 16 bits (unsigned integer) + + Currently unused. + + sai_length: 32 bits (unsigned integer) + + + + +Stewart, et al. Expires June 14, 2007 [Page 39] + +Internet-Draft SCTP sockets API December 2006 + + + This field is the total length of the notification data, including + the notification header. It will generally be sizeof (struct + sctp_adaptation_event). + + sai_adaptation_ind: 32 bits (unsigned integer) + + This field holds the bit array sent by the peer in the adaptation + layer indication parameter. The bits are in network byte order. + + sai_assoc_id: sizeof (sctp_assoc_t) + + The association id field, holds the identifier for the association. + All notifications for a given association have the same association + identifier. For one-to-one style socket, this field is ignored. + +5.3.1.7. SCTP_PARTIAL_DELIVERY_EVENT + + When a receiver is engaged in a partial delivery of a message this + notification will be used to indicate various events. + + struct sctp_pdapi_event { + uint16_t pdapi_type; + uint16_t pdapi_flags; + uint32_t pdapi_length; + uint32_t pdapi_indication; + sctp_assoc_t pdapi_assoc_id; + }; + + pdapi_type + + It should be SCTP_PARTIAL_DELIVERY_EVENT + + pdapi_flags: 16 bits (unsigned integer) + + Currently unused. + + pdapi_length: 32 bits (unsigned integer) + + This field is the total length of the notification data, including + the notification header. It will generally be sizeof (struct + sctp_pdapi_event). + + pdapi_indication: 32 bits (unsigned integer) + + This field holds the indication being sent to the application + possible values include: + + SCTP_PARTIAL_DELIVERY_ABORTED + + + +Stewart, et al. Expires June 14, 2007 [Page 40] + +Internet-Draft SCTP sockets API December 2006 + + + pdapi_assoc_id: sizeof (sctp_assoc_t) + + The association id field, holds the identifier for the association. + All notifications for a given association have the same association + identifier. For one-to-one style socket, this field is ignored. + +5.3.1.8. SCTP_AUTHENTICATION_EVENT + + When a receiver is using authentication this message will provide + notifications regarding new keys being made active as well as errors. + + struct sctp_authkey_event { + uint16_t auth_type; + uint16_t auth_flags; + uint32_t auth_length; + uint16_t auth_keynumber; + uint16_t auth_altkeynumber; + uint32_t auth_indication; + sctp_assoc_t auth_assoc_id; + }; + + auth_type + + It should be SCTP_AUTHENTICATION_EVENT + + auth_flags: 16 bits (unsigned integer) + + Currently unused. + + auth_length: 32 bits (unsigned integer) + + This field is the total length of the notification data, including + the notification header. It will generally be sizeof (struct + sctp_authkey_event). + + auth_keynumber: 32 bits (unsigned integer) + + This field holds the keynumber set by the user for the effected key. + If more than one key is involved, this will contain one of the keys + involved in the notification. + + auth_altkeynumber: 32 bits (unsigned integer) + + This field holds an alternate keynumber which is used by some + notifications. + + auth_indication: 32 bits (unsigned integer) + + + + +Stewart, et al. Expires June 14, 2007 [Page 41] + +Internet-Draft SCTP sockets API December 2006 + + + This field hold the error or indication being reported. The + following values are currently defined: + SCTP_AUTH_NEWKEY - this report indicates that a new key has been + made active (used for the first time by the peer) and is now the + active key. The auth_keynumber field holds the user specified key + number. + + auth_assoc_id: sizeof (sctp_assoc_t) + + The association id field, holds the identifier for the association. + All notifications for a given association have the same association + identifier. + +5.4. Ancillary Data Considerations and Semantics + + Programming with ancillary socket data contains some subtleties and + pitfalls, which are discussed below. + +5.4.1. Multiple Items and Ordering + + Multiple ancillary data items may be included in any call to + sendmsg() or recvmsg(); these may include multiple SCTP or non-SCTP + items, or both. + + The ordering of ancillary data items (either by SCTP or another + protocol) is not significant and is implementation-dependent, so + applications must not depend on any ordering. + + SCTP_SNDRCV items must always correspond to the data in the msghdr's + msg_iov member. There can be only a single SCTP_SNDRCV info for each + sendmsg() or recvmsg() call. + +5.4.2. Accessing and Manipulating Ancillary Data + + Applications can infer the presence of data or ancillary data by + examining the msg_iovlen and msg_controllen msghdr members, + respectively. + + Implementations may have different padding requirements for ancillary + data, so portable applications should make use of the macros + CMSG_FIRSTHDR, CMSG_NXTHDR, CMSG_DATA, CMSG_SPACE, and CMSG_LEN. See + RFC2292 [RFC2292] and your SCTP implementation's documentation for + more information. Following is an example, from RFC2292 [RFC2292], + demonstrating the use of these macros to access ancillary data: + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 42] + +Internet-Draft SCTP sockets API December 2006 + + + struct msghdr msg; + struct cmsghdr *cmsgptr; + + /* fill in msg */ + + /* call recvmsg() */ + + for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; + cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { + if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) { + u_char *ptr; + + ptr = CMSG_DATA(cmsgptr); + /* process data pointed to by ptr */ + } + } + +5.4.3. Control Message Buffer Sizing + + The information conveyed via SCTP_SNDRCV events will often be + fundamental to the correct and sane operation of the sockets + application. This is particularly true of the one-to-many semantics, + but also of the one-ton-one semantics. For example, if an + application needs to send and receive data on different SCTP streams, + SCTP_SNDRCV events are indispensable. + + Given that some ancillary data is critical, and that multiple + ancillary data items may appear in any order, applications should be + carefully written to always provide a large enough buffer to contain + all possible ancillary data that can be presented by recvmsg(). If + the buffer is too small, and crucial data is truncated, it may pose a + fatal error condition. + + Thus it is essential that applications be able to deterministically + calculate the maximum required buffer size to pass to recvmsg(). One + constraint imposed on this specification that makes this possible is + that all ancillary data definitions are of a fixed length. One way + to calculate the maximum required buffer size might be to take the + sum the sizes of all enabled ancillary data item structures, as + calculated by CMSG_SPACE. For example, if we enabled + SCTP_SNDRCV_INFO and IPV6_RECVPKTINFO RFC2292 [RFC2292], we would + calculate and allocate the buffer size as follows: + + + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 43] + +Internet-Draft SCTP sockets API December 2006 + + + size_t total; + void *buf; + + total = CMSG_SPACE(sizeof (struct sctp_sndrcvinfo)) + + CMSG_SPACE(sizeof (struct in6_pktinfo)); + + buf = malloc(total); + + We could then use this buffer for msg_control on each call to + recvmsg() and be assured that we would not lose any ancillary data to + truncation. + + +6. Common Operations for Both Styles + +6.1. send(), recv(), sendto(), recvfrom() + + Applications can use send() and sendto() to transmit data to the peer + of an SCTP endpoint. recv() and recvfrom() can be used to receive + data from the peer. + + The syntax is: + + ssize_t send(int sd, const void *msg, size_t len, int flags); + ssize_t sendto(int sd, const void *msg, size_t len, int flags, + const struct sockaddr *to, socklen_t tolen); + ssize_t recv(int sd, void *buf, size_t len, int flags); + ssize_t recvfrom(int sd, void *buf, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen); + + sd - the socket descriptor of an SCTP endpoint. + msg - the message to be sent. + len - the size of the message or the size of buffer. + to - one of the peer addresses of the association to be used to send + the message. + tolen - the size of the address. + buf - the buffer to store a received message. + from - the buffer to store the peer address used to send the + received message. + fromlen - the size of the from address + flags - (described below). + + These calls give access to only basic SCTP protocol features. If + either peer in the association uses multiple streams, or sends + unordered data these calls will usually be inadequate, and may + deliver the data in unpredictable ways. + + SCTP has the concept of multiple streams in one association. The + + + +Stewart, et al. Expires June 14, 2007 [Page 44] + +Internet-Draft SCTP sockets API December 2006 + + + above calls do not allow the caller to specify on which stream a + message should be sent. The system uses stream 0 as the default + stream for send() and sendto(). recv() and recvfrom() return data + from any stream, but the caller can not distinguish the different + streams. This may result in data seeming to arrive out of order. + Similarly, if a data chunk is sent unordered, recv() and recvfrom() + provide no indication. + + SCTP is message based. The msg buffer above in send() and sendto() + is considered to be a single message. This means that if the caller + wants to send a message which is composed by several buffers, the + caller needs to combine them before calling send() or sendto(). + Alternately, the caller can use sendmsg() to do that without + combining them. recv() and recvfrom() cannot distinguish message + boundaries. + + In receiving, if the buffer supplied is not large enough to hold a + complete message, the receive call acts like a stream socket and + returns as much data as will fit in the buffer. + + Note, the send() and recv() calls may not be used for a one-to-many + style socket. + + Note, if an application calls a send function with no user data and + no ancillary data the SCTP implementation should reject the request + with an appropriate error message. An implementation is NOT allowed + to send a Data chunk with no user data RFC2960 [RFC2960]. + +6.2. setsockopt(), getsockopt() + + Applications use setsockopt() and getsockopt() to set or retrieve + socket options. Socket options are used to change the default + behavior of sockets calls. They are described in Section 7 + + The syntax is: + + ret = getsockopt(int sd, int level, int optname, void *optval, + socklen_t *optlen); + ret = setsockopt(int sd, int level, int optname, const void *optval, + socklen_t optlen); + + + sd - the socket descriptor. + level - set to IPPROTO_SCTP for all SCTP options. + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 45] + +Internet-Draft SCTP sockets API December 2006 + + + optname - the option name. + optval - the buffer to store the value of the option. + optlen - the size of the buffer (or the length of the option + returned). + + All socket options set on a 1-to-1 listening sockets also apply all + accepted sockets. All socket options set on a 1-to-many socket using + the assoc_id 0 applies for all future assocs on the socket. + +6.3. read() and write() + + Applications can use read() and write() to send and receive data to + and from peer. They have the same semantics as send() and recv() + except that the flags parameter cannot be used. + + Note, these calls, when used in the one-to-many style, may only be + used with branched off socket descriptors (see Section 8.2). + +6.4. getsockname() + + Applications use getsockname() to retrieve the locally-bound socket + address of the specified socket. This is especially useful if the + caller let SCTP chose a local port. This call is for where the + endpoint is not multi-homed. It does not work well with multi-homed + sockets. See Section 8.5 for a multi-homed version of the call. + + The syntax is: + + int getsockname(int sd, struct sockaddr *address, + socklen_t *len); + + sd - the socket descriptor to be queried. + address - On return, one locally bound address (chosen by the SCTP + stack) is stored in this buffer. If the socket is an IPv4 socket, + the address will be IPv4. If the socket is an IPv6 socket, the + address will be either an IPv6 or IPv4 address. + len - The caller should set the length of address here. On return, + this is set to the length of the returned address. + + If the actual length of the address is greater than the length of the + supplied sockaddr structure, the stored address will be truncated. + + If the socket has not been bound to a local name, the value stored in + the object pointed to by address is unspecified. + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 46] + +Internet-Draft SCTP sockets API December 2006 + + +7. Socket Options + + The following sub-section describes various SCTP level socket options + that are common to both styles. SCTP associations can be multi- + homed. Therefore, certain option parameters include a + sockaddr_storage structure to select which peer address the option + should be applied to. + + For the one-to-many style sockets, an sctp_assoc_t structure + (association ID) is used to identify the the association instance + that the operation affects. So it must be set when using this style. + + For the one-to-one style sockets and branched off one-to-many style + sockets (see Section 8.2) this association ID parameter is ignored. + + Note that socket or IP level options are set or retrieved per socket. + This means that for one-to-many style sockets, those options will be + applied to all associations belonging to the socket. And for one-to- + one style, those options will be applied to all peer addresses of the + association controlled by the socket. Applications should be very + careful in setting those options. + + For some IP stacks getsockopt() is read-only; so a new interface will + be needed when information must be passed both in to and out of the + SCTP stack. The syntax for sctp_opt_info() is, + + int sctp_opt_info(int sd, + sctp_assoc_t id, + int opt, + void *arg, + socklen_t *size); + + The sctp_opt_info() call is a replacement for getsockopt() only and + will not set any options associated with the specified socket. A + setsockopt() must be used to set any writeable option. + + For one-to-many style sockets, id specifies the association to query. + For one-to-one style sockets, id is ignored. + + opt specifies which SCTP socket option to get. It can get any socket + option currently supported that requests information (either read/ + write options or read only) such as: + SCTP_RTOINFO + SCTP_ASSOCINFO + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 47] + +Internet-Draft SCTP sockets API December 2006 + + + SCTP_DEFAULT_SEND_PARAM + SCTP_GET_PEER_ADDR_INFO + SCTP_PRIMARY_ADDR + SCTP_PEER_ADDR_PARAMS + SCTP_STATUS + SCTP_AUTH_ACTIVE_KEY + SCTP_PEER_AUTH_CHUNKS + SCTP_LOCAL_AUTH_CHUNKS + + arg is an option-specific structure buffer provided by the caller. + See Section 8.5) subsections for more information on these options + and option-specific structures. + + sctp_opt_info() returns 0 on success, or on failure returns -1 and + sets errno to the appropriate error code. + + All options that support specific settings on an association by + filling in either an association id variable or a sockaddr_storage + SHOULD also support setting of the same value for the entire endpoint + (i.e. future associations). To accomplish this the following logic + is used when setting one of these options: + + a) If an address is specified via a sockaddr_storage that is included + in the structure, the address is used to lookup the association + and the settings are applied to the specific address (if + appropriate) or to the entire association. + b) If an association identification is filled in but not a + sockaddr_storage (if present), the association is found using the + association identification and the settings should be applied to + the entire association (since a specific address is not + specified). Note this also applies to options that hold an + association identification in their structure but do not have a + sockaddr_storage field. + c) If neither the sockaddr_storage or association identification is + set, i.e. the sockaddr_storage is set to all 0's (INADDR_ANY) and + the association identification is 0, the settings are a default + and to be applied to the endpoint (all future associations). + +7.1. Read / Write Options + +7.1.1. Retransmission Timeout Parameters (SCTP_RTOINFO) + + The protocol parameters used to initialize and bound retransmission + timeout (RTO) are tunable. See RFC2960 [RFC2960] for more + information on how these parameters are used in RTO calculation. + + The following structure is used to access and modify these + parameters: + + + +Stewart, et al. Expires June 14, 2007 [Page 48] + +Internet-Draft SCTP sockets API December 2006 + + + struct sctp_rtoinfo { + sctp_assoc_t srto_assoc_id; + uint32_t srto_initial; + uint32_t srto_max; + uint32_t srto_min; + }; + + srto_initial - This contains the initial RTO value. + srto_max and srto_min - These contain the maximum and minimum bounds + for all RTOs. + srto_assoc_id - (one-to-many style socket) This is filled in the + application, and identifies the association for this query. If + this parameter is '0' (on a one-to-many style socket), then the + change effects the entire endpoint. + + All parameters are time values, in milliseconds. A value of 0, when + modifying the parameters, indicates that the current value should not + be changed. + + To access or modify these parameters, the application should call + getsockopt or setsockopt() respectively with the option name + SCTP_RTOINFO. + +7.1.2. Association Parameters (SCTP_ASSOCINFO) + + This option is used to both examine and set various association and + endpoint parameters. + + See RFC2960 [RFC2960] for more information on how this parameter is + used. The peer address parameter is ignored for one-to-one style + socket. + + The following structure is used to access and modify this parameters: + + struct sctp_assocparams { + sctp_assoc_t sasoc_assoc_id; + uint16_t sasoc_asocmaxrxt; + uint16_t sasoc_number_peer_destinations; + uint32_t sasoc_peer_rwnd; + uint32_t sasoc_local_rwnd; + uint32_t sasoc_cookie_life; + }; + + sasoc_asocmaxrxt - This contains the maximum retransmission attempts + to make for the association. + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 49] + +Internet-Draft SCTP sockets API December 2006 + + + sasoc_number_peer_destinations - This is the number of destination + addresses that the peer has. + sasoc_peer_rwnd - This holds the current value of the peers rwnd + (reported in the last SACK) minus any outstanding data (i.e. data + inflight). + sasoc_local_rwnd - This holds the last reported rwnd that was sent + to the peer. + sasoc_cookie_life - This is the associations cookie life value used + when issuing cookies. + sasoc_assoc_id - This is filled in the application, and identifies + the association for this query. + + This information may be examined for either the endpoint or a + specific association. To examine a endpoints default parameters the + association id (sasoc_assoc_id) should must be set to the value '0'. + The values of the sasoc_peer_rwnd is meaningless when examining + endpoint information. + + All parameters are time values, in milliseconds. A value of 0, when + modifying the parameters, indicates that the current value should not + be changed. + + The values of the sasoc_asocmaxrxt and sasoc_cookie_life may be set + on either an endpoint or association basis. The rwnd and destination + counts (sasoc_number_peer_destinations, + sasoc_peer_rwnd,sasoc_local_rwnd) are NOT settable and any value + placed in these is ignored. + + To access or modify these parameters, the application should call + getsockopt or setsockopt() respectively with the option name + SCTP_ASSOCINFO. + + The maximum number of retransmissions before an address is considered + unreachable is also tunable, but is address-specific, so it is + covered in a separate option. If an application attempts to set the + value of the association maximum retransmission parameter to more + than the sum of all maximum retransmission parameters, setsockopt() + shall return an error. The reason for this, from RFC2960 [RFC2960] + section 8.2: + + Note: When configuring the SCTP endpoint, the user should avoid + having the value of 'Association.Max.Retrans' larger than the + summation of the 'Path.Max.Retrans' of all the destination addresses + for the remote endpoint. Otherwise, all the destination addresses + may become inactive while the endpoint still considers the peer + endpoint reachable. + + + + + +Stewart, et al. Expires June 14, 2007 [Page 50] + +Internet-Draft SCTP sockets API December 2006 + + +7.1.3. Initialization Parameters (SCTP_INITMSG) + + Applications can specify protocol parameters for the default + association initialization. The structure used to access and modify + these parameters is defined in Section 5.2.1). The option name + argument to setsockopt() and getsockopt() is SCTP_INITMSG. + + Setting initialization parameters is effective only on an unconnected + socket (for one-to-many style sockets only future associations are + effected by the change). With one-to-one style sockets, this option + is inherited by sockets derived from a listener socket. + +7.1.4. SO_LINGER + + An application using the one-to-one style socket can use this option + to perform the SCTP ABORT primitive. The linger option structure is: + + struct linger { + int l_onoff; /* option on/off */ + int l_linger; /* linger time */ + }; + + To enable the option, set l_onoff to 1. If the l_linger value is set + to 0, calling close() is the same as the ABORT primitive. If the + value is set to a negative value, the setsockopt() call will return + an error. If the value is set to a positive value linger_time, the + close() can be blocked for at most linger_time ms. If the graceful + shutdown phase does not finish during this period, close() will + return but the graceful shutdown phase continues in the system. + + Note, this is a socket level option NOT an SCTP level option. So + when setting SO_LINGER you must specify a level of SOL_SOCKET in the + setsockopt() call. + +7.1.5. SCTP_NODELAY + + Turn on/off any Nagle-like algorithm. This means that packets are + generally sent as soon as possible and no unnecessary delays are + introduced, at the cost of more packets in the network. Expects an + integer boolean flag. + +7.1.6. SO_RCVBUF + + Sets receive buffer size in octets. For SCTP one-to-one style + sockets, this controls the receiver window size. For one-to-many + style sockets the meaning depends on the constant HAVE_SCTP_MULTIBUF + (see Section 3.4). If the implementation defines HAVE_SCTP_MULTIBUF + as 1, this controls the receiver window size for each association + + + +Stewart, et al. Expires June 14, 2007 [Page 51] + +Internet-Draft SCTP sockets API December 2006 + + + bound to the socket descriptor. If the implementation defines + HAVE_SCTP_MULTIBUF as 0, this controls the size of the single receive + buffer for the whole socket. The call expects an integer. + +7.1.7. SO_SNDBUF + + Sets send buffer size. For SCTP one-to-one style sockets, this + controls the amount of data SCTP may have waiting in internal buffers + to be sent. This option therefore bounds the maximum size of data + that can be sent in a single send call. For one-to-many style + sockets, the effect is the same, except that it applies to one or all + associations (see Section 3.4) bound to the socket descriptor used in + the setsockopt() or getsockopt() call. The option applies to each + association's window size separately. The call expects an integer. + +7.1.8. Automatic Close of associations (SCTP_AUTOCLOSE) + + This socket option is applicable to the one-to-many style socket + only. When set it will cause associations that are idle for more + than the specified number of seconds to automatically close using the + graceful shutdown procedure. An association being idle is defined as + an association that has NOT sent or received user data. The special + value of '0' indicates that no automatic close of any associations + should be performed, this is the default value. The option expects + an integer defining the number of seconds of idle time before an + association is closed. + + An application using this option should enable receiving the + association change notification. This is the only mechanism an + application is informed about the closing of an association. After + an association is closed, the association ID assigned to it can be + reused. An application should be aware of this to avoid the possible + problem of sending data to an incorrect peer end point. + +7.1.9. Set Peer Primary Address (SCTP_SET_PEER_PRIMARY_ADDR) + + Requests that the peer mark the enclosed address as the association + primary. The enclosed address must be one of the association's + locally bound addresses. The following structure is used to make a + set primary request: + + struct sctp_setpeerprim { + sctp_assoc_t sspp_assoc_id; + struct sockaddr_storage sspp_addr; + }; + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 52] + +Internet-Draft SCTP sockets API December 2006 + + + sspp_addr - The address to set as primary + sspp_assoc_id - This is filled in by the application, and identifies + the association for this request. + + This functionality is optional. Implementations that do not support + this functionality should return EOPNOTSUPP. + +7.1.10. Set Primary Address (SCTP_PRIMARY_ADDR) + + Requests that the local SCTP stack use the enclosed peer address as + the association primary. The enclosed address must be one of the + association peer's addresses. The following structure is used to + make a set peer primary request: + + struct sctp_setprim { + sctp_assoc_t ssp_assoc_id; + struct sockaddr_storage ssp_addr; + }; + + ssp_addr - The address to set as primary + ssp_assoc_id - This is filled in by the application, and identifies + the association for this request. + +7.1.11. Set Adaptation Layer Indicator (SCTP_ADAPTATION_LAYER) + + Requests that the local endpoint set the specified Adaptation Layer + Indication parameter for all future INIT and INIT-ACK exchanges. + + + struct sctp_setadaptation { + uint32_t ssb_adaptation_ind; + }; + + + ssb_adaptation_ind - The adaptation layer indicator that will be + included in any outgoing Adaptation Layer Indication parameter. + +7.1.12. Enable/Disable message fragmentation (SCTP_DISABLE_FRAGMENTS) + + This option is a on/off flag and is passed an integer where a non- + zero is on and a zero is off. If enabled no SCTP message + fragmentation will be performed. Instead if a message being sent + exceeds the current PMTU size, the message will NOT be sent and + instead a error will be indicated to the user. + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 53] + +Internet-Draft SCTP sockets API December 2006 + + +7.1.13. Peer Address Parameters (SCTP_PEER_ADDR_PARAMS) + + Applications can enable or disable heartbeats for any peer address of + an association, modify an address's heartbeat interval, force a + heartbeat to be sent immediately, and adjust the address's maximum + number of retransmissions sent before an address is considered + unreachable. The following structure is used to access and modify an + address's parameters: + + struct sctp_paddrparams { + sctp_assoc_t spp_assoc_id; + struct sockaddr_storage spp_address; + uint32_t spp_hbinterval; + uint16_t spp_pathmaxrxt; + uint32_t spp_pathmtu; + uint32_t spp_sackdelay; + uint32_t spp_flags; + uint32_t spp_ipv6_flowlabel; + uint8_t spp_ipv4_tos; + }; + + spp_assoc_id - (one-to-many style socket) This is filled in the + application, and identifies the association for this query. + spp_address - This specifies which address is of interest. + spp_hbinterval - This contains the value of the heartbeat interval, + in milliseconds. Note that unless the spp_flag is set to + SPP_HB_ENABLE the value of this field is ignored. Note also that + a value of zero indicates the current setting should be left + unchanged. To set an actual value of zero the use of the flag + SPP_HB_TIME_IS_ZERO should be used. + spp_pathmaxrxt - This contains the maximum number of retransmissions + before this address shall be considered unreachable. Note that + unless the spp_flag is set to SPP_PMTUD_ENABLE the value of this + field is ignored. Note also that a value of zero indicates the + current setting should be left unchanged. + spp_pathmtu - When Path MTU discovery is disabled the value + specified here will be the "fixed" path mtu (i.e. the value of the + spp_flags field must include the flag SPP_PMTUD_DISABLE for this + field to have any effect). Note that if the spp_address field is + empty then all associations on this address will have this fixed + path mtu set upon them. If an address is specified, then only + that address will be effected. + spp_sackdelay - When delayed sack is enabled, this value specifies + the number of milliseconds that sacks will be delayed for. This + value will apply to all addresses of an association if the + spp_address field is empty. Note that unless the spp_flag is set + to SPP_SACKDELAY_ENABLE the value of this field is ignored. Note + also that a value of zero indicates the current setting should be + + + +Stewart, et al. Expires June 14, 2007 [Page 54] + +Internet-Draft SCTP sockets API December 2006 + + + left unchanged. + spp_ipv6_flowlabel- This field is used in conjunction with the + SPP_IPV4_FLOWLABEL flag. + spp_ipv4_tos- This field is used in conjunction with the + SPP_IPV4_TOS flag. + spp_flags- These flags are used to control various features on an + association. The flag field is a bit mask which may contain zero + or more of the following options: + SPP_HB_ENABLE - Enable heartbeats on the specified address. Note + that if the address field is empty all addresses for the + association have heartbeats enabled upon them. + SPP_HB_DISABLE - Disable heartbeats on the specified address. + Note that if the address field is empty all addresses for the + association will have their heartbeats disabled. Note also + that SPP_HB_ENABLE and SPP_HB_DISABLE are mutually exclusive, + only one of these two should be specified. Enabling both + fields will have undetermined results. + SPP_HB_DEMAND - Request a user initiated heartbeat to be made + immediately. + SPP_HB_TIME_IS_ZERO - Specify's that the time for heartbeat delay + is to be set to the value of 0 milliseconds. + SPP_PMTUD_ENABLE - This field will enable PMTU discovery upon the + specified address. Note that if the address field is empty + then all addresses on the association are effected. + SPP_PMTUD_DISABLE - This field will disable PMTU discovery upon + the specified address. Note that if the address field is empty + then all addresses on the association are effected. Not also + that SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually + exclusive. Enabling both will have undetermined results. + SPP_SACKDELAY_ENABLE - Setting this flag turns on delayed sack. + The time specified in spp_sackdelay is used to specify the sack + delay for this address. Note that if spp_address is empty then + all addresses will enable delayed sack and take on the sack + delay value specified in spp_sackdelay. + SPP_SACKDELAY_DISABLE - Setting this flag turns off delayed sack. + If the spp_address field is blank then delayed sack is disabled + for the entire association. Note also that this field is + mutually exclusive to SPP_SACKDELAY_ENABLE, setting both will + have undefined results. + SPP_IPV6_FLOWLABEL - Setting this flag enables setting of the + IPV6 flowlabel value associated with either the association or + the specific address. If the address field is filled in, then + the specific destination address has this value set upon it. + If the association is specified, but not the address, then the + flowlabel value is set for any future destination addresses + that may be added. The value is obtained in the + spp_ipv6_flowlabel field. + + + + +Stewart, et al. Expires June 14, 2007 [Page 55] + +Internet-Draft SCTP sockets API December 2006 + + + Upon retrieval, this flag will be set to indicate that the + spp_ipv6_flowlabel field has a valid value returned. If a + specific destination addresses is set (in the spp_address + field) when called then the value returned is that of the + address. If just an association is specified (and no address) + then the association default flowlabel is returned. If neither + an association nor an destination is specified, then the + sockets default flowlabel is returned. For non IPv6 sockets, + then this flag will be left cleared. + SPP_IPV4_TOS - Setting this flag enables setting of the IPV4 tos + value associated with either the association or specific + address. If the address field is filled in, then the specific + destination address has this value set upon it. If the + association is specified, but not the address, then the tos + value is set for any future destination addresses that may be + added. The value is obtained in the spp_ipv4_tos field. + + Upon retrieval, this flag will be set to indicate that the + spp_ipv4_tos field has a valid value returned. If a specific + destination addresses is set when called (in the spp_address + field) then that specific destination addresses tos value is + returned. If just an association is specified then the + association default tos is returned. If neither an association + nor an destination is specified, then the sockets default tos + is returned. For non IPv4 sockets, then this flag will be left + cleared. + + To read or modify these parameters, the application should call + sctp_opt_info() with the SCTP_PEER_ADDR_PARAMS option. + +7.1.14. Set default send parameters (SCTP_DEFAULT_SEND_PARAM) + + Applications that wish to use the sendto() system call may wish to + specify a default set of parameters that would normally be supplied + through the inclusion of ancillary data. This socket option allows + such an application to set the default sctp_sndrcvinfo structure. + The application that wishes to use this socket option simply passes + in to this call the sctp_sndrcvinfo structure defined in + Section 5.2.2) The input parameters accepted by this call include + sinfo_stream, sinfo_flags, sinfo_ppid, sinfo_context, + sinfo_timetolive. The sinfo_assoc_id field specifies the default + association used for send operations on one-to-many style sockets. + It is ignored on the one-to-one style. Note that setting the + sinfo_assoc_id field to zero indicates that the users wishes to set + the endpoint default send parameters for all future associations. + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 56] + +Internet-Draft SCTP sockets API December 2006 + + +7.1.15. Set notification and ancillary events (SCTP_EVENTS) + + This socket option is used to specify various notifications and + ancillary data the user wishes to receive. Please see Section 7.3) + for a full description of this option and its usage. + +7.1.16. Set/clear IPv4 mapped addresses (SCTP_I_WANT_MAPPED_V4_ADDR) + + This socket option is a boolean flag which turns on or off mapped V4 + addresses. If this option is turned on and the socket is type + PF_INET6, then IPv4 addresses will be mapped to V6 representation. + If this option is turned off, then no mapping will be done of V4 + addresses and a user will receive both PF_INET6 and PF_INET type + addresses on the socket. + + By default this option is turned on and expects an integer to be + passed where non-zero turns on the option and zero turns off the + option. + +7.1.17. Set the maximum fragmentation size (SCTP_MAXSEG) + + This socket option specifies the maximum size to put in any outgoing + SCTP DATA chunk. If a message is larger than this size it will be + fragmented by SCTP into the specified size. Note that the underlying + SCTP implementation may fragment into smaller sized chunks when the + PMTU of the underlying association is smaller than the value set by + the user. The option expects an integer. + + The default value for this option is '0' which indicates the user is + NOT limiting fragmentation and only the PMTU will effect SCTP's + choice of DATA chunk size. + +7.1.18. Add a chunk that must be authenticated (SCTP_AUTH_CHUNK) + + This option adds a chunk type that the user is requesting to be + received only in an authenticated way. Changes to the list of chunks + will only effect future associations on the socket. + + struct sctp_authchunk { + uint8_t sauth_chunk; + }; + + sauth_chunks - This parameter contains a chunk type + that the user is requesting to be authenticated. + + + The chunk types for INIT, INIT-ACK, SHUTDOWN-COMPLETE, and AUTH + chunks MUST not be used. If they are used an error MUST be returned. + + + +Stewart, et al. Expires June 14, 2007 [Page 57] + +Internet-Draft SCTP sockets API December 2006 + + + The usage of this option enables SCTP-AUTH in cases where it is not + required by other means (for example the use of ADD-IP). + +7.1.19. Get or set the list of supported HMAC Identifiers + (SCTP_HMAC_IDENT) + + This option gets or sets the list of HMAC algorithms that the local + endpoint requires the peer to use. + + + struct sctp_hmacalgo { + uint16_t shmac_idents[]; + }; + + + shmac_idents - This parameter contains an array of HMAC Identifiers + that the local endpoint is requesting the peer to use, in priority + order. + +7.1.20. Set a shared key (SCTP_AUTH_KEY) + + This option will set a shared secret key which is used to build an + association shared key. + + struct sctp_authkey { + sctp_assoc_t sca_assoc_id; + uint16_t sca_keynumber; + uint8_t sca_key[]; + }; + + + sca_assoc_id - This parameter, if non-zero, indicates what + association that the shared key is being set upon. Note that if + this element contains zero, then the shared key is set upon the + endpoint and all future associations will use this key (if not + changed by subsequent calls to SCTP_AUTH_KEY). For one-to-one + sockets, this parameter is ignored. Note, however, that this + option will set a key on the association if the socket is + connected, otherwise this will set a key on the endpoint. + sca_keynumber - this parameter is the shared key identifier by which + the application will refer to this key. If a key of the specified + index already exists, then this new key will replace the old + existing key. Note that shared key identifier '0' defaults to a + null key. + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 58] + +Internet-Draft SCTP sockets API December 2006 + + + sca_key - This parameter contains an array of bytes that is to be + used by the endpoint (or association) as the shared secret key. + Note, if the length of this field is zero, a null key is set. + +7.1.21. Get or set the active shared key (SCTP_AUTH_ACTIVE_KEY) + + This option will get or set the active shared key to be used to build + the association shared key. + + + struct sctp_authkeyid { + sctp_assoc_t scact_assoc_id; + uint16_t scact_keynumber; + }; + + + scact_assoc_id - This parameter, if non-zero, indicates what + association that the shared key identifier is being set active + upon. Note that if this element contains zero, then the + activation applies to the endpoint and all future associations + will use the specified shared key identifier. For one-to-one + sockets, this parameter is ignored. Note, however, that this + option will set the active key on the association if the socket is + connected, otherwise this will set the default active key for the + endpoint. + scact_keynumber - this parameter is the shared key identifier which + the application is requesting to become the active shared key to + be used for sending authenticated chunks. The key identifier MUST + correspond to an existing shared key. Note that shared key + identifier '0' defaults to a null key. + +7.1.22. Delete a shared key (SCTP_AUTH_DELETE_KEY) + + This option will delete a shared secret key from use. + + + struct sctp_authkeyid { + sctp_assoc_t scact_assoc_id; + uint16_t scact_keynumber; + }; + + + scact_assoc_id - This parameter, if non-zero, indicates what + association that the shared key identifier is being deleted from. + Note that if this element contains zero, then the shared key is + deleted from the endpoint and all associations will no longer use + the specified shared key identifier (unless otherwise set on the + association using SCTP_AUTH_KEY). For one-to-one sockets, this + + + +Stewart, et al. Expires June 14, 2007 [Page 59] + +Internet-Draft SCTP sockets API December 2006 + + + parameter is ignored. Note, however, that this option will delete + the key from the association if the socket is connected, otherwise + this will delete the key from the endpoint. + scact_keynumber - this parameter is the shared key identifier which + the application is requesting to be deleted. The key identifier + MUST correspond to an existing shared key and MUST NOT be the + current active key. Note if this parameter is zero, use of the + null key identifier '0' is disabled on the endpoint and/or + association. + +7.1.23. Get or set delayed ack timer (SCTP_DELAYED_ACK_TIME) + + This options will get or set the delayed ack timer. The time is set + in milliseconds. If the assoc_id is 0, then this sets or gets the + endpoints default delayed ack timer value. If the assoc_id field is + non-zero, then the set or get effects the specified association. + + + struct sctp_assoc_value { + sctp_assoc_t assoc_id; + uint32_t assoc_value; + }; + + + assoc_id - This parameter, indicates which association the user is + performing an action upon. Note that if this field's value is + zero then the endpoints default value is changed (effecting future + associations only). + assoc_value - This parameter contains the number of milliseconds + that the user is requesting the delayed ACK timer be set to. Note + that this value is defined in the standard to be between 200 and + 500 milliseconds. + +7.1.24. Get or set fragmented interleave (SCTP_FRAGMENT_INTERLEAVE) + + This options will at a minimum specify if the implementation is doing + fragmented interleave. Fragmented interleave, for a one to many + socket, is when subsequent calls to receive a message may return + parts of messages from different associations. Some implementations + may allow you to turn this value on or off. If so, when turned off, + no fragment interleave will occur (which will cause a head of line + blocking amongst multiple associations sharing the same one to many + socket). When this option is turned on, then each receive call may + come from a different association (thus the user must receive data + with the extended calls (e.g. sctp_recvmsg) to keep track of which + association each receive belongs to. + + This option takes a boolean value. A non-zero value indicates that + + + +Stewart, et al. Expires June 14, 2007 [Page 60] + +Internet-Draft SCTP sockets API December 2006 + + + fragmented interleave is on. A value of zero indicates that + fragmented interleave is off. + + Note that it is important that an implementation that allows this + option to be turned on, have it off by default. Otherwise an unaware + application using the one to many model may become confused and act + incorrectly. + +7.1.25. Set or Get the sctp partial delivery point + (SCTP_PARTIAL_DELIVERY_POINT) + + This option will set or get the SCTP partial delivery point. This + point is the size of a message where the partial delivery API will be + invoked to help free up rwnd space for the peer. Setting this to a + lower value will cause partial delivery's to happen more often. The + calls argument is an integer that sets or gets the partial delivery + point. + +7.1.26. Set or Get the use of extended receive info + (SCTP_USE_EXT_RCVINFO) + + This option will enable or disable the use of the extended version of + the sctp_sndrcvinfo structure. If this option is disabled, then the + normal sctp_sndrcvinfo structure is returned in all receive message + calls. If this option is enabled then the sctp_extrcvinfo structure + is returned in all receive message calls. + + Note that the sctp_extrcvinfo structure is never used in any send + call. + +7.1.27. Set or Get the auto asconf flag (SCTP_AUTO_ASCONF) + + This option will enable or disable the use of the automatic + generation of ASCONF chunks to add and delete addresses to an + existing association. Note that this option has two caveats namely: + a) it only effects sockets that are bound to all addresses on the + machine, and b) the system administrator may have an overriding + control that turns the asconf feature off no matter what setting the + socket option may have. + +7.1.28. Set or Get the maximum burst (SCTP_MAX_BURST) + + This option will allow a user to change the maximum burst of packets + that can be emitted by this association. Note that the default value + is 4, and some implementations may restrict this setting so that it + can only be lowered. + + + + + +Stewart, et al. Expires June 14, 2007 [Page 61] + +Internet-Draft SCTP sockets API December 2006 + + +7.1.29. Set or Get the default context (SCTP_CONTEXT) + + The context field in the sctp_sndrcvinfo structure is normally only + used when a failed message is retrieved holding the value that was + sent down on the actual send call. This option allows the setting of + a default context on an association basis that will be received on + reading messages from the peer. This is especially helpful in the + one-2-many model for an application to keep some reference to an + internal state machine that is processing messages on the + association. Note that the setting of this value only effects + received messages from the peer and does not effect the value that is + saved with outbound messages. + + To set or get this option the user fills in the following structure: + + + struct sctp_assoc_value { + sctp_assoc_t assoc_id; + uint32_t assoc_value; + }; + + + assoc_id - This parameter, indicates which association the user is + performing an action upon. Note that if this field's value is + zero then the endpoints default value is changed (effecting future + associations only). + assoc_value - This parameter contains the context. + +7.1.30. Enable or disable explicit EOR marking (SCTP_EXPLICIT_EOR) + + This boolean flag is used to enable or disable explict end of record + (EOR) marking. When this option is enabled, a user may make multiple + send system calls to send a record and must indicate that they are + finished sending a particular record by including on the send the + SCTP_EOR flag. If this boolean flag is disabled then each individual + send system call is considered to have a SCTP_EOR indicator set on it + implicitly without the user having to explicitly add this flag. + +7.2. Read-Only Options + +7.2.1. Association Status (SCTP_STATUS) + + Applications can retrieve current status information about an + association, including association state, peer receiver window size, + number of unacked data chunks, and number of data chunks pending + receipt. This information is read-only. The following structure is + used to access this information: + + + + +Stewart, et al. Expires June 14, 2007 [Page 62] + +Internet-Draft SCTP sockets API December 2006 + + + struct sctp_status { + sctp_assoc_t sstat_assoc_id; + int32_t sstat_state; + uint32_t sstat_rwnd; + uint16_t sstat_unackdata; + uint16_t sstat_penddata; + uint16_t sstat_instrms; + uint16_t sstat_outstrms; + uint32_t sstat_fragmentation_point; + struct sctp_paddrinfo sstat_primary; + }; + + + sstat_state - This contains the association's current state one of + the following values: + SCTP_CLOSED + SCTP_BOUND + SCTP_LISTEN + SCTP_COOKIE_WAIT + SCTP_COOKIE_ECHOED + SCTP_ESTABLISHED + SCTP_SHUTDOWN_PENDING + SCTP_SHUTDOWN_SENT + SCTP_SHUTDOWN_RECEIVED + SCTP_SHUTDOWN_ACK_SENT + sstat_rwnd - This contains the association peer's current receiver + window size. + sstat_unackdata - This is the number of unacked data chunks. + sstat_penddata - This is the number of data chunks pending receipt. + sstat_primary - This is information on the current primary peer + address. + sstat_assoc_id - (one-to-many style socket) This holds the an + identifier for the association. All notifications for a given + association have the same association identifier. + sstat_instrms - The number of streams that the peer will be using + inbound. + sstat_outstrms - The number of streams that the endpoint is allowed + to use outbound. + sstat_fragmentation_point - The size at which SCTP fragmentation + will occur. + + To access these status values, the application calls getsockopt() + with the option name SCTP_STATUS. The sstat_assoc_id parameter is + ignored for one-to-one style socket. + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 63] + +Internet-Draft SCTP sockets API December 2006 + + +7.2.2. Peer Address Information (SCTP_GET_PEER_ADDR_INFO) + + Applications can retrieve information about a specific peer address + of an association, including its reachability state, congestion + window, and retransmission timer values. This information is read- + only. The following structure is used to access this information: + + + struct sctp_paddrinfo { + sctp_assoc_t spinfo_assoc_id; + struct sockaddr_storage spinfo_address; + int32_t spinfo_state; + uint32_t spinfo_cwnd; + uint32_t spinfo_srtt; + uint32_t spinfo_rto; + uint32_t spinfo_mtu; + }; + + + spinfo_address - This is filled in the application, and contains the + peer address of interest. + + On return from getsockopt(): + + spinfo_state - This contains the peer addresses's state (either + SCTP_ACTIVE or SCTP_INACTIVE and possibly the modifier + SCTP_UNCONFIRMED) + spinfo_cwnd - This contains the peer addresses's current congestion + window. + spinfo_srtt - This contains the peer addresses's current smoothed + round-trip time calculation in milliseconds. + spinfo_rto - This contains the peer addresses's current + retransmission timeout value in milliseconds. + spinfo_mtu - The current P-MTU of this address. + spinfo_assoc_id - This is field may be filled in by the application, + if so, this field will have priority in looking up the association + over the address specified in spinfo_address. Note that if the + address does not belong to the association specified then this + call will fail. If the application does NOT fill in the + spinfo_assoc_id, then the address will be used to lookup the + association and on return this field will have the valid + association id. In other words, this call can be used to + translate a address into an association id. + + To retrieve this information, use sctp_opt_info() with the + SCTP_GET_PEER_ADDR_INFO options. + + + + + +Stewart, et al. Expires June 14, 2007 [Page 64] + +Internet-Draft SCTP sockets API December 2006 + + +7.2.3. Get the list of chunks the peer requires to be authenticated + (SCTP_PEER_AUTH_CHUNKS) + + This option gets a list of chunks for a specified association that + the peer requires to be received authenticated only. + + + struct sctp_authchunks { + sctp_assoc_t gauth_assoc_id; + uint8_t gauth_chunks[]; + }; + + + gauth_assoc_id - This parameter, indicates which association the + user is requesting the list of peer authenticated chunks. For + one-to-one sockets, this parameter is ignored. + gauth_chunks - This parameter contains an array of chunks that the + peer is requesting to be authenticated. + +7.2.4. Get the list of chunks the local endpoint requires to be + authenticated (SCTP_LOCAL_AUTH_CHUNKS) + + This option gets a list of chunks for a specified association that + the local endpoint requires to be received authenticated only. + + + struct sctp_authchunks { + sctp_assoc_t gauth_assoc_id; + uint8_t gauth_chunks[]; + }; + + + gauth_assoc_id - This parameter, indicates which association the + user is requesting the list of local authenticated chunks. For + one-to-one sockets, this parameter is ignored. + gauth_chunks - This parameter contains an array of chunks that the + local endpoint is requesting to be authenticated. + +7.2.5. Get the list of current associations (SCTP_GET_ASOC_ID_LIST) + + This option gets a list of current associations that are associated + with a socket. + + + struct sctp_assoc_ids { + uint16_t asls_assoc_start; /* array of index's start at 0 */ + uint8_t asls_numb_present; + uint8_t asls_more_to_get; + + + +Stewart, et al. Expires June 14, 2007 [Page 65] + +Internet-Draft SCTP sockets API December 2006 + + + sctp_assoc_t asls_assoc_id[MAX_ASOC_IDS_RET]; + }; + + + asls_assoc_start - This parameter gives an initial starting place to + begin collecting association information. Normally a user sets + this initially to 0. Subsequent calls that need to get more + association identifications (in cases where the socket has more + than MAX_ASOC_IDS_RET established i.e asls_more_to_get returns set + to false) are made by incrementing the asls_assoc_start by the + number of previous association id's seen. This cycle is repeated + until the asls_more_to_get field becomes true, indicating that all + association id's have been retrieved. + asls_numb_present - This field holds the total number of + associations that have been copied into the asls_assoc_id array. + This value will NOT be larger than MAX_ASOC_IDS_RET. + asls_more_to_get - This field holds a boolean flag indicating to the + caller if more association id's are available then asked for. + Subsequent calls to this option will be needed to gather these + association id's. + asls_assoc_id - an array of association id's that are currently + active under this socket. + MAX_ASOC_IDS_RET This value is a constant defined to limit the + number of association identifications returned with each call. + This value can be no larger than 255.. + +7.3. Ancillary Data and Notification Interest Options + + Applications can receive per-message ancillary information and + notifications of certain SCTP events with recvmsg(). + + The following optional information is available to the application: + + 1. SCTP_SNDRCV (sctp_data_io_event): Per-message information (i.e. + stream number, TSN, SSN, etc. described in Section 5.2.2) + 2. SCTP_ASSOC_CHANGE (sctp_association_event): (described in + Section 5.3.1.1) + 3. SCTP_PEER_ADDR_CHANGE (sctp_address_event): (described in + Section 5.3.1.2) + 4. SCTP_SEND_FAILED (sctp_send_failure_event): (described in + Section 5.3.1.4) + 5. SCTP_REMOTE_ERROR (sctp_peer_error_event): (described in + Section 5.3.1.3) + 6. SCTP_SHUTDOWN_EVENT (sctp_shtudown_event): (described in + Section 5.3.1.5) + 7. SCTP_PARTIAL_DELIVERY_EVENT (sctp_partial_delivery_event): + (described in Section 5.3.1.7) + + + + +Stewart, et al. Expires June 14, 2007 [Page 66] + +Internet-Draft SCTP sockets API December 2006 + + + 8. SCTP_ADAPTATION_INDICATION (sctp_adaptation_layer_event): + (described in Section 5.3.1.6) + 9. SCTP_AUTHENTICATION_INDICATION (sctp_authentication_event): + (described in Section 5.3.1.8) + + To receive any ancillary data or notifications, first the application + registers it's interest by calling the SCTP_EVENTS setsockopt() with + the following structure. + + struct sctp_event_subscribe{ + uint8_t sctp_data_io_event; + uint8_t sctp_association_event; + uint8_t sctp_address_event; + uint8_t sctp_send_failure_event; + uint8_t sctp_peer_error_event; + uint8_t sctp_shutdown_event; + uint8_t sctp_partial_delivery_event; + uint8_t sctp_adaptation_layer_event; + uint8_t sctp_authentication_event; + }; + + sctp_data_io_event - Setting this flag to 1 will cause the reception + of SCTP_SNDRCV information on a per message basis. The application + will need to use the recvmsg() interface so that it can receive the + event information contained in the msg_control field. Please see + Section 5.2 for further details. Setting the flag to 0 will disable + reception of the message control information. + + sctp_association_event - Setting this flag to 1 will enable the + reception of association event notifications. Setting the flag to 0 + will disable association event notifications. For more information + on event notifications please see Section 5.3. + + sctp_address_event - Setting this flag to 1 will enable the reception + of address event notifications. Setting the flag to 0 will disable + address event notifications. For more information on event + notifications please see Section 5.3. + + sctp_send_failure_event - Setting this flag to 1 will enable the + reception of send failure event notifications. Setting the flag to 0 + will disable send failure event notifications. For more information + on event notifications please see Section 5.3. + + sctp_peer_error_event - Setting this flag to 1 will enable the + reception of peer error event notifications. Setting the flag to 0 + will disable peer error event notifications. For more information on + event notifications please see Section 5.3. + + + + +Stewart, et al. Expires June 14, 2007 [Page 67] + +Internet-Draft SCTP sockets API December 2006 + + + sctp_shutdown_event - Setting this flag to 1 will enable the + reception of shutdown event notifications. Setting the flag to 0 + will disable shutdown event notifications. For more information on + event notifications please see Section 5.3. + + sctp_partial_delivery_event - Setting this flag to 1 will enable the + reception of partial delivery notifications. Setting the flag to 0 + will disable partial delivery event notifications. For more + information on event notifications please see Section 5.3. + + sctp_adaptation_layer_event - Setting this flag to 1 will enable the + reception of adaptation layer notifications. Setting the flag to 0 + will disable adaptation layer event notifications. For more + information on event notifications please see Section 5.3. + + sctp_authentication_event - Setting this flag to 1 will enable the + reception of authentication layer notifications. Setting the flag to + 0 will disable authentication layer event notifications. For More + information please see Section 5.3. + + An example where an application would like to receive data io events + and association events but no others would be as follows: + + { + struct sctp_event_subscribe event; + + memset(&event,0,sizeof(event)); + + event.sctp_data_io_event = 1; + event.sctp_association_event = 1; + + setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)); + } + + Note that for one-to-many style SCTP sockets, the caller of recvmsg() + receives ancillary data and notifications for ALL associations bound + to the file descriptor. For one-to-one style SCTP sockets, the + caller receives ancillary data and notifications for only the single + association bound to the file descriptor. + + By default both the one-to-one style and one-to-many style socket has + all options off. + + +8. New Interfaces + + Depending on the system, the following interface can be implemented + as a system call or library function. + + + +Stewart, et al. Expires June 14, 2007 [Page 68] + +Internet-Draft SCTP sockets API December 2006 + + +8.1. sctp_bindx() + + The syntax of sctp_bindx() is, + + int sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, + int flags); + + If sd is an IPv4 socket, the addresses passed must be IPv4 addresses. + If the sd is an IPv6 socket, the addresses passed can either be IPv4 + or IPv6 addresses. + + A single address may be specified as INADDR_ANY or IN6ADDR_ANY, see + Section 3.1.2 for this usage. + + addrs is a pointer to an array of one or more socket addresses. Each + address is contained in its appropriate structure. For an IPv6 + socket, an array of sockaddr_in6 would be returned. For a IPv4 + socket, an array of sockaddr_in would be returned. The caller + specifies the number of addresses in the array with addrcnt. Note + that the wildcard addresses cannot be used with this function, doing + so will result in an error. + + On success, sctp_bindx() returns 0. On failure, sctp_bindx() returns + -1, and sets errno to the appropriate error code. + + For SCTP, the port given in each socket address must be the same, or + sctp_bindx() will fail, setting errno to EINVAL. + + The flags parameter is formed from the bitwise OR of zero or more of + the following currently defined flags: + + SCTP_BINDX_ADD_ADDR + + SCTP_BINDX_REM_ADDR + + SCTP_BINDX_ADD_ADDR directs SCTP to add the given addresses to the + association, and SCTP_BINDX_REM_ADDR directs SCTP to remove the given + addresses from the association. The two flags are mutually + exclusive; if both are given, sctp_bindx() will fail with EINVAL. A + caller may not remove all addresses from an association; sctp_bindx() + will reject such an attempt with EINVAL. + + An application can use sctp_bindx(SCTP_BINDX_ADD_ADDR) to associate + additional addresses with an endpoint after calling bind(). Or use + sctp_bindx(SCTP_BINDX_REM_ADDR) to remove some addresses a listening + socket is associated with so that no new association accepted will be + associated with those addresses. If the endpoint supports dynamic + address a SCTP_BINDX_REM_ADDR or SCTP_BINDX_ADD_ADDR may cause a + + + +Stewart, et al. Expires June 14, 2007 [Page 69] + +Internet-Draft SCTP sockets API December 2006 + + + endpoint to send the appropriate message to the peer to change the + peers address lists. + + Adding and removing addresses from a connected association is + optional functionality. Implementations that do not support this + functionality should return EOPNOTSUPP. + +8.2. Branched-off Association + + After an association is established on a one-to-many style socket, + the application may wish to branch off the association into a + separate socket/file descriptor. + + This is particularly desirable when, for instance, the application + wishes to have a number of sporadic message senders/receivers remain + under the original one-to-many style socket but branch off those + associations carrying high volume data traffic into their own + separate socket descriptors. + + The application uses sctp_peeloff() call to branch off an association + into a separate socket (Note the semantics are somewhat changed from + the traditional one-to-one style accept() call). Note that the new + socket is a one-to-one style socket. Thus it will be confined to + operations allowed for a one-to-one style socket. + + The syntax is: + + new_sd = sctp_peeloff(int sd, sctp_assoc_t assoc_id); + + new_sd: the new socket descriptor representing the branched-off + association. + sd: the original one-to-many style socket descriptor returned from + the socket() system call (see Section 3.1.1). + assoc_id: the specified identifier of the association that is to be + branched off to a separate file descriptor (Note, in a traditional + one-to-one style accept() call, this would be an out parameter, + but for the one-to-many style call, this is an in parameter). + +8.3. sctp_getpaddrs() + + sctp_getpaddrs() returns all peer addresses in an association. The + syntax is, + + int sctp_getpaddrs(int sd, sctp_assoc_t id, + struct sockaddr **addrs); + + + On return, addrs will point to an array dynamically allocated + + + +Stewart, et al. Expires June 14, 2007 [Page 70] + +Internet-Draft SCTP sockets API December 2006 + + + sockaddr structures of the appropriate type for the socket type. The + caller should use sctp_freepaddrs() to free the memory. Note that + the in/out parameter addrs must not be NULL. + + If sd is an IPv4 socket, the addresses returned will be all IPv4 + addresses. If sd is an IPv6 socket, the addresses returned can be a + mix of IPv4 or IPv6 addresses. + + For one-to-many style sockets, id specifies the association to query. + For one-to-one style sockets, id is ignored. + + On success, sctp_getpaddrs() returns the number of peer addresses in + the association. If there is no association on this socket, + sctp_getpaddrs() returns 0, and the value of *addrs is undefined. If + an error occurs, sctp_getpaddrs() returns -1, and the value of *addrs + is undefined. + +8.4. sctp_freepaddrs() + + + + sctp_freepaddrs() frees all resources allocated by + sctp_getpaddrs(). Its syntax is, + + void sctp_freepaddrs(struct sockaddr *addrs); + addrs is the array of peer addresses returned by sctp_getpaddrs(). + + +8.5. sctp_getladdrs() + + sctp_getladdrs() returns all locally bound address(es) on a socket. + The syntax is, + + int sctp_getladdrs(int sd, sctp_assoc_t id, + struct sockaddr **ss); + + + On return, addrs will point to a dynamically allocated array of + sockaddr structures of the appropriate type for the socket type. The + caller should use sctp_freeladdrs() to free the memory. Note that + the in/out parameter addrs must not be NULL. + + If sd is an IPv4 socket, the addresses returned will be all IPv4 + addresses. If sd is an IPv6 socket, the addresses returned can be a + mix of IPv4 or IPv6 addresses. + + For one-to-many style sockets, id specifies the association to query. + For one-to-one style sockets, id is ignored. + + + +Stewart, et al. Expires June 14, 2007 [Page 71] + +Internet-Draft SCTP sockets API December 2006 + + + If the id field is set to the value '0' then the locally bound + addresses are returned without regard to any particular association. + + On success, sctp_getladdrs() returns the number of local addresses + bound to the socket. If the socket is unbound, sctp_getladdrs() + returns 0, and the value of *addrs is undefined. If an error occurs, + sctp_getladdrs() returns -1, and the value of *addrs is undefined. + +8.6. sctp_freeladdrs() + + sctp_freeladdrs() frees all resources allocated by + sctp_getladdrs(). Its syntax is, + + void sctp_freeladdrs(struct sockaddr *addrs); + + addrs is the array of peer addresses returned by sctp_getladdrs(). + +8.7. sctp_sendmsg() + + An implementation may provide a library function (or possibly system + call) to assist the user with the advanced features of SCTP. + + + sctp_sendmsg(). Its syntax is, + + ssize_t sctp_sendmsg(int sd, + const void *msg, + size_t len, + const struct sockaddr *to, + socklen_t tolen, + uint32_t ppid, + uint32_t flags, + uint16_t stream_no, + uint32_t timetolive, + uint32_t context) + + + sd - is the socket descriptor + msg - is the message to be sent. + len - is the length of the message. + to - is the destination address of the message. + tolen - is the length of the destination address. + ppid - is the same as sinfo_ppid (see section 5.2.2) + flags - is the same as sinfo_flags (see section 5.2.2) + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 72] + +Internet-Draft SCTP sockets API December 2006 + + + stream_no - is the same as sinfo_stream (see section 5.2.2) + timetolive - is the same as sinfo_timetolive (see section 5.2.2) + context - is the same as sinfo_context (see section 5.2.2) + The call returns the number of characters sent, or -1 if an error + occurred. The variable errno is then set appropriately. + +8.8. sctp_recvmsg() + + An implementation may provide a library function (or possibly system + call) to assist the user with the advanced features of SCTP. Note + that in order for the sctp_sndrcvinfo structure to be filled in by + sctp_recvmsg() the caller must enable the sctp_data_io_events with + the SCTP_EVENTS option. Note that the setting of the + SCTP_USE_EXT_RCVINFO will effect this function as well, causing the + sctp_sndrcvinfo information to be extended. + + + sctp_recvmsg(). Its syntax is, + + ssize_t sctp_recvmsg(int sd, + void *msg, + size_t len, + struct sockaddr *from, + socklen_t *fromlen + struct sctp_sndrcvinfo *sinfo + int *msg_flags) + + + sd - is the socket descriptor + msg - is a message buffer to be filled. + len - is the length of the message buffer. + from - is a pointer to a address to be filled with the sender of + this messages address. + fromlen - is the from length. + sinfo - A pointer to a sctp_sndrcvinfo structure to be filled upon + receipt of the message. + msg_flags - A pointer to a integer to be filled with any message + flags (e.g. MSG_NOTIFICATION). + The call returns the number of bytes received, or -1 if an error + occurred. The variable errno is then set appropriately. + +8.9. sctp_connectx() + + An implementation may provide a library function (or possibly system + call) to assist the user with associating to an endpoint that is + multi-homed. Much like sctp_bindx() this call allows a caller to + specify multiple addresses at which a peer can be reached. The way + the SCTP stack uses the list of addresses to set up the association + + + +Stewart, et al. Expires June 14, 2007 [Page 73] + +Internet-Draft SCTP sockets API December 2006 + + + is implementation dependent. This function only specifies that the + stack will try to make use of all the addresses in the list when + needed. + + Note that the list of addresses passed in is only used for setting up + the association. It does not necessarily equal the set of addresses + the peer uses for the resulting association. If the caller wants to + find out the set of peer addresses, it must use sctp_getpaddrs() to + retrieve them after the association has been set up. + + sctp_connectx(). Its syntax is, + + + int sctp_connectx(int sd, + struct sockaddr *addrs, + int addrcnt, + sctp_assoc_t *id) + + + sd - is the socket descriptor + addrs - is an array of addresses. + addrcnt - is the number of addresses in the array. + id - is an output parameter that if passed in as a non-NULL will + return the association identification for the newly created + association (if successful). + + The call returns 0 on success or -1 if an error occured. The + variable errno is then set appropriately. + +8.10. sctp_send() + + An implementation may provide another alternative function or system + call to assist an application with the sending of data without the + use of the CMSG header structures. The function takes the following + form: + + sctp_send(). Its syntax is, + + int sctp_send(int sd, + const void *msg, + size_t len, + const struct sctp_sndrcvinfo *sinfo, + int flags); + + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 74] + +Internet-Draft SCTP sockets API December 2006 + + + sd - is the socket descriptor + msg - The message to be sent + len - The length of the message + sinfo - A pointer to a sctp_sndrcvinfo structure used as described + in 5.2.2 for a sendmsg call. + flags - is used in the same format as the sendmsg call flags (e.g. + MSG_DONTROUTE). + + This function call may also be used to terminate an association using + an association identification by setting the sinfo.sinfo_flags to + SCTP_EOF and the sinfo.sinfo_assoc_id to the association that needs + to be terminated. In such a case the len of the message would be + zero. + + The call returns the number of characters sent, or -1 if an error + occurred. The variable errno is then set appropriately. + +8.11. sctp_sendx() + + An implementation may provide another alternative function or system + call to assist an application with the sending of data without the + use of the CMSG header structures that also gives a list of + addresses. The list of addresses is provided for implicit + association setup. In such a case the list of addresses serves the + same purpose as the addresses given in sctp_connectx (see + Section 8.9). + + + sctp_sendx(). Its syntax is, + + int sctp_sendx(int sd, + const void *msg, + size_t len, + struct sockaddr *addrs, + int addrcnt, + struct sctp_sndrcvinfo *sinfo, + int flags); + + sd - is the socket descriptor + msg - The message to be sent + len - The length of the message + addrs - is an array of addresses. + addrcnt - is the number of addresses in the array. + sinfo - A pointer to a sctp_sndrcvinfo structure used as described + in 5.2.2 for a sendmsg call. + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 75] + +Internet-Draft SCTP sockets API December 2006 + + + flags - is used in the same format as the sendmsg call flags (e.g. + MSG_DONTROUTE). + + Note that on return from this call the sinfo structure will have + changed in that the sinfo_assoc_id will be filled in with the new + association id. + + This function call may also be used to terminate an association using + an association identification by setting the sinfo.sinfo_flags to + SCTP_EOF and the sinfo.sinfo_assoc_id to the association that needs + to be terminated. In such a case the len of the message would be + zero. + + The call returns the number of characters sent, or -1 if an error + occurred. The variable errno is then set appropriately. + +8.12. sctp_getaddrlen + + For application binary portability it is sometimes desirable to know + what the kernel thinks is the length of a socket address family. + This function, when called with a valid family type will return the + length that the operating system uses in the specified family's + socket address structure. + + + int sctp_getaddrlen(sa_family_t family); + + +9. Preprocessor Constants + + For application portability it is desirable to define pre-processor + constants for determination if sctp is present and supports various + features. The following pre-processor constants should be defined in + a include file, sctp.h. + + HAVE_SCTP - If this constant is defined to 1, then an implementation + of SCTP is available. + HAVE_KERNEL_SCTP - If this constant is defined to 1, then a kernel + SCTP implementation is available through the sockets interface. + HAVE_SCTP_PRSCTP - If this constant is defined to 1, then the SCTP + implementation supports the partial reliability extension to SCTP. + HAVE_SCTP_ADDIP - If this constant is defined to 1, then the SCTP + implementation supports the dynamic address extension to SCTP. + HAVE_SCTP_CANSET_PRIMARY - If this constant is defined to 1, then + the SCTP implementation supports the ability to request setting of + the remote primary address. + + + + + +Stewart, et al. Expires June 14, 2007 [Page 76] + +Internet-Draft SCTP sockets API December 2006 + + + HAVE_SCTP_SAT_NETWORK_CAPABILITY - If this constant is defined to 1, + then the SCTP implementation supports the satellite network + extension to SCTP. + HAVE_SCTP_MULTIBUF - If this constant is defined to 1, then the SCTP + implementation dedicates separate buffer space to each association + on a one-to-many socket. If this constant is defined to 0, then + the implementation provides a single block of shared buffer space + for a one-to-many socket. + HAVE_SCTP_NOCONNECT - If this constant is defined to 1, then the + SCTP implementation supports initiating an association on a one- + to-one style socket without the use of connect(), as outlined in + Section 4.1.5. + HAVE_SCTP_EXT_RCVINFO - If this constant is defined to 1, then the + SCTP implementation supports the use of the extended style + sndrecinfo structure, sctp_extrcvinfo. + + +10. IANA considerations + + This document contains no IANA considerations. + + +11. Security Considerations + + Many TCP and UDP implementations reserve port numbers below 1024 for + privileged users. If the target platform supports privileged users, + the SCTP implementation SHOULD restrict the ability to call bind() or + sctp_bindx() on these port numbers to privileged users. + + Similarly unprivileged users should not be able to set protocol + parameters which could result in the congestion control algorithm + being more aggressive than permitted on the public Internet. These + parameters are: + + struct sctp_rtoinfo + + If an unprivileged user inherits a one-to-many style socket with open + associations on a privileged port, it MAY be permitted to accept new + associations, but it SHOULD NOT be permitted to open new + associations. This could be relevant for the r* family of protocols. + + +12. Acknowledgments + + Special acknowledgment is given to Ken Fujita and Jonathan Woods who + helped extensively in the early formation of this document. + + The authors also wish to thank Kavitha Baratakke, Mike Bartlett, Jon + + + +Stewart, et al. Expires June 14, 2007 [Page 77] + +Internet-Draft SCTP sockets API December 2006 + + + Berger, Mark Butler, Scott Kimble, Renee Revis, Andreas Fink, and + many others on the TSVWG mailing list for contributing valuable + comments. + + A special thanks to Phillip Conrad, for his suggested text, quick and + constructive insights, and most of all his persistent fighting to + keep the interface to SCTP usable for the application programmer. + + +13. Normative references + + [RFC0793] Postel, J., "Transmission Control Protocol", STD 7, + RFC 793, September 1981. + + [RFC0768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, + August 1980. + + [RFC1644] Braden, B., "T/TCP -- TCP Extensions for Transactions + Functional Specification", RFC 1644, July 1994. + + [RFC2026] Bradner, S., "The Internet Standards Process -- Revision + 3", BCP 9, RFC 2026, October 1996. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC2292] Stevens, W. and M. Thomas, "Advanced Sockets API for + IPv6", RFC 2292, February 1998. + + [RFC2553] Gilligan, R., Thomson, S., Bound, J., and W. Stevens, + "Basic Socket Interface Extensions for IPv6", RFC 2553, + March 1999. + + [RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C., + Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M., + Zhang, L., and V. Paxson, "Stream Control Transmission + Protocol", RFC 2960, October 2000. + + +Appendix A. one-to-one style Code Example + + The following code is a simple implementation of an echo server over + SCTP. The example shows how to use some features of one-to-one style + IPv4 SCTP sockets, including: + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 78] + +Internet-Draft SCTP sockets API December 2006 + + + o Opening, binding, and listening for new associations on a socket; + o Enabling ancillary data + o Enabling notifications + o Using ancillary data with sendmsg() and recvmsg() + o Using MSG_EOR to determine if an entire message has been read + o Handling notifications + + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #define BUFLEN 100 + + static void + handle_event(void *buf) + { + struct sctp_assoc_change *sac; + struct sctp_send_failed *ssf; + struct sctp_paddr_change *spc; + struct sctp_remote_error *sre; + union sctp_notification *snp; + char addrbuf[INET6_ADDRSTRLEN]; + const char *ap; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + + snp = buf; + + switch (snp->sn_header.sn_type) { + case SCTP_ASSOC_CHANGE: + sac = &snp->sn_assoc_change; + printf("^^^ assoc_change: state=%hu, error=%hu, instr=%hu " + "outstr=%hu\n", sac->sac_state, sac->sac_error, + sac->sac_inbound_streams, sac->sac_outbound_streams); + break; + case SCTP_SEND_FAILED: + ssf = &snp->sn_send_failed; + printf("^^^ sendfailed: len=%hu err=%d\n", ssf->ssf_length, + ssf->ssf_error); + break; + + case SCTP_PEER_ADDR_CHANGE: + + + +Stewart, et al. Expires June 14, 2007 [Page 79] + +Internet-Draft SCTP sockets API December 2006 + + + spc = &snp->sn_paddr_change; + if (spc->spc_aaddr.ss_family == AF_INET) { + sin = (struct sockaddr_in *)&spc->spc_aaddr; + ap = inet_ntop(AF_INET, &sin->sin_addr, + addrbuf, INET6_ADDRSTRLEN); + } else { + sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr; + ap = inet_ntop(AF_INET6, &sin6->sin6_addr, + addrbuf, INET6_ADDRSTRLEN); + } + printf("^^^ intf_change: %s state=%d, error=%d\n", ap, + spc->spc_state, spc->spc_error); + break; + case SCTP_REMOTE_ERROR: + sre = &snp->sn_remote_error; + printf("^^^ remote_error: err=%hu len=%hu\n", + ntohs(sre->sre_error), ntohs(sre->sre_length)); + break; + case SCTP_SHUTDOWN_EVENT: + printf("^^^ shutdown event\n"); + break; + default: + printf("unknown type: %hu\n", snp->sn_header.sn_type); + break; + }; + } + + static void * + mysctp_recvmsg(int fd, struct msghdr *msg, void *buf, size_t *buflen, + ssize_t *nrp, size_t cmsglen) + { + ssize_t nr = 0, nnr = 0; + struct iovec iov[1]; + + *nrp = 0; + iov->iov_base = buf; + iov->iov_len = *buflen; + msg->msg_iov = iov; + msg->msg_iovlen = 1; + + + for (;;) { + #ifndef MSG_XPG4_2 + #define MSG_XPG4_2 0 + #endif + msg->msg_flags = MSG_XPG4_2; + msg->msg_controllen = cmsglen; + + + + +Stewart, et al. Expires June 14, 2007 [Page 80] + +Internet-Draft SCTP sockets API December 2006 + + + nnr = recvmsg(fd, msg, 0); + if (nnr <= 0) { + /* EOF or error */ + *nrp = nr; + return (NULL); + } + nr += nnr; + + if ((msg->msg_flags & MSG_EOR) != 0) { + *nrp = nr; + return (buf); + } + + /* Realloc the buffer? */ + if (*buflen == (size_t)nr) { + buf = realloc(buf, *buflen * 2); + if (buf == 0) { + fprintf(stderr, "out of memory\n"); + exit(1); + } + *buflen *= 2; + } + /* Set the next read offset */ + iov->iov_base = (char *)buf + nr; + iov->iov_len = *buflen - nr; + } + } + + static void + echo(int fd, int socketModeone_to_many) + { + ssize_t nr; + struct sctp_sndrcvinfo *sri; + struct msghdr msg[1]; + struct cmsghdr *cmsg; + char cbuf[sizeof (*cmsg) + sizeof (*sri)]; + char *buf; + size_t buflen; + struct iovec iov[1]; + size_t cmsglen = sizeof (*cmsg) + sizeof (*sri); + /* Allocate the initial data buffer */ + buflen = BUFLEN; + if (!(buf = malloc(BUFLEN))) { + fprintf(stderr, "out of memory\n"); + exit(1); + } + + /* Set up the msghdr structure for receiving */ + + + +Stewart, et al. Expires June 14, 2007 [Page 81] + +Internet-Draft SCTP sockets API December 2006 + + + memset(msg, 0, sizeof (*msg)); + msg->msg_control = cbuf; + msg->msg_controllen = cmsglen; + msg->msg_flags = 0; + cmsg = (struct cmsghdr *)cbuf; + sri = (struct sctp_sndrcvinfo *)(cmsg + 1); + + /* Wait for something to echo */ + while (buf = mysctp_recvmsg(fd, msg, + buf, &buflen, &nr, cmsglen)) { + + /* Intercept notifications here */ + if (msg->msg_flags & MSG_NOTIFICATION) { + handle_event(buf); + continue; + } + + iov->iov_base = buf; + iov->iov_len = nr; + msg->msg_iov = iov; + msg->msg_iovlen = 1; + + printf("got %u bytes on stream %hu:\n", nr, + sri->sinfo_stream); + write(0, buf, nr); + + /* Echo it back */ + msg->msg_flags = MSG_XPG4_2; + if (sendmsg(fd, msg, 0) < 0) { + perror("sendmsg"); + exit(1); + } + } + + if (nr < 0) { + perror("recvmsg"); + } + if(socketModeone_to_many == 0) + close(fd); + } + + int main() + { + struct sctp_event_subscribe event; + int lfd, cfd; + int onoff = 1; + struct sockaddr_in sin[1]; + if ((lfd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1) { + + + +Stewart, et al. Expires June 14, 2007 [Page 82] + +Internet-Draft SCTP sockets API December 2006 + + + perror("socket"); + exit(1); + } + + sin->sin_family = AF_INET; + sin->sin_port = htons(7); + sin->sin_addr.s_addr = INADDR_ANY; + if (bind(lfd, (struct sockaddr *)sin, sizeof (*sin)) == -1) { + perror("bind"); + exit(1); + } + + if (listen(lfd, 1) == -1) { + perror("listen"); + exit(1); + } + + /* Wait for new associations */ + for (;;) { + if ((cfd = accept(lfd, NULL, 0)) == -1) { + perror("accept"); + exit(1); + } + + /* Enable all events */ + event.sctp_data_io_event = 1; + event.sctp_association_event = 1; + event.sctp_address_event = 1; + event.sctp_send_failure_event = 1; + event.sctp_peer_error_event = 1; + event.sctp_shutdown_event = 1; + event.sctp_partial_delivery_event = 1; + event.sctp_adaptation_layer_event = 1; + if (setsockopt(cfd, IPPROTO_SCTP, + SCTP_EVENTS, &event, + sizeof(event)) != 0) { + perror("setevent failed"); + exit(1); + } + /* Echo back any and all data */ + echo(cfd,0); + } + } + + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 83] + +Internet-Draft SCTP sockets API December 2006 + + +Appendix B. one-to-many style Code Example + + The following code is a simple implementation of an echo server over + SCTP. The example shows how to use some features of one-to-many + style IPv4 SCTP sockets, including: + + o Opening and binding of a socket; + o Enabling ancillary data + o Enabling notifications + o Using ancillary data with sendmsg() and recvmsg() + o Using MSG_EOR to determine if an entire message has been read + o Handling notifications + + Note most functions defined in Appendix A are reused in this example. + + int main() + { + int fd; + int idleTime = 2; + struct sockaddr_in sin[1]; + struct sctp_event_subscribe event; + + if ((fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) == -1) { + perror("socket"); + exit(1); + } + + sin->sin_family = AF_INET; + sin->sin_port = htons(7); + sin->sin_addr.s_addr = INADDR_ANY; + if (bind(fd, (struct sockaddr *)sin, sizeof (*sin)) == -1) { + perror("bind"); + exit(1); + } + + /* Enable all notifications and events */ + event.sctp_data_io_event = 1; + event.sctp_association_event = 1; + event.sctp_address_event = 1; + event.sctp_send_failure_event = 1; + event.sctp_peer_error_event = 1; + event.sctp_shutdown_event = 1; + event.sctp_partial_delivery_event = 1; + event.sctp_adaptation_layer_event = 1; + if (setsockopt(fd, IPPROTO_SCTP, + SCTP_EVENTS, &event, + sizeof(event)) != 0) { + perror("setevent failed"); + + + +Stewart, et al. Expires June 14, 2007 [Page 84] + +Internet-Draft SCTP sockets API December 2006 + + + exit(1); + } + /* Set associations to auto-close in 2 seconds of + * inactivity + */ + if (setsockopt(fd, IPPROTO_SCTP, SCTP_AUTOCLOSE, + &idleTime, 4) < 0) { + perror("setsockopt SCTP_AUTOCLOSE"); + exit(1); + } + + /* Allow new associations to be accepted */ + if (listen(fd, 1) < 0) { + perror("listen"); + exit(1); + } + + /* Wait for new associations */ + while(1){ + /* Echo back any and all data */ + echo(fd,1); + } + } + + +Authors' Addresses + + Randall R. Stewart + Cisco Systems, Inc. + 4875 Forest Drive + Suite 200 + Columbia, SC 29206 + USA + + Phone: + Email: rrs@cisco.com + + + Qiaobing Xie + Motorola, Inc. + 1501 W. Shure Drive, #2309 + Arlington Heights, IL 60004 + USA + + Phone: + Email: qxie1@email.mot.com + + + + + +Stewart, et al. Expires June 14, 2007 [Page 85] + +Internet-Draft SCTP sockets API December 2006 + + + La Monte H.P. Yarroll + TimeSys Corp + 925 Liberty Ave. + Pittsburgh, PA 15222 + USA + + Phone: + Email: piggy@acm.org + + + Kacheong Poon + Sun Microsystems, Inc. + 4150 Network Circle + Santa Clara, CA 95054 + USA + + Phone: + Email: kacheong.poon@sun.com + + + Michael Tuexen + Univ. of Applied Sciences Muenster + Stegerwaldstr. 39 + 48565 Steinfurt + Germany + + Email: tuexen@fh-muenster.de + + + + + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Expires June 14, 2007 [Page 86] + +Internet-Draft SCTP sockets API December 2006 + + +Full Copyright Statement + + Copyright (C) The IETF Trust (2006). + + This document is subject to the rights, licenses and restrictions + contained in BCP 78, and except as set forth therein, the authors + retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND + THE INTERNET ENGINEERING TASK FORCE DISCLAIM 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. + + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at + ietf-ipr@ietf.org. + + +Acknowledgment + + Funding for the RFC Editor function is provided by the IETF + Administrative Support Activity (IASA). + + + + + +Stewart, et al. Expires June 14, 2007 [Page 87] + + diff --git a/doc/rfc2960.txt b/doc/rfc2960.txt new file mode 100644 index 0000000..7054d55 --- /dev/null +++ b/doc/rfc2960.txt @@ -0,0 +1,7507 @@ + + + + + + +Network Working Group R. Stewart +Request for Comments: 2960 Q. Xie +Category: Standards Track Motorola + K. Morneault + C. Sharp + Cisco + H. Schwarzbauer + Siemens + T. Taylor + Nortel Networks + I. Rytina + Ericsson + M. Kalla + Telcordia + L. Zhang + UCLA + V. Paxson + ACIRI + October 2000 + + + Stream Control Transmission Protocol + +Status of this Memo + + This document specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" (STD 1) for the standardization state + and status of this protocol. Distribution of this memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2000). All Rights Reserved. + +Abstract + + This document describes the Stream Control Transmission Protocol + (SCTP). SCTP is designed to transport PSTN signaling messages over + IP networks, but is capable of broader applications. + + SCTP is a reliable transport protocol operating on top of a + connectionless packet network such as IP. It offers the following + services to its users: + + -- acknowledged error-free non-duplicated transfer of user data, + -- data fragmentation to conform to discovered path MTU size, + + + + +Stewart, et al. Standards Track [Page 1] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + -- sequenced delivery of user messages within multiple streams, + with an option for order-of-arrival delivery of individual user + messages, + -- optional bundling of multiple user messages into a single SCTP + packet, and + -- network-level fault tolerance through supporting of multi- + homing at either or both ends of an association. + + The design of SCTP includes appropriate congestion avoidance behavior + and resistance to flooding and masquerade attacks. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 2] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +Table of Contents + + 1. Introduction.................................................. 5 + 1.1 Motivation.................................................. 6 + 1.2 Architectural View of SCTP.................................. 6 + 1.3 Functional View of SCTP..................................... 7 + 1.3.1 Association Startup and Takedown........................ 8 + 1.3.2 Sequenced Delivery within Streams....................... 9 + 1.3.3 User Data Fragmentation................................. 9 + 1.3.4 Acknowledgement and Congestion Avoidance................ 9 + 1.3.5 Chunk Bundling ......................................... 10 + 1.3.6 Packet Validation....................................... 10 + 1.3.7 Path Management......................................... 11 + 1.4 Key Terms................................................... 11 + 1.5 Abbreviations............................................... 15 + 1.6 Serial Number Arithmetic.................................... 15 + 2. Conventions.................................................... 16 + 3. SCTP packet Format............................................ 16 + 3.1 SCTP Common Header Field Descriptions....................... 17 + 3.2 Chunk Field Descriptions.................................... 18 + 3.2.1 Optional/Variable-length Parameter Format............... 20 + 3.3 SCTP Chunk Definitions...................................... 21 + 3.3.1 Payload Data (DATA)..................................... 22 + 3.3.2 Initiation (INIT)....................................... 24 + 3.3.2.1 Optional or Variable Length Parameters.............. 26 + 3.3.3 Initiation Acknowledgement (INIT ACK)................... 30 + 3.3.3.1 Optional or Variable Length Parameters.............. 33 + 3.3.4 Selective Acknowledgement (SACK)........................ 33 + 3.3.5 Heartbeat Request (HEARTBEAT)........................... 37 + 3.3.6 Heartbeat Acknowledgement (HEARTBEAT ACK)............... 38 + 3.3.7 Abort Association (ABORT)............................... 39 + 3.3.8 Shutdown Association (SHUTDOWN)......................... 40 + 3.3.9 Shutdown Acknowledgement (SHUTDOWN ACK)................. 40 + 3.3.10 Operation Error (ERROR)................................ 41 + 3.3.10.1 Invalid Stream Identifier.......................... 42 + 3.3.10.2 Missing Mandatory Parameter........................ 43 + 3.3.10.3 Stale Cookie Error................................. 43 + 3.3.10.4 Out of Resource.................................... 44 + 3.3.10.5 Unresolvable Address............................... 44 + 3.3.10.6 Unrecognized Chunk Type............................ 44 + 3.3.10.7 Invalid Mandatory Parameter........................ 45 + 3.3.10.8 Unrecognized Parameters............................ 45 + 3.3.10.9 No User Data....................................... 46 + 3.3.10.10 Cookie Received While Shutting Down............... 46 + 3.3.11 Cookie Echo (COOKIE ECHO).............................. 46 + 3.3.12 Cookie Acknowledgement (COOKIE ACK).................... 47 + 3.3.13 Shutdown Complete (SHUTDOWN COMPLETE).................. 48 + 4. SCTP Association State Diagram................................. 48 + + + +Stewart, et al. Standards Track [Page 3] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + 5. Association Initialization..................................... 52 + 5.1 Normal Establishment of an Association...................... 52 + 5.1.1 Handle Stream Parameters................................ 54 + 5.1.2 Handle Address Parameters............................... 54 + 5.1.3 Generating State Cookie................................. 56 + 5.1.4 State Cookie Processing................................. 57 + 5.1.5 State Cookie Authentication............................. 57 + 5.1.6 An Example of Normal Association Establishment.......... 58 + 5.2 Handle Duplicate or unexpected INIT, INIT ACK, COOKIE ECHO, + and COOKIE ACK.............................................. 60 + 5.2.1 Handle Duplicate INIT in COOKIE-WAIT + or COOKIE-ECHOED States................................. 60 + 5.2.2 Unexpected INIT in States Other than CLOSED, + COOKIE-ECHOED, COOKIE-WAIT and SHUTDOWN-ACK-SENT........ 61 + 5.2.3 Unexpected INIT ACK..................................... 61 + 5.2.4 Handle a COOKIE ECHO when a TCB exists.................. 62 + 5.2.4.1 An Example of a Association Restart................. 64 + 5.2.5 Handle Duplicate COOKIE ACK............................. 66 + 5.2.6 Handle Stale COOKIE Error............................... 66 + 5.3 Other Initialization Issues................................. 67 + 5.3.1 Selection of Tag Value.................................. 67 + 6. User Data Transfer............................................. 67 + 6.1 Transmission of DATA Chunks................................. 69 + 6.2 Acknowledgement on Reception of DATA Chunks................. 70 + 6.2.1 Tracking Peer's Receive Buffer Space.................... 73 + 6.3 Management Retransmission Timer............................. 75 + 6.3.1 RTO Calculation......................................... 75 + 6.3.2 Retransmission Timer Rules.............................. 76 + 6.3.3 Handle T3-rtx Expiration................................ 77 + 6.4 Multi-homed SCTP Endpoints.................................. 78 + 6.4.1 Failover from Inactive Destination Address.............. 79 + 6.5 Stream Identifier and Stream Sequence Number................ 80 + 6.6 Ordered and Unordered Delivery.............................. 80 + 6.7 Report Gaps in Received DATA TSNs........................... 81 + 6.8 Adler-32 Checksum Calculation............................... 82 + 6.9 Fragmentation............................................... 83 + 6.10 Bundling .................................................. 84 + 7. Congestion Control .......................................... 85 + 7.1 SCTP Differences from TCP Congestion Control................ 85 + 7.2 SCTP Slow-Start and Congestion Avoidance.................... 87 + 7.2.1 Slow-Start.............................................. 87 + 7.2.2 Congestion Avoidance.................................... 89 + 7.2.3 Congestion Control...................................... 89 + 7.2.4 Fast Retransmit on Gap Reports.......................... 90 + 7.3 Path MTU Discovery.......................................... 91 + 8. Fault Management.............................................. 92 + 8.1 Endpoint Failure Detection.................................. 92 + 8.2 Path Failure Detection...................................... 92 + + + +Stewart, et al. Standards Track [Page 4] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + 8.3 Path Heartbeat.............................................. 93 + 8.4 Handle "Out of the blue" Packets............................ 95 + 8.5 Verification Tag............................................ 96 + 8.5.1 Exceptions in Verification Tag Rules.................... 97 + 9. Termination of Association..................................... 98 + 9.1 Abort of an Association..................................... 98 + 9.2 Shutdown of an Association.................................. 98 + 10. Interface with Upper Layer....................................101 + 10.1 ULP-to-SCTP................................................101 + 10.2 SCTP-to-ULP................................................111 + 11. Security Considerations.......................................114 + 11.1 Security Objectives........................................114 + 11.2 SCTP Responses To Potential Threats........................115 + 11.2.1 Countering Insider Attacks.............................115 + 11.2.2 Protecting against Data Corruption in the Network......115 + 11.2.3 Protecting Confidentiality.............................115 + 11.2.4 Protecting against Blind Denial of Service Attacks.....116 + 11.2.4.1 Flooding...........................................116 + 11.2.4.2 Blind Masquerade...................................118 + 11.2.4.3 Improper Monopolization of Services................118 + 11.3 Protection against Fraud and Repudiation...................119 + 12. Recommended Transmission Control Block (TCB) Parameters.......120 + 12.1 Parameters necessary for the SCTP instance.................120 + 12.2 Parameters necessary per association (i.e. the TCB)........120 + 12.3 Per Transport Address Data.................................122 + 12.4 General Parameters Needed..................................123 + 13. IANA Considerations...........................................123 + 13.1 IETF-defined Chunk Extension...............................123 + 13.2 IETF-defined Chunk Parameter Extension.....................124 + 13.3 IETF-defined Additional Error Causes.......................124 + 13.4 Payload Protocol Identifiers...............................125 + 14. Suggested SCTP Protocol Parameter Values......................125 + 15. Acknowledgements..............................................126 + 16. Authors' Addresses............................................126 + 17. References....................................................128 + 18. Bibliography..................................................129 + Appendix A .......................................................131 + Appendix B .......................................................132 + Full Copyright Statement .........................................134 + +1. Introduction + + This section explains the reasoning behind the development of the + Stream Control Transmission Protocol (SCTP), the services it offers, + and the basic concepts needed to understand the detailed description + of the protocol. + + + + + +Stewart, et al. Standards Track [Page 5] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +1.1 Motivation + + TCP [RFC793] has performed immense service as the primary means of + reliable data transfer in IP networks. However, an increasing number + of recent applications have found TCP too limiting, and have + incorporated their own reliable data transfer protocol on top of UDP + [RFC768]. The limitations which users have wished to bypass include + the following: + + -- TCP provides both reliable data transfer and strict order-of- + transmission delivery of data. Some applications need reliable + transfer without sequence maintenance, while others would be + satisfied with partial ordering of the data. In both of these + cases the head-of-line blocking offered by TCP causes unnecessary + delay. + + -- The stream-oriented nature of TCP is often an inconvenience. + Applications must add their own record marking to delineate their + messages, and must make explicit use of the push facility to + ensure that a complete message is transferred in a reasonable + time. + + -- The limited scope of TCP sockets complicates the task of + providing highly-available data transfer capability using multi- + homed hosts. + + -- TCP is relatively vulnerable to denial of service attacks, such + as SYN attacks. + + Transport of PSTN signaling across the IP network is an application + for which all of these limitations of TCP are relevant. While this + application directly motivated the development of SCTP, other + applications may find SCTP a good match to their requirements. + +1.2 Architectural View of SCTP + + SCTP is viewed as a layer between the SCTP user application ("SCTP + user" for short) and a connectionless packet network service such as + IP. The remainder of this document assumes SCTP runs on top of IP. + The basic service offered by SCTP is the reliable transfer of user + messages between peer SCTP users. It performs this service within + the context of an association between two SCTP endpoints. Section 10 + of this document sketches the API which should exist at the boundary + between the SCTP and the SCTP user layers. + + SCTP is connection-oriented in nature, but the SCTP association is a + broader concept than the TCP connection. SCTP provides the means for + each SCTP endpoint (Section 1.4) to provide the other endpoint + + + +Stewart, et al. Standards Track [Page 6] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + (during association startup) with a list of transport addresses + (i.e., multiple IP addresses in combination with an SCTP port) + through which that endpoint can be reached and from which it will + originate SCTP packets. The association spans transfers over all of + the possible source/destination combinations which may be generated + from each endpoint's lists. + + _____________ _____________ + | SCTP User | | SCTP User | + | Application | | Application | + |-------------| |-------------| + | SCTP | | SCTP | + | Transport | | Transport | + | Service | | Service | + |-------------| |-------------| + | |One or more ---- One or more| | + | IP Network |IP address \/ IP address| IP Network | + | Service |appearances /\ appearances| Service | + |_____________| ---- |_____________| + + SCTP Node A |<-------- Network transport ------->| SCTP Node B + + Figure 1: An SCTP Association + +1.3 Functional View of SCTP + + The SCTP transport service can be decomposed into a number of + functions. These are depicted in Figure 2 and explained in the + remainder of this section. + + + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 7] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + SCTP User Application + + ----------------------------------------------------- + _____________ ____________________ + | | | Sequenced delivery | + | Association | | within streams | + | | |____________________| + | startup | + | | ____________________________ + | and | | User Data Fragmentation | + | | |____________________________| + | takedown | + | | ____________________________ + | | | Acknowledgement | + | | | and | + | | | Congestion Avoidance | + | | |____________________________| + | | + | | ____________________________ + | | | Chunk Bundling | + | | |____________________________| + | | + | | ________________________________ + | | | Packet Validation | + | | |________________________________| + | | + | | ________________________________ + | | | Path Management | + |_____________| |________________________________| + + Figure 2: Functional View of the SCTP Transport Service + +1.3.1 Association Startup and Takedown + + An association is initiated by a request from the SCTP user (see the + description of the ASSOCIATE (or SEND) primitive in Section 10). + + A cookie mechanism, similar to one described by Karn and Simpson in + [RFC2522], is employed during the initialization to provide + protection against security attacks. The cookie mechanism uses a + four-way handshake, the last two legs of which are allowed to carry + user data for fast setup. The startup sequence is described in + Section 5 of this document. + + SCTP provides for graceful close (i.e., shutdown) of an active + association on request from the SCTP user. See the description of + the SHUTDOWN primitive in Section 10. SCTP also allows ungraceful + close (i.e., abort), either on request from the user (ABORT + + + +Stewart, et al. Standards Track [Page 8] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + primitive) or as a result of an error condition detected within the + SCTP layer. Section 9 describes both the graceful and the ungraceful + close procedures. + + SCTP does not support a half-open state (like TCP) wherein one side + may continue sending data while the other end is closed. When either + endpoint performs a shutdown, the association on each peer will stop + accepting new data from its user and only deliver data in queue at + the time of the graceful close (see Section 9). + +1.3.2 Sequenced Delivery within Streams + + The term "stream" is used in SCTP to refer to a sequence of user + messages that are to be delivered to the upper-layer protocol in + order with respect to other messages within the same stream. This is + in contrast to its usage in TCP, where it refers to a sequence of + bytes (in this document a byte is assumed to be eight bits). + + The SCTP user can specify at association startup time the number of + streams to be supported by the association. This number is + negotiated with the remote end (see Section 5.1.1). User messages + are associated with stream numbers (SEND, RECEIVE primitives, Section + 10). Internally, SCTP assigns a stream sequence number to each + message passed to it by the SCTP user. On the receiving side, SCTP + ensures that messages are delivered to the SCTP user in sequence + within a given stream. However, while one stream may be blocked + waiting for the next in-sequence user message, delivery from other + streams may proceed. + + SCTP provides a mechanism for bypassing the sequenced delivery + service. User messages sent using this mechanism are delivered to + the SCTP user as soon as they are received. + +1.3.3 User Data Fragmentation + + When needed, SCTP fragments user messages to ensure that the SCTP + packet passed to the lower layer conforms to the path MTU. On + receipt, fragments are reassembled into complete messages before + being passed to the SCTP user. + +1.3.4 Acknowledgement and Congestion Avoidance + + SCTP assigns a Transmission Sequence Number (TSN) to each user data + fragment or unfragmented message. The TSN is independent of any + stream sequence number assigned at the stream level. The receiving + + + + + + +Stewart, et al. Standards Track [Page 9] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + end acknowledges all TSNs received, even if there are gaps in the + sequence. In this way, reliable delivery is kept functionally + separate from sequenced stream delivery. + + The acknowledgement and congestion avoidance function is responsible + for packet retransmission when timely acknowledgement has not been + received. Packet retransmission is conditioned by congestion + avoidance procedures similar to those used for TCP. See Sections 6 + and 7 for a detailed description of the protocol procedures + associated with this function. + +1.3.5 Chunk Bundling + + As described in Section 3, the SCTP packet as delivered to the lower + layer consists of a common header followed by one or more chunks. + Each chunk may contain either user data or SCTP control information. + The SCTP user has the option to request bundling of more than one + user messages into a single SCTP packet. The chunk bundling function + of SCTP is responsible for assembly of the complete SCTP packet and + its disassembly at the receiving end. + + During times of congestion an SCTP implementation MAY still perform + bundling even if the user has requested that SCTP not bundle. The + user's disabling of bundling only affects SCTP implementations that + may delay a small period of time before transmission (to attempt to + encourage bundling). When the user layer disables bundling, this + small delay is prohibited but not bundling that is performed during + congestion or retransmission. + +1.3.6 Packet Validation + + A mandatory Verification Tag field and a 32 bit checksum field (see + Appendix B for a description of the Adler-32 checksum) are included + in the SCTP common header. The Verification Tag value is chosen by + each end of the association during association startup. Packets + received without the expected Verification Tag value are discarded, + as a protection against blind masquerade attacks and against stale + SCTP packets from a previous association. The Adler-32 checksum + should be set by the sender of each SCTP packet to provide additional + protection against data corruption in the network. The receiver of + an SCTP packet with an invalid Adler-32 checksum silently discards + the packet. + + + + + + + + + +Stewart, et al. Standards Track [Page 10] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +1.3.7 Path Management + + The sending SCTP user is able to manipulate the set of transport + addresses used as destinations for SCTP packets through the + primitives described in Section 10. The SCTP path management + function chooses the destination transport address for each outgoing + SCTP packet based on the SCTP user's instructions and the currently + perceived reachability status of the eligible destination set. The + path management function monitors reachability through heartbeats + when other packet traffic is inadequate to provide this information + and advises the SCTP user when reachability of any far-end transport + address changes. The path management function is also responsible + for reporting the eligible set of local transport addresses to the + far end during association startup, and for reporting the transport + addresses returned from the far end to the SCTP user. + + At association start-up, a primary path is defined for each SCTP + endpoint, and is used for normal sending of SCTP packets. + + On the receiving end, the path management is responsible for + verifying the existence of a valid SCTP association to which the + inbound SCTP packet belongs before passing it for further processing. + + Note: Path Management and Packet Validation are done at the same + time, so although described separately above, in reality they cannot + be performed as separate items. + +1.4 Key Terms + + Some of the language used to describe SCTP has been introduced in the + previous sections. This section provides a consolidated list of the + key terms and their definitions. + + o Active destination transport address: A transport address on a + peer endpoint which a transmitting endpoint considers available + for receiving user messages. + + o Bundling: An optional multiplexing operation, whereby more than + one user message may be carried in the same SCTP packet. Each + user message occupies its own DATA chunk. + + o Chunk: A unit of information within an SCTP packet, consisting of + a chunk header and chunk-specific content. + + o Congestion Window (cwnd): An SCTP variable that limits the data, + in number of bytes, a sender can send to a particular destination + transport address before receiving an acknowledgement. + + + + +Stewart, et al. Standards Track [Page 11] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + o Cumulative TSN Ack Point: The TSN of the last DATA chunk + acknowledged via the Cumulative TSN Ack field of a SACK. + + o Idle destination address: An address that has not had user + messages sent to it within some length of time, normally the + HEARTBEAT interval or greater. + + o Inactive destination transport address: An address which is + considered inactive due to errors and unavailable to transport + user messages. + + o Message = user message: Data submitted to SCTP by the Upper Layer + Protocol (ULP). + + o Message Authentication Code (MAC): An integrity check mechanism + based on cryptographic hash functions using a secret key. + Typically, message authentication codes are used between two + parties that share a secret key in order to validate information + transmitted between these parties. In SCTP it is used by an + endpoint to validate the State Cookie information that is returned + from the peer in the COOKIE ECHO chunk. The term "MAC" has + different meanings in different contexts. SCTP uses this term + with the same meaning as in [RFC2104]. + + o Network Byte Order: Most significant byte first, a.k.a., Big + Endian. + + o Ordered Message: A user message that is delivered in order with + respect to all previous user messages sent within the stream the + message was sent on. + + o Outstanding TSN (at an SCTP endpoint): A TSN (and the associated + DATA chunk) that has been sent by the endpoint but for which it + has not yet received an acknowledgement. + + o Path: The route taken by the SCTP packets sent by one SCTP + endpoint to a specific destination transport address of its peer + SCTP endpoint. Sending to different destination transport + addresses does not necessarily guarantee getting separate paths. + + o Primary Path: The primary path is the destination and source + address that will be put into a packet outbound to the peer + endpoint by default. The definition includes the source address + since an implementation MAY wish to specify both destination and + source address to better control the return path taken by reply + chunks and on which interface the packet is transmitted when the + data sender is multi-homed. + + + + +Stewart, et al. Standards Track [Page 12] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + o Receiver Window (rwnd): An SCTP variable a data sender uses to + store the most recently calculated receiver window of its peer, in + number of bytes. This gives the sender an indication of the space + available in the receiver's inbound buffer. + + o SCTP association: A protocol relationship between SCTP endpoints, + composed of the two SCTP endpoints and protocol state information + including Verification Tags and the currently active set of + Transmission Sequence Numbers (TSNs), etc. An association can be + uniquely identified by the transport addresses used by the + endpoints in the association. Two SCTP endpoints MUST NOT have + more than one SCTP association between them at any given time. + + o SCTP endpoint: The logical sender/receiver of SCTP packets. On a + multi-homed host, an SCTP endpoint is represented to its peers as + a combination of a set of eligible destination transport addresses + to which SCTP packets can be sent and a set of eligible source + transport addresses from which SCTP packets can be received. All + transport addresses used by an SCTP endpoint must use the same + port number, but can use multiple IP addresses. A transport + address used by an SCTP endpoint must not be used by another SCTP + endpoint. In other words, a transport address is unique to an + SCTP endpoint. + + o SCTP packet (or packet): The unit of data delivery across the + interface between SCTP and the connectionless packet network + (e.g., IP). An SCTP packet includes the common SCTP header, + possible SCTP control chunks, and user data encapsulated within + SCTP DATA chunks. + + o SCTP user application (SCTP user): The logical higher-layer + application entity which uses the services of SCTP, also called + the Upper-layer Protocol (ULP). + + o Slow Start Threshold (ssthresh): An SCTP variable. This is the + threshold which the endpoint will use to determine whether to + perform slow start or congestion avoidance on a particular + destination transport address. Ssthresh is in number of bytes. + + o Stream: A uni-directional logical channel established from one to + another associated SCTP endpoint, within which all user messages + are delivered in sequence except for those submitted to the + unordered delivery service. + + Note: The relationship between stream numbers in opposite directions + is strictly a matter of how the applications use them. It is the + responsibility of the SCTP user to create and manage these + correlations if they are so desired. + + + +Stewart, et al. Standards Track [Page 13] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + o Stream Sequence Number: A 16-bit sequence number used internally + by SCTP to assure sequenced delivery of the user messages within a + given stream. One stream sequence number is attached to each user + message. + + o Tie-Tags: Verification Tags from a previous association. These + Tags are used within a State Cookie so that the newly restarting + association can be linked to the original association within the + endpoint that did not restart. + + o Transmission Control Block (TCB): An internal data structure + created by an SCTP endpoint for each of its existing SCTP + associations to other SCTP endpoints. TCB contains all the status + and operational information for the endpoint to maintain and + manage the corresponding association. + + o Transmission Sequence Number (TSN): A 32-bit sequence number used + internally by SCTP. One TSN is attached to each chunk containing + user data to permit the receiving SCTP endpoint to acknowledge its + receipt and detect duplicate deliveries. + + o Transport address: A Transport Address is traditionally defined + by Network Layer address, Transport Layer protocol and Transport + Layer port number. In the case of SCTP running over IP, a + transport address is defined by the combination of an IP address + and an SCTP port number (where SCTP is the Transport protocol). + + o Unacknowledged TSN (at an SCTP endpoint): A TSN (and the associated + DATA chunk) which has been received by the endpoint but for which + an acknowledgement has not yet been sent. Or in the opposite case, + for a packet that has been sent but no acknowledgement has been + received. + + o Unordered Message: Unordered messages are "unordered" with respect + to any other message, this includes both other unordered messages + as well as other ordered messages. Unordered message might be + delivered prior to or later than ordered messages sent on the same + stream. + + o User message: The unit of data delivery across the interface + between SCTP and its user. + + o Verification Tag: A 32 bit unsigned integer that is randomly + generated. The Verification Tag provides a key that allows a + receiver to verify that the SCTP packet belongs to the current + association and is not an old or stale packet from a previous + association. + + + + +Stewart, et al. Standards Track [Page 14] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +1.5. Abbreviations + + MAC - Message Authentication Code [RFC2104] + + RTO - Retransmission Time-out + + RTT - Round-trip Time + + RTTVAR - Round-trip Time Variation + + SCTP - Stream Control Transmission Protocol + + SRTT - Smoothed RTT + + TCB - Transmission Control Block + + TLV - Type-Length-Value Coding Format + + TSN - Transmission Sequence Number + + ULP - Upper-layer Protocol + +1.6 Serial Number Arithmetic + + It is essential to remember that the actual Transmission Sequence + Number space is finite, though very large. This space ranges from 0 + to 2**32 - 1. Since the space is finite, all arithmetic dealing with + Transmission Sequence Numbers must be performed modulo 2**32. This + unsigned arithmetic preserves the relationship of sequence numbers as + they cycle from 2**32 - 1 to 0 again. There are some subtleties to + computer modulo arithmetic, so great care should be taken in + programming the comparison of such values. When referring to TSNs, + the symbol "=<" means "less than or equal"(modulo 2**32). + + Comparisons and arithmetic on TSNs in this document SHOULD use Serial + Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 32. + + An endpoint SHOULD NOT transmit a DATA chunk with a TSN that is more + than 2**31 - 1 above the beginning TSN of its current send window. + Doing so will cause problems in comparing TSNs. + + Transmission Sequence Numbers wrap around when they reach 2**32 - 1. + That is, the next TSN a DATA chunk MUST use after transmitting TSN = + 2*32 - 1 is TSN = 0. + + Any arithmetic done on Stream Sequence Numbers SHOULD use Serial + Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 16. + + + + +Stewart, et al. Standards Track [Page 15] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + All other arithmetic and comparisons in this document uses normal + arithmetic. + +2. Conventions + + The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, + SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when + they appear in this document, are to be interpreted as described in + [RFC2119]. + +3. SCTP packet Format + + An SCTP packet is composed of a common header and chunks. A chunk + contains either control information or user data. + + The SCTP packet format is shown below: + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Common Header | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Chunk #1 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Chunk #n | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Multiple chunks can be bundled into one SCTP packet up to the MTU + size, except for the INIT, INIT ACK, and SHUTDOWN COMPLETE chunks. + These chunks MUST NOT be bundled with any other chunk in a packet. + See Section 6.10 for more details on chunk bundling. + + If a user data message doesn't fit into one SCTP packet it can be + fragmented into multiple chunks using the procedure defined in + Section 6.9. + + All integer fields in an SCTP packet MUST be transmitted in network + byte order, unless otherwise stated. + + + + + + + + + + + +Stewart, et al. Standards Track [Page 16] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +3.1 SCTP Common Header Field Descriptions + + SCTP Common Header Format + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Source Port Number | Destination Port Number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Verification Tag | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Source Port Number: 16 bits (unsigned integer) + + This is the SCTP sender's port number. It can be used by the + receiver in combination with the source IP address, the SCTP + destination port and possibly the destination IP address to + identify the association to which this packet belongs. + + Destination Port Number: 16 bits (unsigned integer) + + This is the SCTP port number to which this packet is destined. + The receiving host will use this port number to de-multiplex the + SCTP packet to the correct receiving endpoint/application. + + Verification Tag: 32 bits (unsigned integer) + + The receiver of this packet uses the Verification Tag to validate + the sender of this SCTP packet. On transmit, the value of this + Verification Tag MUST be set to the value of the Initiate Tag + received from the peer endpoint during the association + initialization, with the following exceptions: + + - A packet containing an INIT chunk MUST have a zero Verification + Tag. + - A packet containing a SHUTDOWN-COMPLETE chunk with the T-bit + set MUST have the Verification Tag copied from the packet with + the SHUTDOWN-ACK chunk. + - A packet containing an ABORT chunk may have the verification + tag copied from the packet which caused the ABORT to be sent. + For details see Section 8.4 and 8.5. + + An INIT chunk MUST be the only chunk in the SCTP packet carrying it. + + + + + + +Stewart, et al. Standards Track [Page 17] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Checksum: 32 bits (unsigned integer) + + This field contains the checksum of this SCTP packet. Its + calculation is discussed in Section 6.8. SCTP uses the Adler- + 32 algorithm as described in Appendix B for calculating the + checksum + +3.2 Chunk Field Descriptions + + The figure below illustrates the field format for the chunks to be + transmitted in the SCTP packet. Each chunk is formatted with a Chunk + Type field, a chunk-specific Flag field, a Chunk Length field, and a + Value field. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Chunk Type | Chunk Flags | Chunk Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ \ + / Chunk Value / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Chunk Type: 8 bits (unsigned integer) + + This field identifies the type of information contained in the + Chunk Value field. It takes a value from 0 to 254. The value of + 255 is reserved for future use as an extension field. + + The values of Chunk Types are defined as follows: + + ID Value Chunk Type + ----- ---------- + 0 - Payload Data (DATA) + 1 - Initiation (INIT) + 2 - Initiation Acknowledgement (INIT ACK) + 3 - Selective Acknowledgement (SACK) + 4 - Heartbeat Request (HEARTBEAT) + 5 - Heartbeat Acknowledgement (HEARTBEAT ACK) + 6 - Abort (ABORT) + 7 - Shutdown (SHUTDOWN) + 8 - Shutdown Acknowledgement (SHUTDOWN ACK) + 9 - Operation Error (ERROR) + 10 - State Cookie (COOKIE ECHO) + 11 - Cookie Acknowledgement (COOKIE ACK) + 12 - Reserved for Explicit Congestion Notification Echo (ECNE) + 13 - Reserved for Congestion Window Reduced (CWR) + + + +Stewart, et al. Standards Track [Page 18] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + 14 - Shutdown Complete (SHUTDOWN COMPLETE) + 15 to 62 - reserved by IETF + 63 - IETF-defined Chunk Extensions + 64 to 126 - reserved by IETF + 127 - IETF-defined Chunk Extensions + 128 to 190 - reserved by IETF + 191 - IETF-defined Chunk Extensions + 192 to 254 - reserved by IETF + 255 - IETF-defined Chunk Extensions + + Chunk Types are encoded such that the highest-order two bits specify + the action that must be taken if the processing endpoint does not + recognize the Chunk Type. + + 00 - Stop processing this SCTP packet and discard it, do not process + any further chunks within it. + + 01 - Stop processing this SCTP packet and discard it, do not process + any further chunks within it, and report the unrecognized + parameter in an 'Unrecognized Parameter Type' (in either an + ERROR or in the INIT ACK). + + 10 - Skip this chunk and continue processing. + + 11 - Skip this chunk and continue processing, but report in an ERROR + Chunk using the 'Unrecognized Chunk Type' cause of error. + + Note: The ECNE and CWR chunk types are reserved for future use of + Explicit Congestion Notification (ECN). + + Chunk Flags: 8 bits + + The usage of these bits depends on the chunk type as given by the + Chunk Type. Unless otherwise specified, they are set to zero on + transmit and are ignored on receipt. + + Chunk Length: 16 bits (unsigned integer) + + This value represents the size of the chunk in bytes including the + Chunk Type, Chunk Flags, Chunk Length, and Chunk Value fields. + Therefore, if the Chunk Value field is zero-length, the Length + field will be set to 4. The Chunk Length field does not count any + padding. + + + + + + + + +Stewart, et al. Standards Track [Page 19] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Chunk Value: variable length + + The Chunk Value field contains the actual information to be + transferred in the chunk. The usage and format of this field is + dependent on the Chunk Type. + + The total length of a chunk (including Type, Length and Value fields) + MUST be a multiple of 4 bytes. If the length of the chunk is not a + multiple of 4 bytes, the sender MUST pad the chunk with all zero + bytes and this padding is not included in the chunk length field. + The sender should never pad with more than 3 bytes. The receiver + MUST ignore the padding bytes. + + SCTP defined chunks are described in detail in Section 3.3. The + guidelines for IETF-defined chunk extensions can be found in Section + 13.1 of this document. + +3.2.1 Optional/Variable-length Parameter Format + + Chunk values of SCTP control chunks consist of a chunk-type-specific + header of required fields, followed by zero or more parameters. The + optional and variable-length parameters contained in a chunk are + defined in a Type-Length-Value format as shown below. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Parameter Type | Parameter Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ \ + / Parameter Value / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Chunk Parameter Type: 16 bits (unsigned integer) + + The Type field is a 16 bit identifier of the type of parameter. + It takes a value of 0 to 65534. + + The value of 65535 is reserved for IETF-defined extensions. Values + other than those defined in specific SCTP chunk description are + reserved for use by IETF. + + + + + + + + + +Stewart, et al. Standards Track [Page 20] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Chunk Parameter Length: 16 bits (unsigned integer) + + The Parameter Length field contains the size of the parameter in + bytes, including the Parameter Type, Parameter Length, and + Parameter Value fields. Thus, a parameter with a zero-length + Parameter Value field would have a Length field of 4. The + Parameter Length does not include any padding bytes. + + Chunk Parameter Value: variable-length. + + The Parameter Value field contains the actual information to be + transferred in the parameter. + + The total length of a parameter (including Type, Parameter Length and + Value fields) MUST be a multiple of 4 bytes. If the length of the + parameter is not a multiple of 4 bytes, the sender pads the Parameter + at the end (i.e., after the Parameter Value field) with all zero + bytes. The length of the padding is not included in the parameter + length field. A sender SHOULD NOT pad with more than 3 bytes. The + receiver MUST ignore the padding bytes. + + The Parameter Types are encoded such that the highest-order two bits + specify the action that must be taken if the processing endpoint does + not recognize the Parameter Type. + + 00 - Stop processing this SCTP packet and discard it, do not process + any further chunks within it. + + 01 - Stop processing this SCTP packet and discard it, do not process + any further chunks within it, and report the unrecognized + parameter in an 'Unrecognized Parameter Type' (in either an + ERROR or in the INIT ACK). + + 10 - Skip this parameter and continue processing. + + 11 - Skip this parameter and continue processing but report the + unrecognized parameter in an 'Unrecognized Parameter Type' (in + either an ERROR or in the INIT ACK). + + The actual SCTP parameters are defined in the specific SCTP chunk + sections. The rules for IETF-defined parameter extensions are + defined in Section 13.2. + +3.3 SCTP Chunk Definitions + + This section defines the format of the different SCTP chunk types. + + + + + +Stewart, et al. Standards Track [Page 21] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +3.3.1 Payload Data (DATA) (0) + + The following format MUST be used for the DATA chunk: + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 0 | Reserved|U|B|E| Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | TSN | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Stream Identifier S | Stream Sequence Number n | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Payload Protocol Identifier | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ \ + / User Data (seq n of Stream S) / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Reserved: 5 bits + + Should be set to all '0's and ignored by the receiver. + + U bit: 1 bit + + The (U)nordered bit, if set to '1', indicates that this is an + unordered DATA chunk, and there is no Stream Sequence Number + assigned to this DATA chunk. Therefore, the receiver MUST ignore + the Stream Sequence Number field. + + After re-assembly (if necessary), unordered DATA chunks MUST be + dispatched to the upper layer by the receiver without any attempt + to re-order. + + If an unordered user message is fragmented, each fragment of the + message MUST have its U bit set to '1'. + + B bit: 1 bit + + The (B)eginning fragment bit, if set, indicates the first fragment + of a user message. + + E bit: 1 bit + + The (E)nding fragment bit, if set, indicates the last fragment of + a user message. + + + + +Stewart, et al. Standards Track [Page 22] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + An unfragmented user message shall have both the B and E bits set to + '1'. Setting both B and E bits to '0' indicates a middle fragment of + a multi-fragment user message, as summarized in the following table: + + B E Description + ============================================================ + | 1 0 | First piece of a fragmented user message | + +----------------------------------------------------------+ + | 0 0 | Middle piece of a fragmented user message | + +----------------------------------------------------------+ + | 0 1 | Last piece of a fragmented user message | + +----------------------------------------------------------+ + | 1 1 | Unfragmented Message | + ============================================================ + | Table 1: Fragment Description Flags | + ============================================================ + + When a user message is fragmented into multiple chunks, the TSNs are + used by the receiver to reassemble the message. This means that the + TSNs for each fragment of a fragmented user message MUST be strictly + sequential. + + Length: 16 bits (unsigned integer) + + This field indicates the length of the DATA chunk in bytes from + the beginning of the type field to the end of the user data field + excluding any padding. A DATA chunk with no user data field will + have Length set to 16 (indicating 16 bytes). + + TSN : 32 bits (unsigned integer) + + This value represents the TSN for this DATA chunk. The valid + range of TSN is from 0 to 4294967295 (2**32 - 1). TSN wraps back + to 0 after reaching 4294967295. + + Stream Identifier S: 16 bits (unsigned integer) + + Identifies the stream to which the following user data belongs. + + Stream Sequence Number n: 16 bits (unsigned integer) + + This value represents the stream sequence number of the following + user data within the stream S. Valid range is 0 to 65535. + + When a user message is fragmented by SCTP for transport, the same + stream sequence number MUST be carried in each of the fragments of + the message. + + + + +Stewart, et al. Standards Track [Page 23] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Payload Protocol Identifier: 32 bits (unsigned integer) + + This value represents an application (or upper layer) specified + protocol identifier. This value is passed to SCTP by its upper + layer and sent to its peer. This identifier is not used by SCTP + but can be used by certain network entities as well as the peer + application to identify the type of information being carried in + this DATA chunk. This field must be sent even in fragmented DATA + chunks (to make sure it is available for agents in the middle of + the network). + + The value 0 indicates no application identifier is specified by + the upper layer for this payload data. + + User Data: variable length + + This is the payload user data. The implementation MUST pad the + end of the data to a 4 byte boundary with all-zero bytes. Any + padding MUST NOT be included in the length field. A sender MUST + never add more than 3 bytes of padding. + +3.3.2 Initiation (INIT) (1) + + This chunk is used to initiate a SCTP association between two + endpoints. The format of the INIT chunk is shown below: + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 1 | Chunk Flags | Chunk Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Initiate Tag | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Advertised Receiver Window Credit (a_rwnd) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Number of Outbound Streams | Number of Inbound Streams | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Initial TSN | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ \ + / Optional/Variable-Length Parameters / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + The INIT chunk contains the following parameters. Unless otherwise + noted, each parameter MUST only be included once in the INIT chunk. + + + + + +Stewart, et al. Standards Track [Page 24] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Fixed Parameters Status + ---------------------------------------------- + Initiate Tag Mandatory + Advertised Receiver Window Credit Mandatory + Number of Outbound Streams Mandatory + Number of Inbound Streams Mandatory + Initial TSN Mandatory + + Variable Parameters Status Type Value + ------------------------------------------------------------- + IPv4 Address (Note 1) Optional 5 + IPv6 Address (Note 1) Optional 6 + Cookie Preservative Optional 9 + Reserved for ECN Capable (Note 2) Optional 32768 (0x8000) + Host Name Address (Note 3) Optional 11 + Supported Address Types (Note 4) Optional 12 + + Note 1: The INIT chunks can contain multiple addresses that can be + IPv4 and/or IPv6 in any combination. + + Note 2: The ECN capable field is reserved for future use of Explicit + Congestion Notification. + + Note 3: An INIT chunk MUST NOT contain more than one Host Name + address parameter. Moreover, the sender of the INIT MUST NOT combine + any other address types with the Host Name address in the INIT. The + receiver of INIT MUST ignore any other address types if the Host Name + address parameter is present in the received INIT chunk. + + Note 4: This parameter, when present, specifies all the address types + the sending endpoint can support. The absence of this parameter + indicates that the sending endpoint can support any address type. + + The Chunk Flags field in INIT is reserved and all bits in it should + be set to 0 by the sender and ignored by the receiver. The sequence + of parameters within an INIT can be processed in any order. + + Initiate Tag: 32 bits (unsigned integer) + + The receiver of the INIT (the responding end) records the value of + the Initiate Tag parameter. This value MUST be placed into the + Verification Tag field of every SCTP packet that the receiver of + the INIT transmits within this association. + + The Initiate Tag is allowed to have any value except 0. See + Section 5.3.1 for more on the selection of the tag value. + + + + + +Stewart, et al. Standards Track [Page 25] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + If the value of the Initiate Tag in a received INIT chunk is found + to be 0, the receiver MUST treat it as an error and close the + association by transmitting an ABORT. + + Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned + integer) + + This value represents the dedicated buffer space, in number of + bytes, the sender of the INIT has reserved in association with + this window. During the life of the association this buffer space + SHOULD not be lessened (i.e. dedicated buffers taken away from + this association); however, an endpoint MAY change the value of + a_rwnd it sends in SACK chunks. + + Number of Outbound Streams (OS): 16 bits (unsigned integer) + + Defines the number of outbound streams the sender of this INIT + chunk wishes to create in this association. The value of 0 MUST + NOT be used. + + Note: A receiver of an INIT with the OS value set to 0 SHOULD + abort the association. + + Number of Inbound Streams (MIS) : 16 bits (unsigned integer) + + Defines the maximum number of streams the sender of this INIT + chunk allows the peer end to create in this association. The + value 0 MUST NOT be used. + + Note: There is no negotiation of the actual number of streams but + instead the two endpoints will use the min(requested, offered). + See Section 5.1.1 for details. + + Note: A receiver of an INIT with the MIS value of 0 SHOULD abort + the association. + + Initial TSN (I-TSN) : 32 bits (unsigned integer) + + Defines the initial TSN that the sender will use. The valid range + is from 0 to 4294967295. This field MAY be set to the value of + the Initiate Tag field. + +3.3.2.1 Optional/Variable Length Parameters in INIT + + The following parameters follow the Type-Length-Value format as + defined in Section 3.2.1. Any Type-Length-Value fields MUST come + after the fixed-length fields defined in the previous section. + + + + +Stewart, et al. Standards Track [Page 26] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + IPv4 Address Parameter (5) + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 5 | Length = 8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IPv4 Address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + IPv4 Address: 32 bits (unsigned integer) + + Contains an IPv4 address of the sending endpoint. It is binary + encoded. + + IPv6 Address Parameter (6) + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 6 | Length = 20 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + | IPv6 Address | + | | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + IPv6 Address: 128 bit (unsigned integer) + + Contains an IPv6 address of the sending endpoint. It is binary + encoded. + + Note: A sender MUST NOT use an IPv4-mapped IPv6 address [RFC2373] + but should instead use an IPv4 Address Parameter for an IPv4 + address. + + Combined with the Source Port Number in the SCTP common header, + the value passed in an IPv4 or IPv6 Address parameter indicates a + transport address the sender of the INIT will support for the + association being initiated. That is, during the lifetime of this + association, this IP address can appear in the source address + field of an IP datagram sent from the sender of the INIT, and can + be used as a destination address of an IP datagram sent from the + receiver of the INIT. + + + + + +Stewart, et al. Standards Track [Page 27] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + More than one IP Address parameter can be included in an INIT + chunk when the INIT sender is multi-homed. Moreover, a multi- + homed endpoint may have access to different types of network, thus + more than one address type can be present in one INIT chunk, i.e., + IPv4 and IPv6 addresses are allowed in the same INIT chunk. + + If the INIT contains at least one IP Address parameter, then the + source address of the IP datagram containing the INIT chunk and + any additional address(es) provided within the INIT can be used as + destinations by the endpoint receiving the INIT. If the INIT does + not contain any IP Address parameters, the endpoint receiving the + INIT MUST use the source address associated with the received IP + datagram as its sole destination address for the association. + + Note that not using any IP address parameters in the INIT and + INIT-ACK is an alternative to make an association more likely to + work across a NAT box. + + Cookie Preservative (9) + + The sender of the INIT shall use this parameter to suggest to the + receiver of the INIT for a longer life-span of the State Cookie. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 9 | Length = 8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Suggested Cookie Life-span Increment (msec.) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Suggested Cookie Life-span Increment: 32 bits (unsigned integer) + + This parameter indicates to the receiver how much increment in + milliseconds the sender wishes the receiver to add to its default + cookie life-span. + + This optional parameter should be added to the INIT chunk by the + sender when it re-attempts establishing an association with a peer + to which its previous attempt of establishing the association failed + due to a stale cookie operation error. The receiver MAY choose to + ignore the suggested cookie life-span increase for its own security + reasons. + + + + + + + + +Stewart, et al. Standards Track [Page 28] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Host Name Address (11) + + The sender of INIT uses this parameter to pass its Host Name (in + place of its IP addresses) to its peer. The peer is responsible + for resolving the name. Using this parameter might make it more + likely for the association to work across a NAT box. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 11 | Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / Host Name / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Host Name: variable length + + This field contains a host name in "host name syntax" per RFC1123 + Section 2.1 [RFC1123]. The method for resolving the host name is + out of scope of SCTP. + + Note: At least one null terminator is included in the Host Name + string and must be included in the length. + + Supported Address Types (12) + + The sender of INIT uses this parameter to list all the address + types it can support. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 12 | Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Address Type #1 | Address Type #2 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ...... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Address Type: 16 bits (unsigned integer) + + This is filled with the type value of the corresponding address + TLV (e.g., IPv4 = 5, IPv6 = 6, Hostname = 11). + + + + + + + +Stewart, et al. Standards Track [Page 29] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +3.3.3 Initiation Acknowledgement (INIT ACK) (2): + + The INIT ACK chunk is used to acknowledge the initiation of an SCTP + association. + + The parameter part of INIT ACK is formatted similarly to the INIT + chunk. It uses two extra variable parameters: The State Cookie and + the Unrecognized Parameter: + + The format of the INIT ACK chunk is shown below: + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 2 | Chunk Flags | Chunk Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Initiate Tag | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Advertised Receiver Window Credit | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Number of Outbound Streams | Number of Inbound Streams | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Initial TSN | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ \ + / Optional/Variable-Length Parameters / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Initiate Tag: 32 bits (unsigned integer) + + The receiver of the INIT ACK records the value of the Initiate Tag + parameter. This value MUST be placed into the Verification Tag + field of every SCTP packet that the INIT ACK receiver transmits + within this association. + + The Initiate Tag MUST NOT take the value 0. See Section 5.3.1 for + more on the selection of the Initiate Tag value. + + If the value of the Initiate Tag in a received INIT ACK chunk is + found to be 0, the receiver MUST treat it as an error and close + the association by transmitting an ABORT. + + + + + + + + + +Stewart, et al. Standards Track [Page 30] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned + integer) + + This value represents the dedicated buffer space, in number of + bytes, the sender of the INIT ACK has reserved in association with + this window. During the life of the association this buffer space + SHOULD not be lessened (i.e. dedicated buffers taken away from + this association). + + Number of Outbound Streams (OS): 16 bits (unsigned integer) + + Defines the number of outbound streams the sender of this INIT ACK + chunk wishes to create in this association. The value of 0 MUST + NOT be used. + + Note: A receiver of an INIT ACK with the OS value set to 0 SHOULD + destroy the association discarding its TCB. + + Number of Inbound Streams (MIS) : 16 bits (unsigned integer) + + Defines the maximum number of streams the sender of this INIT ACK + chunk allows the peer end to create in this association. The + value 0 MUST NOT be used. + + Note: There is no negotiation of the actual number of streams but + instead the two endpoints will use the min(requested, offered). + See Section 5.1.1 for details. + + Note: A receiver of an INIT ACK with the MIS value set to 0 + SHOULD destroy the association discarding its TCB. + + Initial TSN (I-TSN) : 32 bits (unsigned integer) + + Defines the initial TSN that the INIT-ACK sender will use. The + valid range is from 0 to 4294967295. This field MAY be set to the + value of the Initiate Tag field. + + Fixed Parameters Status + ---------------------------------------------- + Initiate Tag Mandatory + Advertised Receiver Window Credit Mandatory + Number of Outbound Streams Mandatory + Number of Inbound Streams Mandatory + Initial TSN Mandatory + + + + + + + +Stewart, et al. Standards Track [Page 31] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Variable Parameters Status Type Value + ------------------------------------------------------------- + State Cookie Mandatory 7 + IPv4 Address (Note 1) Optional 5 + IPv6 Address (Note 1) Optional 6 + Unrecognized Parameters Optional 8 + Reserved for ECN Capable (Note 2) Optional 32768 (0x8000) + Host Name Address (Note 3) Optional 11 + + Note 1: The INIT ACK chunks can contain any number of IP address + parameters that can be IPv4 and/or IPv6 in any combination. + + Note 2: The ECN capable field is reserved for future use of Explicit + Congestion Notification. + + Note 3: The INIT ACK chunks MUST NOT contain more than one Host Name + address parameter. Moreover, the sender of the INIT ACK MUST NOT + combine any other address types with the Host Name address in the + INIT ACK. The receiver of the INIT ACK MUST ignore any other address + types if the Host Name address parameter is present. + + IMPLEMENTATION NOTE: An implementation MUST be prepared to receive a + INIT ACK that is quite large (more than 1500 bytes) due to the + variable size of the state cookie AND the variable address list. For + example if a responder to the INIT has 1000 IPv4 addresses it wishes + to send, it would need at least 8,000 bytes to encode this in the + INIT ACK. + + In combination with the Source Port carried in the SCTP common + header, each IP Address parameter in the INIT ACK indicates to the + receiver of the INIT ACK a valid transport address supported by the + sender of the INIT ACK for the lifetime of the association being + initiated. + + If the INIT ACK contains at least one IP Address parameter, then the + source address of the IP datagram containing the INIT ACK and any + additional address(es) provided within the INIT ACK may be used as + destinations by the receiver of the INIT-ACK. If the INIT ACK does + not contain any IP Address parameters, the receiver of the INIT-ACK + MUST use the source address associated with the received IP datagram + as its sole destination address for the association. + + The State Cookie and Unrecognized Parameters use the Type-Length- + Value format as defined in Section 3.2.1 and are described below. + The other fields are defined the same as their counterparts in the + INIT chunk. + + + + + +Stewart, et al. Standards Track [Page 32] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +3.3.3.1 Optional or Variable Length Parameters + + State Cookie + + Parameter Type Value: 7 + + Parameter Length: variable size, depending on Size of Cookie + + Parameter Value: + + This parameter value MUST contain all the necessary state and + parameter information required for the sender of this INIT ACK + to create the association, along with a Message Authentication + Code (MAC). See Section 5.1.3 for details on State Cookie + definition. + + Unrecognized Parameters: + + Parameter Type Value: 8 + + Parameter Length: Variable Size. + + Parameter Value: + + This parameter is returned to the originator of the INIT chunk + when the INIT contains an unrecognized parameter which has a + value that indicates that it should be reported to the sender. + This parameter value field will contain unrecognized parameters + copied from the INIT chunk complete with Parameter Type, Length + and Value fields. + +3.3.4 Selective Acknowledgement (SACK) (3): + + This chunk is sent to the peer endpoint to acknowledge received DATA + chunks and to inform the peer endpoint of gaps in the received + subsequences of DATA chunks as represented by their TSNs. + + The SACK MUST contain the Cumulative TSN Ack and Advertised Receiver + Window Credit (a_rwnd) parameters. + + By definition, the value of the Cumulative TSN Ack parameter is the + last TSN received before a break in the sequence of received TSNs + occurs; the next TSN value following this one has not yet been + received at the endpoint sending the SACK. This parameter therefore + acknowledges receipt of all TSNs less than or equal to its value. + + The handling of a_rwnd by the receiver of the SACK is discussed in + detail in Section 6.2.1. + + + +Stewart, et al. Standards Track [Page 33] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + The SACK also contains zero or more Gap Ack Blocks. Each Gap Ack + Block acknowledges a subsequence of TSNs received following a break + in the sequence of received TSNs. By definition, all TSNs + acknowledged by Gap Ack Blocks are greater than the value of the + Cumulative TSN Ack. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 3 |Chunk Flags | Chunk Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cumulative TSN Ack | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Advertised Receiver Window Credit (a_rwnd) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Number of Gap Ack Blocks = N | Number of Duplicate TSNs = X | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Gap Ack Block #1 Start | Gap Ack Block #1 End | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + \ ... \ + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Gap Ack Block #N Start | Gap Ack Block #N End | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Duplicate TSN 1 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + \ ... \ + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Duplicate TSN X | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Chunk Flags: 8 bits + + Set to all zeros on transmit and ignored on receipt. + + Cumulative TSN Ack: 32 bits (unsigned integer) + + This parameter contains the TSN of the last DATA chunk received in + sequence before a gap. + + Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned + integer) + + This field indicates the updated receive buffer space in bytes of + the sender of this SACK, see Section 6.2.1 for details. + + + +Stewart, et al. Standards Track [Page 34] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Number of Gap Ack Blocks: 16 bits (unsigned integer) + + Indicates the number of Gap Ack Blocks included in this SACK. + + Number of Duplicate TSNs: 16 bit + + This field contains the number of duplicate TSNs the endpoint has + received. Each duplicate TSN is listed following the Gap Ack + Block list. + + Gap Ack Blocks: + + These fields contain the Gap Ack Blocks. They are repeated for + each Gap Ack Block up to the number of Gap Ack Blocks defined in + the Number of Gap Ack Blocks field. All DATA chunks with TSNs + greater than or equal to (Cumulative TSN Ack + Gap Ack Block + Start) and less than or equal to (Cumulative TSN Ack + Gap Ack + Block End) of each Gap Ack Block are assumed to have been received + correctly. + + Gap Ack Block Start: 16 bits (unsigned integer) + + Indicates the Start offset TSN for this Gap Ack Block. To + calculate the actual TSN number the Cumulative TSN Ack is added to + this offset number. This calculated TSN identifies the first TSN + in this Gap Ack Block that has been received. + + Gap Ack Block End: 16 bits (unsigned integer) + + Indicates the End offset TSN for this Gap Ack Block. To calculate + the actual TSN number the Cumulative TSN Ack is added to this + offset number. This calculated TSN identifies the TSN of the last + DATA chunk received in this Gap Ack Block. + + For example, assume the receiver has the following DATA chunks newly + arrived at the time when it decides to send a Selective ACK, + + + + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 35] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + ---------- + | TSN=17 | + ---------- + | | <- still missing + ---------- + | TSN=15 | + ---------- + | TSN=14 | + ---------- + | | <- still missing + ---------- + | TSN=12 | + ---------- + | TSN=11 | + ---------- + | TSN=10 | + ---------- + + then, the parameter part of the SACK MUST be constructed as follows + (assuming the new a_rwnd is set to 4660 by the sender): + + +--------------------------------+ + | Cumulative TSN Ack = 12 | + +--------------------------------+ + | a_rwnd = 4660 | + +----------------+---------------+ + | num of block=2 | num of dup=0 | + +----------------+---------------+ + |block #1 strt=2 |block #1 end=3 | + +----------------+---------------+ + |block #2 strt=5 |block #2 end=5 | + +----------------+---------------+ + + + Duplicate TSN: 32 bits (unsigned integer) + + Indicates the number of times a TSN was received in duplicate + since the last SACK was sent. Every time a receiver gets a + duplicate TSN (before sending the SACK) it adds it to the list of + duplicates. The duplicate count is re-initialized to zero after + sending each SACK. + + For example, if a receiver were to get the TSN 19 three times it + would list 19 twice in the outbound SACK. After sending the SACK + if it received yet one more TSN 19 it would list 19 as a duplicate + once in the next outgoing SACK. + + + + + +Stewart, et al. Standards Track [Page 36] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +3.3.5 Heartbeat Request (HEARTBEAT) (4): + + An endpoint should send this chunk to its peer endpoint to probe the + reachability of a particular destination transport address defined in + the present association. + + The parameter field contains the Heartbeat Information which is a + variable length opaque data structure understood only by the sender. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 4 | Chunk Flags | Heartbeat Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ \ + / Heartbeat Information TLV (Variable-Length) / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Chunk Flags: 8 bits + + Set to zero on transmit and ignored on receipt. + + Heartbeat Length: 16 bits (unsigned integer) + + Set to the size of the chunk in bytes, including the chunk header + and the Heartbeat Information field. + + Heartbeat Information: variable length + + Defined as a variable-length parameter using the format described + in Section 3.2.1, i.e.: + + Variable Parameters Status Type Value + ------------------------------------------------------------- + Heartbeat Info Mandatory 1 + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Heartbeat Info Type=1 | HB Info Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / Sender-specific Heartbeat Info / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + + + + +Stewart, et al. Standards Track [Page 37] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + The Sender-specific Heartbeat Info field should normally include + information about the sender's current time when this HEARTBEAT + chunk is sent and the destination transport address to which this + HEARTBEAT is sent (see Section 8.3). + +3.3.6 Heartbeat Acknowledgement (HEARTBEAT ACK) (5): + + An endpoint should send this chunk to its peer endpoint as a response + to a HEARTBEAT chunk (see Section 8.3). A HEARTBEAT ACK is always + sent to the source IP address of the IP datagram containing the + HEARTBEAT chunk to which this ack is responding. + + The parameter field contains a variable length opaque data structure. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 5 | Chunk Flags | Heartbeat Ack Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ \ + / Heartbeat Information TLV (Variable-Length) / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Chunk Flags: 8 bits + + Set to zero on transmit and ignored on receipt. + + Heartbeat Ack Length: 16 bits (unsigned integer) + + Set to the size of the chunk in bytes, including the chunk header + and the Heartbeat Information field. + + Heartbeat Information: variable length + + This field MUST contain the Heartbeat Information parameter of + the Heartbeat Request to which this Heartbeat Acknowledgement is + responding. + + Variable Parameters Status Type Value + ------------------------------------------------------------- + Heartbeat Info Mandatory 1 + + + + + + + + + +Stewart, et al. Standards Track [Page 38] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +3.3.7 Abort Association (ABORT) (6): + + The ABORT chunk is sent to the peer of an association to close the + association. The ABORT chunk may contain Cause Parameters to inform + the receiver the reason of the abort. DATA chunks MUST NOT be + bundled with ABORT. Control chunks (except for INIT, INIT ACK and + SHUTDOWN COMPLETE) MAY be bundled with an ABORT but they MUST be + placed before the ABORT in the SCTP packet, or they will be ignored + by the receiver. + + If an endpoint receives an ABORT with a format error or for an + association that doesn't exist, it MUST silently discard it. + Moreover, under any circumstances, an endpoint that receives an ABORT + MUST NOT respond to that ABORT by sending an ABORT of its own. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 6 |Reserved |T| Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ \ + / zero or more Error Causes / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Chunk Flags: 8 bits + + Reserved: 7 bits + + Set to 0 on transmit and ignored on receipt. + + T bit: 1 bit + + The T bit is set to 0 if the sender had a TCB that it destroyed. + If the sender did not have a TCB it should set this bit to 1. + + Note: Special rules apply to this chunk for verification, please see + Section 8.5.1 for details. + + Length: 16 bits (unsigned integer) + + Set to the size of the chunk in bytes, including the chunk header + and all the Error Cause fields present. + + See Section 3.3.10 for Error Cause definitions. + + + + + + +Stewart, et al. Standards Track [Page 39] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +3.3.8 Shutdown Association (SHUTDOWN) (7): + + An endpoint in an association MUST use this chunk to initiate a + graceful close of the association with its peer. This chunk has the + following format. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 7 | Chunk Flags | Length = 8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cumulative TSN Ack | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Chunk Flags: 8 bits + + Set to zero on transmit and ignored on receipt. + + Length: 16 bits (unsigned integer) + + Indicates the length of the parameter. Set to 8. + + Cumulative TSN Ack: 32 bits (unsigned integer) + + This parameter contains the TSN of the last chunk received in + sequence before any gaps. + + Note: Since the SHUTDOWN message does not contain Gap Ack Blocks, + it cannot be used to acknowledge TSNs received out of order. In a + SACK, lack of Gap Ack Blocks that were previously included + indicates that the data receiver reneged on the associated DATA + chunks. Since SHUTDOWN does not contain Gap Ack Blocks, the + receiver of the SHUTDOWN shouldn't interpret the lack of a Gap Ack + Block as a renege. (see Section 6.2 for information on reneging) + +3.3.9 Shutdown Acknowledgement (SHUTDOWN ACK) (8): + + This chunk MUST be used to acknowledge the receipt of the SHUTDOWN + chunk at the completion of the shutdown process, see Section 9.2 for + details. + + The SHUTDOWN ACK chunk has no parameters. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 8 |Chunk Flags | Length = 4 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + +Stewart, et al. Standards Track [Page 40] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Chunk Flags: 8 bits + + Set to zero on transmit and ignored on receipt. + +3.3.10 Operation Error (ERROR) (9): + + An endpoint sends this chunk to its peer endpoint to notify it of + certain error conditions. It contains one or more error causes. An + Operation Error is not considered fatal in and of itself, but may be + used with an ABORT chunk to report a fatal condition. It has the + following parameters: + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 9 | Chunk Flags | Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ \ + / one or more Error Causes / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Chunk Flags: 8 bits + + Set to zero on transmit and ignored on receipt. + + Length: 16 bits (unsigned integer) + + Set to the size of the chunk in bytes, including the chunk header + and all the Error Cause fields present. + + Error causes are defined as variable-length parameters using the + format described in 3.2.1, i.e.: + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code | Cause Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / Cause-specific Information / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Cause Code: 16 bits (unsigned integer) + + Defines the type of error conditions being reported. + + + + + +Stewart, et al. Standards Track [Page 41] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Cause Code + Value Cause Code + --------- ---------------- + 1 Invalid Stream Identifier + 2 Missing Mandatory Parameter + 3 Stale Cookie Error + 4 Out of Resource + 5 Unresolvable Address + 6 Unrecognized Chunk Type + 7 Invalid Mandatory Parameter + 8 Unrecognized Parameters + 9 No User Data + 10 Cookie Received While Shutting Down + + Cause Length: 16 bits (unsigned integer) + + Set to the size of the parameter in bytes, including the Cause + Code, Cause Length, and Cause-Specific Information fields + + Cause-specific Information: variable length + + This field carries the details of the error condition. + + Sections 3.3.10.1 - 3.3.10.10 define error causes for SCTP. + Guidelines for the IETF to define new error cause values are + discussed in Section 13.3. + +3.3.10.1 Invalid Stream Identifier (1) + + Cause of error + --------------- + Invalid Stream Identifier: Indicates endpoint received a DATA chunk + sent to a nonexistent stream. + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=1 | Cause Length=8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Stream Identifier | (Reserved) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Stream Identifier: 16 bits (unsigned integer) + + Contains the Stream Identifier of the DATA chunk received in + error. + + + + + + + +Stewart, et al. Standards Track [Page 42] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Reserved: 16 bits + + This field is reserved. It is set to all 0's on transmit and + Ignored on receipt. + +3.3.10.2 Missing Mandatory Parameter (2) + + Cause of error + --------------- + Missing Mandatory Parameter: Indicates that one or more mandatory + TLV parameters are missing in a received INIT or INIT ACK. + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=2 | Cause Length=8+N*2 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Number of missing params=N | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Missing Param Type #1 | Missing Param Type #2 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Missing Param Type #N-1 | Missing Param Type #N | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Number of Missing params: 32 bits (unsigned integer) + + This field contains the number of parameters contained in the + Cause-specific Information field. + + Missing Param Type: 16 bits (unsigned integer) + + Each field will contain the missing mandatory parameter number. + +3.3.10.3 Stale Cookie Error (3) + + Cause of error + -------------- + Stale Cookie Error: Indicates the receipt of a valid State Cookie + that has expired. + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=3 | Cause Length=8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Measure of Staleness (usec.) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Measure of Staleness: 32 bits (unsigned integer) + + This field contains the difference, in microseconds, between the + current time and the time the State Cookie expired. + + + +Stewart, et al. Standards Track [Page 43] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + The sender of this error cause MAY choose to report how long past + expiration the State Cookie is by including a non-zero value in + the Measure of Staleness field. If the sender does not wish to + provide this information it should set the Measure of Staleness + field to the value of zero. + +3.3.10.4 Out of Resource (4) + + Cause of error + --------------- + Out of Resource: Indicates that the sender is out of resource. This + is usually sent in combination with or within an ABORT. + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=4 | Cause Length=4 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +3.3.10.5 Unresolvable Address (5) + + Cause of error + --------------- + Unresolvable Address: Indicates that the sender is not able to + resolve the specified address parameter (e.g., type of address is not + supported by the sender). This is usually sent in combination with + or within an ABORT. + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=5 | Cause Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / Unresolvable Address / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Unresolvable Address: variable length + + The unresolvable address field contains the complete Type, Length + and Value of the address parameter (or Host Name parameter) that + contains the unresolvable address or host name. + +3.3.10.6 Unrecognized Chunk Type (6) + + Cause of error + --------------- + Unrecognized Chunk Type: This error cause is returned to the + originator of the chunk if the receiver does not understand the chunk + and the upper bits of the 'Chunk Type' are set to 01 or 11. + + + + + +Stewart, et al. Standards Track [Page 44] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=6 | Cause Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / Unrecognized Chunk / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Unrecognized Chunk: variable length + + The Unrecognized Chunk field contains the unrecognized Chunk from + the SCTP packet complete with Chunk Type, Chunk Flags and Chunk + Length. + +3.3.10.7 Invalid Mandatory Parameter (7) + + Cause of error + --------------- + Invalid Mandatory Parameter: This error cause is returned to the + originator of an INIT or INIT ACK chunk when one of the mandatory + parameters is set to a invalid value. + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=7 | Cause Length=4 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +3.3.10.8 Unrecognized Parameters (8) + + Cause of error + --------------- + Unrecognized Parameters: This error cause is returned to the + originator of the INIT ACK chunk if the receiver does not recognize + one or more Optional TLV parameters in the INIT ACK chunk. + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=8 | Cause Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / Unrecognized Parameters / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Unrecognized Parameters: variable length + + The Unrecognized Parameters field contains the unrecognized + parameters copied from the INIT ACK chunk complete with TLV. This + error cause is normally contained in an ERROR chunk bundled with + the COOKIE ECHO chunk when responding to the INIT ACK, when the + sender of the COOKIE ECHO chunk wishes to report unrecognized + parameters. + + + +Stewart, et al. Standards Track [Page 45] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +3.3.10.9 No User Data (9) + + Cause of error + --------------- + No User Data: This error cause is returned to the originator of a + DATA chunk if a received DATA chunk has no user data. + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=9 | Cause Length=8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / TSN value / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + TSN value: 32 bits (+unsigned integer) + + The TSN value field contains the TSN of the DATA chunk received + with no user data field. + + This cause code is normally returned in an ABORT chunk (see + Section 6.2) + +3.3.10.10 Cookie Received While Shutting Down (10) + + Cause of error + --------------- + Cookie Received While Shutting Down: A COOKIE ECHO was received + While the endpoint was in SHUTDOWN-ACK-SENT state. This error is + usually returned in an ERROR chunk bundled with the retransmitted + SHUTDOWN ACK. + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=10 | Cause Length=4 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +3.3.11 Cookie Echo (COOKIE ECHO) (10): + + This chunk is used only during the initialization of an association. + It is sent by the initiator of an association to its peer to complete + the initialization process. This chunk MUST precede any DATA chunk + sent within the association, but MAY be bundled with one or more DATA + chunks in the same packet. + + + + + + + + + +Stewart, et al. Standards Track [Page 46] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 10 |Chunk Flags | Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / Cookie / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Chunk Flags: 8 bit + + Set to zero on transmit and ignored on receipt. + + Length: 16 bits (unsigned integer) + + Set to the size of the chunk in bytes, including the 4 bytes of + the chunk header and the size of the Cookie. + + Cookie: variable size + + This field must contain the exact cookie received in the State + Cookie parameter from the previous INIT ACK. + + An implementation SHOULD make the cookie as small as possible to + insure interoperability. + +3.3.12 Cookie Acknowledgement (COOKIE ACK) (11): + + This chunk is used only during the initialization of an association. + It is used to acknowledge the receipt of a COOKIE ECHO chunk. This + chunk MUST precede any DATA or SACK chunk sent within the + association, but MAY be bundled with one or more DATA chunks or SACK + chunk in the same SCTP packet. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 11 |Chunk Flags | Length = 4 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Chunk Flags: 8 bits + + Set to zero on transmit and ignored on receipt. + + + + + + + + +Stewart, et al. Standards Track [Page 47] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +3.3.13 Shutdown Complete (SHUTDOWN COMPLETE) (14): + + This chunk MUST be used to acknowledge the receipt of the SHUTDOWN + ACK chunk at the completion of the shutdown process, see Section 9.2 + for details. + + The SHUTDOWN COMPLETE chunk has no parameters. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 14 |Reserved |T| Length = 4 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Chunk Flags: 8 bits + + Reserved: 7 bits + + Set to 0 on transmit and ignored on receipt. + + T bit: 1 bit + + The T bit is set to 0 if the sender had a TCB that it destroyed. + If the sender did not have a TCB it should set this bit to 1. + + Note: Special rules apply to this chunk for verification, please see + Section 8.5.1 for details. + +4. SCTP Association State Diagram + + During the lifetime of an SCTP association, the SCTP endpoint's + association progress from one state to another in response to various + events. The events that may potentially advance an association's + state include: + + o SCTP user primitive calls, e.g., [ASSOCIATE], [SHUTDOWN], [ABORT], + + o Reception of INIT, COOKIE ECHO, ABORT, SHUTDOWN, etc., control + chunks, or + + o Some timeout events. + + The state diagram in the figures below illustrates state changes, + together with the causing events and resulting actions. Note that + some of the error conditions are not shown in the state diagram. + Full description of all special cases should be found in the text. + + + + + +Stewart, et al. Standards Track [Page 48] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Note: Chunk names are given in all capital letters, while parameter + names have the first letter capitalized, e.g., COOKIE ECHO chunk type + vs. State Cookie parameter. If more than one event/message can occur + which causes a state transition it is labeled (A), (B) etc. + + ----- -------- (frm any state) + / \ / rcv ABORT [ABORT] + rcv INIT | | | ---------- or ---------- + --------------- | v v delete TCB snd ABORT + generate Cookie \ +---------+ delete TCB + snd INIT ACK ---| CLOSED | + +---------+ + / \ [ASSOCIATE] + / \ --------------- + | | create TCB + | | snd INIT + | | strt init timer + rcv valid | | + COOKIE ECHO | v + (1) ---------------- | +------------+ + create TCB | | COOKIE-WAIT| (2) + snd COOKIE ACK | +------------+ + | | + | | rcv INIT ACK + | | ----------------- + | | snd COOKIE ECHO + | | stop init timer + | | strt cookie timer + | v + | +--------------+ + | | COOKIE-ECHOED| (3) + | +--------------+ + | | + | | rcv COOKIE ACK + | | ----------------- + | | stop cookie timer + v v + +---------------+ + | ESTABLISHED | + +---------------+ + + + + + + + + + + + +Stewart, et al. Standards Track [Page 49] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + (from the ESTABLISHED state only) + | + | + /--------+--------\ + [SHUTDOWN] / \ + -------------------| | + check outstanding | | + DATA chunks | | + v | + +---------+ | + |SHUTDOWN-| | rcv SHUTDOWN/check + |PENDING | | outstanding DATA + +---------+ | chunks + | |------------------ + No more outstanding | | + ---------------------| | + snd SHUTDOWN | | + strt shutdown timer | | + v v + +---------+ +-----------+ + (4) |SHUTDOWN-| | SHUTDOWN- | (5,6) + |SENT | | RECEIVED | + +---------+ +-----------+ + | \ | + (A) rcv SHUTDOWN ACK | \ | + ----------------------| \ | + stop shutdown timer | \rcv:SHUTDOWN | + send SHUTDOWN COMPLETE| \ (B) | + delete TCB | \ | + | \ | No more outstanding + | \ |----------------- + | \ | send SHUTDOWN ACK + (B)rcv SHUTDOWN | \ | strt shutdown timer + ----------------------| \ | + send SHUTDOWN ACK | \ | + start shutdown timer | \ | + move to SHUTDOWN- | \ | + ACK-SENT | | | + | v | + | +-----------+ + | | SHUTDOWN- | (7) + | | ACK-SENT | + | +----------+- + | | (C)rcv SHUTDOWN COMPLETE + | |----------------- + | | stop shutdown timer + | | delete TCB + | | + + + +Stewart, et al. Standards Track [Page 50] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + | | (D)rcv SHUTDOWN ACK + | |-------------- + | | stop shutdown timer + | | send SHUTDOWN COMPLETE + | | delete TCB + | | + \ +---------+ / + \-->| CLOSED |<--/ + +---------+ + + Figure 3: State Transition Diagram of SCTP + + Notes: + + 1) If the State Cookie in the received COOKIE ECHO is invalid (i.e., + failed to pass the integrity check), the receiver MUST silently + discard the packet. Or, if the received State Cookie is expired + (see Section 5.1.5), the receiver MUST send back an ERROR chunk. + In either case, the receiver stays in the CLOSED state. + + 2) If the T1-init timer expires, the endpoint MUST retransmit INIT + and re-start the T1-init timer without changing state. This MUST + be repeated up to 'Max.Init.Retransmits' times. After that, the + endpoint MUST abort the initialization process and report the + error to SCTP user. + + 3) If the T1-cookie timer expires, the endpoint MUST retransmit + COOKIE ECHO and re-start the T1-cookie timer without changing + state. This MUST be repeated up to 'Max.Init.Retransmits' times. + After that, the endpoint MUST abort the initialization process and + report the error to SCTP user. + + 4) In SHUTDOWN-SENT state the endpoint MUST acknowledge any received + DATA chunks without delay. + + 5) In SHUTDOWN-RECEIVED state, the endpoint MUST NOT accept any new + send request from its SCTP user. + + 6) In SHUTDOWN-RECEIVED state, the endpoint MUST transmit or + retransmit data and leave this state when all data in queue is + transmitted. + + 7) In SHUTDOWN-ACK-SENT state, the endpoint MUST NOT accept any new + send request from its SCTP user. + + The CLOSED state is used to indicate that an association is not + created (i.e., doesn't exist). + + + + +Stewart, et al. Standards Track [Page 51] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +5. Association Initialization + + Before the first data transmission can take place from one SCTP + endpoint ("A") to another SCTP endpoint ("Z"), the two endpoints must + complete an initialization process in order to set up an SCTP + association between them. + + The SCTP user at an endpoint should use the ASSOCIATE primitive to + initialize an SCTP association to another SCTP endpoint. + + IMPLEMENTATION NOTE: From an SCTP-user's point of view, an + association may be implicitly opened, without an ASSOCIATE primitive + (see 10.1 B) being invoked, by the initiating endpoint's sending of + the first user data to the destination endpoint. The initiating SCTP + will assume default values for all mandatory and optional parameters + for the INIT/INIT ACK. + + Once the association is established, unidirectional streams are open + for data transfer on both ends (see Section 5.1.1). + +5.1 Normal Establishment of an Association + + The initialization process consists of the following steps (assuming + that SCTP endpoint "A" tries to set up an association with SCTP + endpoint "Z" and "Z" accepts the new association): + + A) "A" first sends an INIT chunk to "Z". In the INIT, "A" must + provide its Verification Tag (Tag_A) in the Initiate Tag field. + Tag_A SHOULD be a random number in the range of 1 to 4294967295 + (see 5.3.1 for Tag value selection). After sending the INIT, "A" + starts the T1-init timer and enters the COOKIE-WAIT state. + + B) "Z" shall respond immediately with an INIT ACK chunk. The + destination IP address of the INIT ACK MUST be set to the source + IP address of the INIT to which this INIT ACK is responding. In + the response, besides filling in other parameters, "Z" must set + the Verification Tag field to Tag_A, and also provide its own + Verification Tag (Tag_Z) in the Initiate Tag field. + + Moreover, "Z" MUST generate and send along with the INIT ACK a + State Cookie. See Section 5.1.3 for State Cookie generation. + + Note: After sending out INIT ACK with the State Cookie parameter, + "Z" MUST NOT allocate any resources, nor keep any states for the + new association. Otherwise, "Z" will be vulnerable to resource + attacks. + + + + + +Stewart, et al. Standards Track [Page 52] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + C) Upon reception of the INIT ACK from "Z", "A" shall stop the T1- + init timer and leave COOKIE-WAIT state. "A" shall then send the + State Cookie received in the INIT ACK chunk in a COOKIE ECHO + chunk, start the T1-cookie timer, and enter the COOKIE-ECHOED + state. + + Note: The COOKIE ECHO chunk can be bundled with any pending + outbound DATA chunks, but it MUST be the first chunk in the packet + and until the COOKIE ACK is returned the sender MUST NOT send any + other packets to the peer. + + D) Upon reception of the COOKIE ECHO chunk, Endpoint "Z" will reply + with a COOKIE ACK chunk after building a TCB and moving to the + ESTABLISHED state. A COOKIE ACK chunk may be bundled with any + pending DATA chunks (and/or SACK chunks), but the COOKIE ACK chunk + MUST be the first chunk in the packet. + + IMPLEMENTATION NOTE: An implementation may choose to send the + Communication Up notification to the SCTP user upon reception of a + valid COOKIE ECHO chunk. + + E) Upon reception of the COOKIE ACK, endpoint "A" will move from the + COOKIE-ECHOED state to the ESTABLISHED state, stopping the T1- + cookie timer. It may also notify its ULP about the successful + establishment of the association with a Communication Up + notification (see Section 10). + + An INIT or INIT ACK chunk MUST NOT be bundled with any other chunk. + They MUST be the only chunks present in the SCTP packets that carry + them. + + An endpoint MUST send the INIT ACK to the IP address from which it + received the INIT. + + Note: T1-init timer and T1-cookie timer shall follow the same rules + given in Section 6.3. + + If an endpoint receives an INIT, INIT ACK, or COOKIE ECHO chunk but + decides not to establish the new association due to missing mandatory + parameters in the received INIT or INIT ACK, invalid parameter + values, or lack of local resources, it MUST respond with an ABORT + chunk. It SHOULD also specify the cause of abort, such as the type + of the missing mandatory parameters, etc., by including the error + cause parameters with the ABORT chunk. The Verification Tag field in + the common header of the outbound SCTP packet containing the ABORT + chunk MUST be set to the Initiate Tag value of the peer. + + + + + +Stewart, et al. Standards Track [Page 53] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + After the reception of the first DATA chunk in an association the + endpoint MUST immediately respond with a SACK to acknowledge the DATA + chunk. Subsequent acknowledgements should be done as described in + Section 6.2. + + When the TCB is created, each endpoint MUST set its internal + Cumulative TSN Ack Point to the value of its transmitted Initial TSN + minus one. + + IMPLEMENTATION NOTE: The IP addresses and SCTP port are generally + used as the key to find the TCB within an SCTP instance. + +5.1.1 Handle Stream Parameters + + In the INIT and INIT ACK chunks, the sender of the chunk shall + indicate the number of outbound streams (OS) it wishes to have in the + association, as well as the maximum inbound streams (MIS) it will + accept from the other endpoint. + + After receiving the stream configuration information from the other + side, each endpoint shall perform the following check: If the peer's + MIS is less than the endpoint's OS, meaning that the peer is + incapable of supporting all the outbound streams the endpoint wants + to configure, the endpoint MUST either use MIS outbound streams, or + abort the association and report to its upper layer the resources + shortage at its peer. + + After the association is initialized, the valid outbound stream + identifier range for either endpoint shall be 0 to min(local OS, + remote MIS)-1. + +5.1.2 Handle Address Parameters + + During the association initialization, an endpoint shall use the + following rules to discover and collect the destination transport + address(es) of its peer. + + A) If there are no address parameters present in the received INIT or + INIT ACK chunk, the endpoint shall take the source IP address from + which the chunk arrives and record it, in combination with the + SCTP source port number, as the only destination transport address + for this peer. + + B) If there is a Host Name parameter present in the received INIT or + INIT ACK chunk, the endpoint shall resolve that host name to a + list of IP address(es) and derive the transport address(es) of + this peer by combining the resolved IP address(es) with the SCTP + source port. + + + +Stewart, et al. Standards Track [Page 54] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + The endpoint MUST ignore any other IP address parameters if they + are also present in the received INIT or INIT ACK chunk. + + The time at which the receiver of an INIT resolves the host name + has potential security implications to SCTP. If the receiver of + an INIT resolves the host name upon the reception of the chunk, + and the mechanism the receiver uses to resolve the host name + involves potential long delay (e.g. DNS query), the receiver may + open itself up to resource attacks for the period of time while it + is waiting for the name resolution results before it can build the + State Cookie and release local resources. + + Therefore, in cases where the name translation involves potential + long delay, the receiver of the INIT MUST postpone the name + resolution till the reception of the COOKIE ECHO chunk from the + peer. In such a case, the receiver of the INIT SHOULD build the + State Cookie using the received Host Name (instead of destination + transport addresses) and send the INIT ACK to the source IP + address from which the INIT was received. + + The receiver of an INIT ACK shall always immediately attempt to + resolve the name upon the reception of the chunk. + + The receiver of the INIT or INIT ACK MUST NOT send user data + (piggy-backed or stand-alone) to its peer until the host name is + successfully resolved. + + If the name resolution is not successful, the endpoint MUST + immediately send an ABORT with "Unresolvable Address" error cause + to its peer. The ABORT shall be sent to the source IP address + from which the last peer packet was received. + + C) If there are only IPv4/IPv6 addresses present in the received INIT + or INIT ACK chunk, the receiver shall derive and record all the + transport address(es) from the received chunk AND the source IP + address that sent the INIT or INIT ACK. The transport address(es) + are derived by the combination of SCTP source port (from the + common header) and the IP address parameter(s) carried in the INIT + or INIT ACK chunk and the source IP address of the IP datagram. + The receiver should use only these transport addresses as + destination transport addresses when sending subsequent packets to + its peer. + + IMPLEMENTATION NOTE: In some cases (e.g., when the implementation + doesn't control the source IP address that is used for + transmitting), an endpoint might need to include in its INIT or + INIT ACK all possible IP addresses from which packets to the peer + could be transmitted. + + + +Stewart, et al. Standards Track [Page 55] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + After all transport addresses are derived from the INIT or INIT ACK + chunk using the above rules, the endpoint shall select one of the + transport addresses as the initial primary path. + + Note: The INIT-ACK MUST be sent to the source address of the INIT. + + The sender of INIT may include a 'Supported Address Types' parameter + in the INIT to indicate what types of address are acceptable. When + this parameter is present, the receiver of INIT (initiatee) MUST + either use one of the address types indicated in the Supported + Address Types parameter when responding to the INIT, or abort the + association with an "Unresolvable Address" error cause if it is + unwilling or incapable of using any of the address types indicated by + its peer. + + IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK + fails to resolve the address parameter due to an unsupported type, it + can abort the initiation process and then attempt a re-initiation by + using a 'Supported Address Types' parameter in the new INIT to + indicate what types of address it prefers. + +5.1.3 Generating State Cookie + + When sending an INIT ACK as a response to an INIT chunk, the sender + of INIT ACK creates a State Cookie and sends it in the State Cookie + parameter of the INIT ACK. Inside this State Cookie, the sender + should include a MAC (see [RFC2104] for an example), a time stamp on + when the State Cookie is created, and the lifespan of the State + Cookie, along with all the information necessary for it to establish + the association. + + The following steps SHOULD be taken to generate the State Cookie: + + 1) Create an association TCB using information from both the received + INIT and the outgoing INIT ACK chunk, + + 2) In the TCB, set the creation time to the current time of day, and + the lifespan to the protocol parameter 'Valid.Cookie.Life', + + 3) From the TCB, identify and collect the minimal subset of + information needed to re-create the TCB, and generate a MAC using + this subset of information and a secret key (see [RFC2104] for an + example of generating a MAC), and + + 4) Generate the State Cookie by combining this subset of information + and the resultant MAC. + + + + + +Stewart, et al. Standards Track [Page 56] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + After sending the INIT ACK with the State Cookie parameter, the + sender SHOULD delete the TCB and any other local resource related to + the new association, so as to prevent resource attacks. + + The hashing method used to generate the MAC is strictly a private + matter for the receiver of the INIT chunk. The use of a MAC is + mandatory to prevent denial of service attacks. The secret key + SHOULD be random ([RFC1750] provides some information on randomness + guidelines); it SHOULD be changed reasonably frequently, and the + timestamp in the State Cookie MAY be used to determine which key + should be used to verify the MAC. + + An implementation SHOULD make the cookie as small as possible to + insure interoperability. + +5.1.4 State Cookie Processing + + When an endpoint (in the COOKIE WAIT state) receives an INIT ACK + chunk with a State Cookie parameter, it MUST immediately send a + COOKIE ECHO chunk to its peer with the received State Cookie. The + sender MAY also add any pending DATA chunks to the packet after the + COOKIE ECHO chunk. + + The endpoint shall also start the T1-cookie timer after sending out + the COOKIE ECHO chunk. If the timer expires, the endpoint shall + retransmit the COOKIE ECHO chunk and restart the T1-cookie timer. + This is repeated until either a COOKIE ACK is received or ' + Max.Init.Retransmits' is reached causing the peer endpoint to be + marked unreachable (and thus the association enters the CLOSED + state). + +5.1.5 State Cookie Authentication + + When an endpoint receives a COOKIE ECHO chunk from another endpoint + with which it has no association, it shall take the following + actions: + + 1) Compute a MAC using the TCB data carried in the State Cookie and + the secret key (note the timestamp in the State Cookie MAY be used + to determine which secret key to use). Reference [RFC2104] can be + used as a guideline for generating the MAC, + + 2) Authenticate the State Cookie as one that it previously generated + by comparing the computed MAC against the one carried in the State + Cookie. If this comparison fails, the SCTP packet, including the + COOKIE ECHO and any DATA chunks, should be silently discarded, + + + + + +Stewart, et al. Standards Track [Page 57] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + 3) Compare the creation timestamp in the State Cookie to the current + local time. If the elapsed time is longer than the lifespan + carried in the State Cookie, then the packet, including the COOKIE + ECHO and any attached DATA chunks, SHOULD be discarded and the + endpoint MUST transmit an ERROR chunk with a "Stale Cookie" error + cause to the peer endpoint, + + 4) If the State Cookie is valid, create an association to the sender + of the COOKIE ECHO chunk with the information in the TCB data + carried in the COOKIE ECHO, and enter the ESTABLISHED state, + + 5) Send a COOKIE ACK chunk to the peer acknowledging reception of the + COOKIE ECHO. The COOKIE ACK MAY be bundled with an outbound DATA + chunk or SACK chunk; however, the COOKIE ACK MUST be the first + chunk in the SCTP packet. + + 6) Immediately acknowledge any DATA chunk bundled with the COOKIE + ECHO with a SACK (subsequent DATA chunk acknowledgement should + follow the rules defined in Section 6.2). As mentioned in step + 5), if the SACK is bundled with the COOKIE ACK, the COOKIE ACK + MUST appear first in the SCTP packet. + + If a COOKIE ECHO is received from an endpoint with which the receiver + of the COOKIE ECHO has an existing association, the procedures in + Section 5.2 should be followed. + +5.1.6 An Example of Normal Association Establishment + + In the following example, "A" initiates the association and then + sends a user message to "Z", then "Z" sends two user messages to "A" + later (assuming no bundling or fragmentation occurs): + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 58] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Endpoint A Endpoint Z + {app sets association with Z} + (build TCB) + INIT [I-Tag=Tag_A + & other info] --------\ + (Start T1-init timer) \ + (Enter COOKIE-WAIT state) \---> (compose temp TCB and Cookie_Z) + + /--- INIT ACK [Veri Tag=Tag_A, + / I-Tag=Tag_Z, + (Cancel T1-init timer) <------/ Cookie_Z, & other info] + (destroy temp TCB) + COOKIE ECHO [Cookie_Z] ------\ + (Start T1-init timer) \ + (Enter COOKIE-ECHOED state) \---> (build TCB enter ESTABLISHED + state) + + + /---- COOKIE-ACK + / + (Cancel T1-init timer, <-----/ + Enter ESTABLISHED state) + {app sends 1st user data; strm 0} + DATA [TSN=initial TSN_A + Strm=0,Seq=1 & user data]--\ + (Start T3-rtx timer) \ + \-> + /----- SACK [TSN Ack=init + TSN_A,Block=0] + (Cancel T3-rtx timer) <------/ + + ... + {app sends 2 messages;strm 0} + /---- DATA + / [TSN=init TSN_Z + <--/ Strm=0,Seq=1 & user data 1] + SACK [TSN Ack=init TSN_Z, /---- DATA + Block=0] --------\ / [TSN=init TSN_Z +1, + \/ Strm=0,Seq=2 & user data 2] + <------/\ + \ + \------> + + Figure 4: INITiation Example + + If the T1-init timer expires at "A" after the INIT or COOKIE ECHO + chunks are sent, the same INIT or COOKIE ECHO chunk with the same + Initiate Tag (i.e., Tag_A) or State Cookie shall be retransmitted and + + + +Stewart, et al. Standards Track [Page 59] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + the timer restarted. This shall be repeated Max.Init.Retransmits + times before "A" considers "Z" unreachable and reports the failure to + its upper layer (and thus the association enters the CLOSED state). + When retransmitting the INIT, the endpoint MUST follow the rules + defined in 6.3 to determine the proper timer value. + +5.2 Handle Duplicate or Unexpected INIT, INIT ACK, COOKIE ECHO, and + COOKIE ACK + + During the lifetime of an association (in one of the possible + states), an endpoint may receive from its peer endpoint one of the + setup chunks (INIT, INIT ACK, COOKIE ECHO, and COOKIE ACK). The + receiver shall treat such a setup chunk as a duplicate and process it + as described in this section. + + Note: An endpoint will not receive the chunk unless the chunk was + sent to a SCTP transport address and is from a SCTP transport address + associated with this endpoint. Therefore, the endpoint processes + such a chunk as part of its current association. + + The following scenarios can cause duplicated or unexpected chunks: + + A) The peer has crashed without being detected, re-started itself and + sent out a new INIT chunk trying to restore the association, + + B) Both sides are trying to initialize the association at about the + same time, + + C) The chunk is from a stale packet that was used to establish the + present association or a past association that is no longer in + existence, + + D) The chunk is a false packet generated by an attacker, or + + E) The peer never received the COOKIE ACK and is retransmitting its + COOKIE ECHO. + + The rules in the following sections shall be applied in order to + identify and correctly handle these cases. + +5.2.1 INIT received in COOKIE-WAIT or COOKIE-ECHOED State (Item B) + + This usually indicates an initialization collision, i.e., each + endpoint is attempting, at about the same time, to establish an + association with the other endpoint. + + Upon receipt of an INIT in the COOKIE-WAIT or COOKIE-ECHOED state, an + endpoint MUST respond with an INIT ACK using the same parameters it + + + +Stewart, et al. Standards Track [Page 60] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + sent in its original INIT chunk (including its Initiation Tag, + unchanged). These original parameters are combined with those from + the newly received INIT chunk. The endpoint shall also generate a + State Cookie with the INIT ACK. The endpoint uses the parameters + sent in its INIT to calculate the State Cookie. + + After that, the endpoint MUST NOT change its state, the T1-init timer + shall be left running and the corresponding TCB MUST NOT be + destroyed. The normal procedures for handling State Cookies when a + TCB exists will resolve the duplicate INITs to a single association. + + For an endpoint that is in the COOKIE-ECHOED state it MUST populate + its Tie-Tags with the Tag information of itself and its peer (see + section 5.2.2 for a description of the Tie-Tags). + +5.2.2 Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED, + COOKIE-WAIT and SHUTDOWN-ACK-SENT + + Unless otherwise stated, upon reception of an unexpected INIT for + this association, the endpoint shall generate an INIT ACK with a + State Cookie. In the outbound INIT ACK the endpoint MUST copy its + current Verification Tag and peer's Verification Tag into a reserved + place within the state cookie. We shall refer to these locations as + the Peer's-Tie-Tag and the Local-Tie-Tag. The outbound SCTP packet + containing this INIT ACK MUST carry a Verification Tag value equal to + the Initiation Tag found in the unexpected INIT. And the INIT ACK + MUST contain a new Initiation Tag (randomly generated see Section + 5.3.1). Other parameters for the endpoint SHOULD be copied from the + existing parameters of the association (e.g. number of outbound + streams) into the INIT ACK and cookie. + + After sending out the INIT ACK, the endpoint shall take no further + actions, i.e., the existing association, including its current state, + and the corresponding TCB MUST NOT be changed. + + Note: Only when a TCB exists and the association is not in a COOKIE- + WAIT state are the Tie-Tags populated. For a normal association INIT + (i.e. the endpoint is in a COOKIE-WAIT state), the Tie-Tags MUST be + set to 0 (indicating that no previous TCB existed). The INIT ACK and + State Cookie are populated as specified in section 5.2.1. + +5.2.3 Unexpected INIT ACK + + If an INIT ACK is received by an endpoint in any state other than the + COOKIE-WAIT state, the endpoint should discard the INIT ACK chunk. + An unexpected INIT ACK usually indicates the processing of an old or + duplicated INIT chunk. + + + + +Stewart, et al. Standards Track [Page 61] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +5.2.4 Handle a COOKIE ECHO when a TCB exists + + When a COOKIE ECHO chunk is received by an endpoint in any state for + an existing association (i.e., not in the CLOSED state) the following + rules shall be applied: + + 1) Compute a MAC as described in Step 1 of Section 5.1.5, + + 2) Authenticate the State Cookie as described in Step 2 of Section + 5.1.5 (this is case C or D above). + + 3) Compare the timestamp in the State Cookie to the current time. If + the State Cookie is older than the lifespan carried in the State + Cookie and the Verification Tags contained in the State Cookie do + not match the current association's Verification Tags, the packet, + including the COOKIE ECHO and any DATA chunks, should be + discarded. The endpoint also MUST transmit an ERROR chunk with a + "Stale Cookie" error cause to the peer endpoint (this is case C or + D in section 5.2). + + If both Verification Tags in the State Cookie match the + Verification Tags of the current association, consider the State + Cookie valid (this is case E of section 5.2) even if the lifespan + is exceeded. + + 4) If the State Cookie proves to be valid, unpack the TCB into a + temporary TCB. + + 5) Refer to Table 2 to determine the correct action to be taken. + + + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 62] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + ++------------+------------+---------------+--------------+-------------+ +| Local Tag | Peer's Tag | Local-Tie-Tag |Peer's-Tie-Tag| Action/ | +| | | | | Description | ++------------+------------+---------------+--------------+-------------+ +| X | X | M | M | (A) | ++------------+------------+---------------+--------------+-------------+ +| M | X | A | A | (B) | ++------------+------------+---------------+--------------+-------------+ +| M | 0 | A | A | (B) | ++------------+------------+---------------+--------------+-------------+ +| X | M | 0 | 0 | (C) | ++------------+------------+---------------+--------------+-------------+ +| M | M | A | A | (D) | ++======================================================================+ +| Table 2: Handling of a COOKIE ECHO when a TCB exists | ++======================================================================+ + + Legend: + + X - Tag does not match the existing TCB + M - Tag matches the existing TCB. + 0 - No Tie-Tag in Cookie (unknown). + A - All cases, i.e. M, X or 0. + + Note: For any case not shown in Table 2, the cookie should be + silently discarded. + + Action + + A) In this case, the peer may have restarted. When the endpoint + recognizes this potential 'restart', the existing session is + treated the same as if it received an ABORT followed by a new + COOKIE ECHO with the following exceptions: + + - Any SCTP DATA Chunks MAY be retained (this is an implementation + specific option). + + - A notification of RESTART SHOULD be sent to the ULP instead of + a "COMMUNICATION LOST" notification. + + All the congestion control parameters (e.g., cwnd, ssthresh) + related to this peer MUST be reset to their initial values (see + Section 6.2.1). + + After this the endpoint shall enter the ESTABLISHED state. + + + + + + +Stewart, et al. Standards Track [Page 63] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes + the peer has restarted (Action A), it MUST NOT setup a new + association but instead resend the SHUTDOWN ACK and send an ERROR + chunk with a "Cookie Received while Shutting Down" error cause to + its peer. + + B) In this case, both sides may be attempting to start an association + at about the same time but the peer endpoint started its INIT + after responding to the local endpoint's INIT. Thus it may have + picked a new Verification Tag not being aware of the previous Tag + it had sent this endpoint. The endpoint should stay in or enter + the ESTABLISHED state but it MUST update its peer's Verification + Tag from the State Cookie, stop any init or cookie timers that may + running and send a COOKIE ACK. + + C) In this case, the local endpoint's cookie has arrived late. + Before it arrived, the local endpoint sent an INIT and received an + INIT-ACK and finally sent a COOKIE ECHO with the peer's same tag + but a new tag of its own. The cookie should be silently + discarded. The endpoint SHOULD NOT change states and should leave + any timers running. + + D) When both local and remote tags match the endpoint should always + enter the ESTABLISHED state, if it has not already done so. It + should stop any init or cookie timers that may be running and send + a COOKIE ACK. + + Note: The "peer's Verification Tag" is the tag received in the + Initiate Tag field of the INIT or INIT ACK chunk. + +5.2.4.1 An Example of a Association Restart + + In the following example, "A" initiates the association after a + restart has occurred. Endpoint "Z" had no knowledge of the restart + until the exchange (i.e. Heartbeats had not yet detected the failure + of "A"). (assuming no bundling or fragmentation occurs): + + + + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 64] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +Endpoint A Endpoint Z +<-------------- Association is established----------------------> +Tag=Tag_A Tag=Tag_Z +<---------------------------------------------------------------> +{A crashes and restarts} +{app sets up a association with Z} +(build TCB) +INIT [I-Tag=Tag_A' + & other info] --------\ +(Start T1-init timer) \ +(Enter COOKIE-WAIT state) \---> (find a existing TCB + compose temp TCB and Cookie_Z + with Tie-Tags to previous + association) + /--- INIT ACK [Veri Tag=Tag_A', + / I-Tag=Tag_Z', +(Cancel T1-init timer) <------/ Cookie_Z[TieTags= + Tag_A,Tag_Z + & other info] + (destroy temp TCB,leave original + in place) +COOKIE ECHO [Veri=Tag_Z', + Cookie_Z + Tie=Tag_A, + Tag_Z]----------\ +(Start T1-init timer) \ +(Enter COOKIE-ECHOED state) \---> (Find existing association, + Tie-Tags match old tags, + Tags do not match i.e. + case X X M M above, + Announce Restart to ULP + and reset association). + /---- COOKIE-ACK + / +(Cancel T1-init timer, <-----/ + Enter ESTABLISHED state) +{app sends 1st user data; strm 0} +DATA [TSN=initial TSN_A + Strm=0,Seq=1 & user data]--\ +(Start T3-rtx timer) \ + \-> + /----- SACK [TSN Ack=init TSN_A,Block=0] +(Cancel T3-rtx timer) <------/ + + Figure 5: A Restart Example + + + + + + +Stewart, et al. Standards Track [Page 65] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +5.2.5 Handle Duplicate COOKIE-ACK. + + At any state other than COOKIE-ECHOED, an endpoint should silently + discard a received COOKIE ACK chunk. + +5.2.6 Handle Stale COOKIE Error + + Receipt of an ERROR chunk with a "Stale Cookie" error cause indicates + one of a number of possible events: + + A) That the association failed to completely setup before the State + Cookie issued by the sender was processed. + + B) An old State Cookie was processed after setup completed. + + C) An old State Cookie is received from someone that the receiver is + not interested in having an association with and the ABORT chunk + was lost. + + When processing an ERROR chunk with a "Stale Cookie" error cause an + endpoint should first examine if an association is in the process of + being setup, i.e. the association is in the COOKIE-ECHOED state. In + all cases if the association is not in the COOKIE-ECHOED state, the + ERROR chunk should be silently discarded. + + If the association is in the COOKIE-ECHOED state, the endpoint may + elect one of the following three alternatives. + + 1) Send a new INIT chunk to the endpoint to generate a new State + Cookie and re-attempt the setup procedure. + + 2) Discard the TCB and report to the upper layer the inability to + setup the association. + + 3) Send a new INIT chunk to the endpoint, adding a Cookie + Preservative parameter requesting an extension to the lifetime of + the State Cookie. When calculating the time extension, an + implementation SHOULD use the RTT information measured based on + the previous COOKIE ECHO / ERROR exchange, and should add no more + than 1 second beyond the measured RTT, due to long State Cookie + lifetimes making the endpoint more subject to a replay attack. + + + + + + + + + + +Stewart, et al. Standards Track [Page 66] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +5.3 Other Initialization Issues + +5.3.1 Selection of Tag Value + + Initiate Tag values should be selected from the range of 1 to 2**32 - + 1. It is very important that the Initiate Tag value be randomized to + help protect against "man in the middle" and "sequence number" + attacks. The methods described in [RFC1750] can be used for the + Initiate Tag randomization. Careful selection of Initiate Tags is + also necessary to prevent old duplicate packets from previous + associations being mistakenly processed as belonging to the current + association. + + Moreover, the Verification Tag value used by either endpoint in a + given association MUST NOT change during the lifetime of an + association. A new Verification Tag value MUST be used each time the + endpoint tears-down and then re-establishes an association to the + same peer. + +6. User Data Transfer + + Data transmission MUST only happen in the ESTABLISHED, SHUTDOWN- + PENDING, and SHUTDOWN-RECEIVED states. The only exception to this is + that DATA chunks are allowed to be bundled with an outbound COOKIE + ECHO chunk when in COOKIE-WAIT state. + + DATA chunks MUST only be received according to the rules below in + ESTABLISHED, SHUTDOWN-PENDING, SHUTDOWN-SENT. A DATA chunk received + in CLOSED is out of the blue and SHOULD be handled per 8.4. A DATA + chunk received in any other state SHOULD be discarded. + + A SACK MUST be processed in ESTABLISHED, SHUTDOWN-PENDING, and + SHUTDOWN-RECEIVED. An incoming SACK MAY be processed in COOKIE- + ECHOED. A SACK in the CLOSED state is out of the blue and SHOULD be + processed according to the rules in 8.4. A SACK chunk received in + any other state SHOULD be discarded. + + + A SCTP receiver MUST be able to receive a minimum of 1500 bytes in + one SCTP packet. This means that a SCTP endpoint MUST NOT indicate + less than 1500 bytes in its Initial a_rwnd sent in the INIT or INIT + ACK. + + For transmission efficiency, SCTP defines mechanisms for bundling of + small user messages and fragmentation of large user messages. The + following diagram depicts the flow of user messages through SCTP. + + + + + +Stewart, et al. Standards Track [Page 67] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + In this section the term "data sender" refers to the endpoint that + transmits a DATA chunk and the term "data receiver" refers to the + endpoint that receives a DATA chunk. A data receiver will transmit + SACK chunks. + + +--------------------------+ + | User Messages | + +--------------------------+ + SCTP user ^ | + ==================|==|======================================= + | v (1) + +------------------+ +--------------------+ + | SCTP DATA Chunks | |SCTP Control Chunks | + +------------------+ +--------------------+ + ^ | ^ | + | v (2) | v (2) + +--------------------------+ + | SCTP packets | + +--------------------------+ + SCTP ^ | + ===========================|==|=========================== + | v + Connectionless Packet Transfer Service (e.g., IP) + + Notes: + + 1) When converting user messages into DATA chunks, an endpoint + will fragment user messages larger than the current association + path MTU into multiple DATA chunks. The data receiver will + normally reassemble the fragmented message from DATA chunks + before delivery to the user (see Section 6.9 for details). + + 2) Multiple DATA and control chunks may be bundled by the sender + into a single SCTP packet for transmission, as long as the + final size of the packet does not exceed the current path MTU. + The receiver will unbundle the packet back into the original + chunks. Control chunks MUST come before DATA chunks in the + packet. + + Figure 6: Illustration of User Data Transfer + + The fragmentation and bundling mechanisms, as detailed in Sections + 6.9 and 6.10, are OPTIONAL to implement by the data sender, but they + MUST be implemented by the data receiver, i.e., an endpoint MUST + properly receive and process bundled or fragmented data. + + + + + + +Stewart, et al. Standards Track [Page 68] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +6.1 Transmission of DATA Chunks + + This document is specified as if there is a single retransmission + timer per destination transport address, but implementations MAY have + a retransmission timer for each DATA chunk. + + The following general rules MUST be applied by the data sender for + transmission and/or retransmission of outbound DATA chunks: + + A) At any given time, the data sender MUST NOT transmit new data to + any destination transport address if its peer's rwnd indicates + that the peer has no buffer space (i.e. rwnd is 0, see Section + 6.2.1). However, regardless of the value of rwnd (including if it + is 0), the data sender can always have one DATA chunk in flight to + the receiver if allowed by cwnd (see rule B below). This rule + allows the sender to probe for a change in rwnd that the sender + missed due to the SACK having been lost in transit from the data + receiver to the data sender. + + B) At any given time, the sender MUST NOT transmit new data to a + given transport address if it has cwnd or more bytes of data + outstanding to that transport address. + + C) When the time comes for the sender to transmit, before sending new + DATA chunks, the sender MUST first transmit any outstanding DATA + chunks which are marked for retransmission (limited by the current + cwnd). + + D) Then, the sender can send out as many new DATA chunks as Rule A + and Rule B above allow. + + Multiple DATA chunks committed for transmission MAY be bundled in a + single packet. Furthermore, DATA chunks being retransmitted MAY be + bundled with new DATA chunks, as long as the resulting packet size + does not exceed the path MTU. A ULP may request that no bundling is + performed but this should only turn off any delays that a SCTP + implementation may be using to increase bundling efficiency. It does + not in itself stop all bundling from occurring (i.e. in case of + congestion or retransmission). + + Before an endpoint transmits a DATA chunk, if any received DATA + chunks have not been acknowledged (e.g., due to delayed ack), the + sender should create a SACK and bundle it with the outbound DATA + chunk, as long as the size of the final SCTP packet does not exceed + the current MTU. See Section 6.2. + + + + + + +Stewart, et al. Standards Track [Page 69] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + IMPLEMENTATION NOTE: When the window is full (i.e., transmission is + disallowed by Rule A and/or Rule B), the sender MAY still accept send + requests from its upper layer, but MUST transmit no more DATA chunks + until some or all of the outstanding DATA chunks are acknowledged and + transmission is allowed by Rule A and Rule B again. + + Whenever a transmission or retransmission is made to any address, if + the T3-rtx timer of that address is not currently running, the sender + MUST start that timer. If the timer for that address is already + running, the sender MUST restart the timer if the earliest (i.e., + lowest TSN) outstanding DATA chunk sent to that address is being + retransmitted. Otherwise, the data sender MUST NOT restart the + timer. + + When starting or restarting the T3-rtx timer, the timer value must be + adjusted according to the timer rules defined in Sections 6.3.2, and + 6.3.3. + + Note: The data sender SHOULD NOT use a TSN that is more than 2**31 - + 1 above the beginning TSN of the current send window. + +6.2 Acknowledgement on Reception of DATA Chunks + + The SCTP endpoint MUST always acknowledge the reception of each valid + DATA chunk. + + The guidelines on delayed acknowledgement algorithm specified in + Section 4.2 of [RFC2581] SHOULD be followed. Specifically, an + acknowledgement SHOULD be generated for at least every second packet + (not every second DATA chunk) received, and SHOULD be generated + within 200 ms of the arrival of any unacknowledged DATA chunk. In + some situations it may be beneficial for an SCTP transmitter to be + more conservative than the algorithms detailed in this document + allow. However, an SCTP transmitter MUST NOT be more aggressive than + the following algorithms allow. + + A SCTP receiver MUST NOT generate more than one SACK for every + incoming packet, other than to update the offered window as the + receiving application consumes new data. + + IMPLEMENTATION NOTE: The maximum delay for generating an + acknowledgement may be configured by the SCTP administrator, either + statically or dynamically, in order to meet the specific timing + requirement of the protocol being carried. + + An implementation MUST NOT allow the maximum delay to be configured + to be more than 500 ms. In other words an implementation MAY lower + this value below 500ms but MUST NOT raise it above 500ms. + + + +Stewart, et al. Standards Track [Page 70] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Acknowledgements MUST be sent in SACK chunks unless shutdown was + requested by the ULP in which case an endpoint MAY send an + acknowledgement in the SHUTDOWN chunk. A SACK chunk can acknowledge + the reception of multiple DATA chunks. See Section 3.3.4 for SACK + chunk format. In particular, the SCTP endpoint MUST fill in the + Cumulative TSN Ack field to indicate the latest sequential TSN (of a + valid DATA chunk) it has received. Any received DATA chunks with TSN + greater than the value in the Cumulative TSN Ack field SHOULD also be + reported in the Gap Ack Block fields. + + Note: The SHUTDOWN chunk does not contain Gap Ack Block fields. + Therefore, the endpoint should use a SACK instead of the SHUTDOWN + chunk to acknowledge DATA chunks received out of order . + + When a packet arrives with duplicate DATA chunk(s) and with no new + DATA chunk(s), the endpoint MUST immediately send a SACK with no + delay. If a packet arrives with duplicate DATA chunk(s) bundled with + new DATA chunks, the endpoint MAY immediately send a SACK. Normally + receipt of duplicate DATA chunks will occur when the original SACK + chunk was lost and the peer's RTO has expired. The duplicate TSN + number(s) SHOULD be reported in the SACK as duplicate. + + When an endpoint receives a SACK, it MAY use the Duplicate TSN + information to determine if SACK loss is occurring. Further use of + this data is for future study. + + The data receiver is responsible for maintaining its receive buffers. + The data receiver SHOULD notify the data sender in a timely manner of + changes in its ability to receive data. How an implementation + manages its receive buffers is dependent on many factors (e.g., + Operating System, memory management system, amount of memory, etc.). + However, the data sender strategy defined in Section 6.2.1 is based + on the assumption of receiver operation similar to the following: + + A) At initialization of the association, the endpoint tells the + peer how much receive buffer space it has allocated to the + association in the INIT or INIT ACK. The endpoint sets a_rwnd + to this value. + + B) As DATA chunks are received and buffered, decrement a_rwnd by + the number of bytes received and buffered. This is, in effect, + closing rwnd at the data sender and restricting the amount of + data it can transmit. + + C) As DATA chunks are delivered to the ULP and released from the + receive buffers, increment a_rwnd by the number of bytes + delivered to the upper layer. This is, in effect, opening up + rwnd on the data sender and allowing it to send more data. The + + + +Stewart, et al. Standards Track [Page 71] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + data receiver SHOULD NOT increment a_rwnd unless it has + released bytes from its receive buffer. For example, if the + receiver is holding fragmented DATA chunks in a reassembly + queue, it should not increment a_rwnd. + + D) When sending a SACK, the data receiver SHOULD place the current + value of a_rwnd into the a_rwnd field. The data receiver + SHOULD take into account that the data sender will not + retransmit DATA chunks that are acked via the Cumulative TSN + Ack (i.e., will drop from its retransmit queue). + + Under certain circumstances, the data receiver may need to drop DATA + chunks that it has received but hasn't released from its receive + buffers (i.e., delivered to the ULP). These DATA chunks may have + been acked in Gap Ack Blocks. For example, the data receiver may be + holding data in its receive buffers while reassembling a fragmented + user message from its peer when it runs out of receive buffer space. + It may drop these DATA chunks even though it has acknowledged them in + Gap Ack Blocks. If a data receiver drops DATA chunks, it MUST NOT + include them in Gap Ack Blocks in subsequent SACKs until they are + received again via retransmission. In addition, the endpoint should + take into account the dropped data when calculating its a_rwnd. + + An endpoint SHOULD NOT revoke a SACK and discard data. Only in + extreme circumstance should an endpoint use this procedure (such as + out of buffer space). The data receiver should take into account + that dropping data that has been acked in Gap Ack Blocks can result + in suboptimal retransmission strategies in the data sender and thus + in suboptimal performance. + + The following example illustrates the use of delayed + acknowledgements: + + + + + + + + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 72] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Endpoint A Endpoint Z + + {App sends 3 messages; strm 0} + DATA [TSN=7,Strm=0,Seq=3] ------------> (ack delayed) + (Start T3-rtx timer) + + DATA [TSN=8,Strm=0,Seq=4] ------------> (send ack) + /------- SACK [TSN Ack=8,block=0] + (cancel T3-rtx timer) <-----/ + + DATA [TSN=9,Strm=0,Seq=5] ------------> (ack delayed) + (Start T3-rtx timer) + ... + {App sends 1 message; strm 1} + (bundle SACK with DATA) + /----- SACK [TSN Ack=9,block=0] \ + / DATA [TSN=6,Strm=1,Seq=2] + (cancel T3-rtx timer) <------/ (Start T3-rtx timer) + + (ack delayed) + (send ack) + SACK [TSN Ack=6,block=0] -------------> (cancel T3-rtx timer) + + Figure 7: Delayed Acknowledgment Example + + If an endpoint receives a DATA chunk with no user data (i.e., the + Length field is set to 16) it MUST send an ABORT with error cause set + to "No User Data". + + An endpoint SHOULD NOT send a DATA chunk with no user data part. + +6.2.1 Processing a Received SACK + + Each SACK an endpoint receives contains an a_rwnd value. This value + represents the amount of buffer space the data receiver, at the time + of transmitting the SACK, has left of its total receive buffer space + (as specified in the INIT/INIT ACK). Using a_rwnd, Cumulative TSN + Ack and Gap Ack Blocks, the data sender can develop a representation + of the peer's receive buffer space. + + One of the problems the data sender must take into account when + processing a SACK is that a SACK can be received out of order. That + is, a SACK sent by the data receiver can pass an earlier SACK and be + received first by the data sender. If a SACK is received out of + order, the data sender can develop an incorrect view of the peer's + receive buffer space. + + + + + +Stewart, et al. Standards Track [Page 73] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Since there is no explicit identifier that can be used to detect + out-of-order SACKs, the data sender must use heuristics to determine + if a SACK is new. + + An endpoint SHOULD use the following rules to calculate the rwnd, + using the a_rwnd value, the Cumulative TSN Ack and Gap Ack Blocks in + a received SACK. + + A) At the establishment of the association, the endpoint initializes + the rwnd to the Advertised Receiver Window Credit (a_rwnd) the + peer specified in the INIT or INIT ACK. + + B) Any time a DATA chunk is transmitted (or retransmitted) to a peer, + the endpoint subtracts the data size of the chunk from the rwnd of + that peer. + + C) Any time a DATA chunk is marked for retransmission (via either + T3-rtx timer expiration (Section 6.3.3)or via fast retransmit + (Section 7.2.4)), add the data size of those chunks to the rwnd. + + Note: If the implementation is maintaining a timer on each DATA + chunk then only DATA chunks whose timer expired would be marked + for retransmission. + + D) Any time a SACK arrives, the endpoint performs the following: + + i) If Cumulative TSN Ack is less than the Cumulative TSN Ack + Point, then drop the SACK. Since Cumulative TSN Ack is + monotonically increasing, a SACK whose Cumulative TSN Ack is + less than the Cumulative TSN Ack Point indicates an out-of- + order SACK. + + ii) Set rwnd equal to the newly received a_rwnd minus the + number of bytes still outstanding after processing the + Cumulative TSN Ack and the Gap Ack Blocks. + + iii) If the SACK is missing a TSN that was previously + acknowledged via a Gap Ack Block (e.g., the data receiver + reneged on the data), then mark the corresponding DATA chunk as + available for retransmit: Mark it as missing for fast + retransmit as described in Section 7.2.4 and if no retransmit + timer is running for the destination address to which the DATA + chunk was originally transmitted, then T3-rtx is started for + that destination address. + + + + + + + +Stewart, et al. Standards Track [Page 74] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +6.3 Management of Retransmission Timer + + An SCTP endpoint uses a retransmission timer T3-rtx to ensure data + delivery in the absence of any feedback from its peer. The duration + of this timer is referred to as RTO (retransmission timeout). + + When an endpoint's peer is multi-homed, the endpoint will calculate a + separate RTO for each different destination transport address of its + peer endpoint. + + The computation and management of RTO in SCTP follows closely how TCP + manages its retransmission timer. To compute the current RTO, an + endpoint maintains two state variables per destination transport + address: SRTT (smoothed round-trip time) and RTTVAR (round-trip time + variation). + +6.3.1 RTO Calculation + + The rules governing the computation of SRTT, RTTVAR, and RTO are as + follows: + + C1) Until an RTT measurement has been made for a packet sent to the + given destination transport address, set RTO to the protocol + parameter 'RTO.Initial'. + + C2) When the first RTT measurement R is made, set SRTT <- R, RTTVAR + <- R/2, and RTO <- SRTT + 4 * RTTVAR. + + C3) When a new RTT measurement R' is made, set + + RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'| SRTT + <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R' + + Note: The value of SRTT used in the update to RTTVAR is its value + before updating SRTT itself using the second assignment. + + After the computation, update RTO <- SRTT + 4 * RTTVAR. + + C4) When data is in flight and when allowed by rule C5 below, a new + RTT measurement MUST be made each round trip. Furthermore, new + RTT measurements SHOULD be made no more than once per round-trip + for a given destination transport address. There are two reasons + for this recommendation: First, it appears that measuring more + frequently often does not in practice yield any significant + benefit [ALLMAN99]; second, if measurements are made more often, + then the values of RTO.Alpha and RTO.Beta in rule C3 above should + be adjusted so that SRTT and RTTVAR still adjust to changes at + roughly the same rate (in terms of how many round trips it takes + + + +Stewart, et al. Standards Track [Page 75] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + them to reflect new values) as they would if making only one + measurement per round-trip and using RTO.Alpha and RTO.Beta as + given in rule C3. However, the exact nature of these adjustments + remains a research issue. + + C5) Karn's algorithm: RTT measurements MUST NOT be made using packets + that were retransmitted (and thus for which it is ambiguous + whether the reply was for the first instance of the packet or a + later instance). + + C6) Whenever RTO is computed, if it is less than RTO.Min seconds then + it is rounded up to RTO.Min seconds. The reason for this rule is + that RTOs that do not have a high minimum value are susceptible + to unnecessary timeouts [ALLMAN99]. + + C7) A maximum value may be placed on RTO provided it is at least + RTO.max seconds. + + There is no requirement for the clock granularity G used for + computing RTT measurements and the different state variables, other + than: + + G1) Whenever RTTVAR is computed, if RTTVAR = 0, then adjust RTTVAR <- + G. + + Experience [ALLMAN99] has shown that finer clock granularities (<= + 100 msec) perform somewhat better than more coarse granularities. + +6.3.2 Retransmission Timer Rules + + The rules for managing the retransmission timer are as follows: + + R1) Every time a DATA chunk is sent to any address (including a + retransmission), if the T3-rtx timer of that address is not + running, start it running so that it will expire after the RTO of + that address. The RTO used here is that obtained after any + doubling due to previous T3-rtx timer expirations on the + corresponding destination address as discussed in rule E2 below. + + R2) Whenever all outstanding data sent to an address have been + acknowledged, turn off the T3-rtx timer of that address. + + R3) Whenever a SACK is received that acknowledges the DATA chunk with + the earliest outstanding TSN for that address, restart T3-rtx + timer for that address with its current RTO (if there is still + outstanding data on that address). + + + + + +Stewart, et al. Standards Track [Page 76] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + R4) Whenever a SACK is received missing a TSN that was previously + acknowledged via a Gap Ack Block, start T3-rtx for the + destination address to which the DATA chunk was originally + transmitted if it is not already running. + + The following example shows the use of various timer rules (assuming + the receiver uses delayed acks). + + Endpoint A Endpoint Z + {App begins to send} + Data [TSN=7,Strm=0,Seq=3] ------------> (ack delayed) + (Start T3-rtx timer) + {App sends 1 message; strm 1} + (bundle ack with data) + DATA [TSN=8,Strm=0,Seq=4] ----\ /-- SACK [TSN Ack=7,Block=0] + \ / DATA [TSN=6,Strm=1,Seq=2] + \ / (Start T3-rtx timer) + \ + / \ + (Re-start T3-rtx timer) <------/ \--> (ack delayed) + (ack delayed) + {send ack} + SACK [TSN Ack=6,Block=0] --------------> (Cancel T3-rtx timer) + .. + (send ack) + (Cancel T3-rtx timer) <-------------- SACK [TSN Ack=8,Block=0] + + Figure 8 - Timer Rule Examples + +6.3.3 Handle T3-rtx Expiration + + Whenever the retransmission timer T3-rtx expires for a destination + address, do the following: + + E1) For the destination address for which the timer expires, adjust + its ssthresh with rules defined in Section 7.2.3 and set the cwnd + <- MTU. + + E2) For the destination address for which the timer expires, set RTO + <- RTO * 2 ("back off the timer"). The maximum value discussed + in rule C7 above (RTO.max) may be used to provide an upper bound + to this doubling operation. + + E3) Determine how many of the earliest (i.e., lowest TSN) outstanding + DATA chunks for the address for which the T3-rtx has expired will + fit into a single packet, subject to the MTU constraint for the + path corresponding to the destination transport address to which + the retransmission is being sent (this may be different from the + + + +Stewart, et al. Standards Track [Page 77] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + address for which the timer expires [see Section 6.4]). Call + this value K. Bundle and retransmit those K DATA chunks in a + single packet to the destination endpoint. + + E4) Start the retransmission timer T3-rtx on the destination address + to which the retransmission is sent, if rule R1 above indicates + to do so. The RTO to be used for starting T3-rtx should be the + one for the destination address to which the retransmission is + sent, which, when the receiver is multi-homed, may be different + from the destination address for which the timer expired (see + Section 6.4 below). + + After retransmitting, once a new RTT measurement is obtained (which + can happen only when new data has been sent and acknowledged, per + rule C5, or for a measurement made from a HEARTBEAT [see Section + 8.3]), the computation in rule C3 is performed, including the + computation of RTO, which may result in "collapsing" RTO back down + after it has been subject to doubling (rule E2). + + Note: Any DATA chunks that were sent to the address for which the + T3-rtx timer expired but did not fit in one MTU (rule E3 above), + should be marked for retransmission and sent as soon as cwnd allows + (normally when a SACK arrives). + + The final rule for managing the retransmission timer concerns + failover (see Section 6.4.1): + + F1) Whenever an endpoint switches from the current destination + transport address to a different one, the current retransmission + timers are left running. As soon as the endpoint transmits a + packet containing DATA chunk(s) to the new transport address, + start the timer on that transport address, using the RTO value of + the destination address to which the data is being sent, if rule + R1 indicates to do so. + +6.4 Multi-homed SCTP Endpoints + + An SCTP endpoint is considered multi-homed if there are more than one + transport address that can be used as a destination address to reach + that endpoint. + + Moreover, the ULP of an endpoint shall select one of the multiple + destination addresses of a multi-homed peer endpoint as the primary + path (see Sections 5.1.2 and 10.1 for details). + + By default, an endpoint SHOULD always transmit to the primary path, + unless the SCTP user explicitly specifies the destination transport + address (and possibly source transport address) to use. + + + +Stewart, et al. Standards Track [Page 78] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + An endpoint SHOULD transmit reply chunks (e.g., SACK, HEARTBEAT ACK, + etc.) to the same destination transport address from which it + received the DATA or control chunk to which it is replying. This + rule should also be followed if the endpoint is bundling DATA chunks + together with the reply chunk. + + However, when acknowledging multiple DATA chunks received in packets + from different source addresses in a single SACK, the SACK chunk may + be transmitted to one of the destination transport addresses from + which the DATA or control chunks being acknowledged were received. + + When a receiver of a duplicate DATA chunk sends a SACK to a multi- + homed endpoint it MAY be beneficial to vary the destination address + and not use the source address of the DATA chunk. The reason being + that receiving a duplicate from a multi-homed endpoint might indicate + that the return path (as specified in the source address of the DATA + chunk) for the SACK is broken. + + Furthermore, when its peer is multi-homed, an endpoint SHOULD try to + retransmit a chunk to an active destination transport address that is + different from the last destination address to which the DATA chunk + was sent. + + Retransmissions do not affect the total outstanding data count. + However, if the DATA chunk is retransmitted onto a different + destination address, both the outstanding data counts on the new + destination address and the old destination address to which the data + chunk was last sent shall be adjusted accordingly. + +6.4.1 Failover from Inactive Destination Address + + Some of the transport addresses of a multi-homed SCTP endpoint may + become inactive due to either the occurrence of certain error + conditions (see Section 8.2) or adjustments from SCTP user. + + When there is outbound data to send and the primary path becomes + inactive (e.g., due to failures), or where the SCTP user explicitly + requests to send data to an inactive destination transport address, + before reporting an error to its ULP, the SCTP endpoint should try to + send the data to an alternate active destination transport address if + one exists. + + When retransmitting data, if the endpoint is multi-homed, it should + consider each source-destination address pair in its retransmission + selection policy. When retransmitting the endpoint should attempt to + pick the most divergent source-destination pair from the original + source-destination pair to which the packet was transmitted. + + + + +Stewart, et al. Standards Track [Page 79] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Note: Rules for picking the most divergent source-destination pair + are an implementation decision and is not specified within this + document. + +6.5 Stream Identifier and Stream Sequence Number + + Every DATA chunk MUST carry a valid stream identifier. If an + endpoint receives a DATA chunk with an invalid stream identifier, it + shall acknowledge the reception of the DATA chunk following the + normal procedure, immediately send an ERROR chunk with cause set to + "Invalid Stream Identifier" (see Section 3.3.10) and discard the DATA + chunk. The endpoint may bundle the ERROR chunk in the same packet as + the SACK as long as the ERROR follows the SACK. + + The stream sequence number in all the streams shall start from 0 when + the association is established. Also, when the stream sequence + number reaches the value 65535 the next stream sequence number shall + be set to 0. + +6.6 Ordered and Unordered Delivery + + Within a stream, an endpoint MUST deliver DATA chunks received with + the U flag set to 0 to the upper layer according to the order of + their stream sequence number. If DATA chunks arrive out of order of + their stream sequence number, the endpoint MUST hold the received + DATA chunks from delivery to the ULP until they are re-ordered. + + However, an SCTP endpoint can indicate that no ordered delivery is + required for a particular DATA chunk transmitted within the stream by + setting the U flag of the DATA chunk to 1. + + When an endpoint receives a DATA chunk with the U flag set to 1, it + must bypass the ordering mechanism and immediately deliver the data + to the upper layer (after re-assembly if the user data is fragmented + by the data sender). + + This provides an effective way of transmitting "out-of-band" data in + a given stream. Also, a stream can be used as an "unordered" stream + by simply setting the U flag to 1 in all DATA chunks sent through + that stream. + + IMPLEMENTATION NOTE: When sending an unordered DATA chunk, an + implementation may choose to place the DATA chunk in an outbound + packet that is at the head of the outbound transmission queue if + possible. + + + + + + +Stewart, et al. Standards Track [Page 80] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + The 'Stream Sequence Number' field in a DATA chunk with U flag set to + 1 has no significance. The sender can fill it with arbitrary value, + but the receiver MUST ignore the field. + + Note: When transmitting ordered and unordered data, an endpoint does + not increment its Stream Sequence Number when transmitting a DATA + chunk with U flag set to 1. + +6.7 Report Gaps in Received DATA TSNs + + Upon the reception of a new DATA chunk, an endpoint shall examine the + continuity of the TSNs received. If the endpoint detects a gap in + the received DATA chunk sequence, it SHOULD send a SACK with Gap Ack + Blocks immediately. The data receiver continues sending a SACK after + receipt of each SCTP packet that doesn't fill the gap. + + Based on the Gap Ack Block from the received SACK, the endpoint can + calculate the missing DATA chunks and make decisions on whether to + retransmit them (see Section 6.2.1 for details). + + Multiple gaps can be reported in one single SACK (see Section 3.3.4). + + When its peer is multi-homed, the SCTP endpoint SHOULD always try to + send the SACK to the same destination address from which the last + DATA chunk was received. + + Upon the reception of a SACK, the endpoint MUST remove all DATA + chunks which have been acknowledged by the SACK's Cumulative TSN Ack + from its transmit queue. The endpoint MUST also treat all the DATA + chunks with TSNs not included in the Gap Ack Blocks reported by the + SACK as "missing". The number of "missing" reports for each + outstanding DATA chunk MUST be recorded by the data sender in order + to make retransmission decisions. See Section 7.2.4 for details. + + The following example shows the use of SACK to report a gap. + + + + + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 81] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Endpoint A Endpoint Z + {App sends 3 messages; strm 0} + DATA [TSN=6,Strm=0,Seq=2] ---------------> (ack delayed) + (Start T3-rtx timer) + + DATA [TSN=7,Strm=0,Seq=3] --------> X (lost) + + DATA [TSN=8,Strm=0,Seq=4] ---------------> (gap detected, + immediately send ack) + /----- SACK [TSN Ack=6,Block=1, + / Strt=2,End=2] + <-----/ + (remove 6 from out-queue, + and mark 7 as "1" missing report) + + Figure 9 - Reporting a Gap using SACK + + The maximum number of Gap Ack Blocks that can be reported within a + single SACK chunk is limited by the current path MTU. When a single + SACK can not cover all the Gap Ack Blocks needed to be reported due + to the MTU limitation, the endpoint MUST send only one SACK, + reporting the Gap Ack Blocks from the lowest to highest TSNs, within + the size limit set by the MTU, and leave the remaining highest TSN + numbers unacknowledged. + +6.8 Adler-32 Checksum Calculation + + When sending an SCTP packet, the endpoint MUST strengthen the data + integrity of the transmission by including the Adler-32 checksum + value calculated on the packet, as described below. + + After the packet is constructed (containing the SCTP common header + and one or more control or DATA chunks), the transmitter shall: + + 1) Fill in the proper Verification Tag in the SCTP common header and + initialize the checksum field to 0's. + + 2) Calculate the Adler-32 checksum of the whole packet, including the + SCTP common header and all the chunks. Refer to appendix B for + details of the Adler-32 algorithm. And, + + 3) Put the resultant value into the checksum field in the common + header, and leave the rest of the bits unchanged. + + When an SCTP packet is received, the receiver MUST first check the + Adler-32 checksum: + + 1) Store the received Adler-32 checksum value aside, + + + +Stewart, et al. Standards Track [Page 82] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + 2) Replace the 32 bits of the checksum field in the received SCTP + packet with all '0's and calculate an Adler-32 checksum value of + the whole received packet. And, + + 3) Verify that the calculated Adler-32 checksum is the same as the + received Adler-32 checksum. If not, the receiver MUST treat the + packet as an invalid SCTP packet. + + The default procedure for handling invalid SCTP packets is to + silently discard them. + +6.9 Fragmentation and Reassembly + + An endpoint MAY support fragmentation when sending DATA chunks, but + MUST support reassembly when receiving DATA chunks. If an endpoint + supports fragmentation, it MUST fragment a user message if the size + of the user message to be sent causes the outbound SCTP packet size + to exceed the current MTU. If an implementation does not support + fragmentation of outbound user messages, the endpoint must return an + error to its upper layer and not attempt to send the user message. + + IMPLEMENTATION NOTE: In this error case, the Send primitive + discussed in Section 10.1 would need to return an error to the upper + layer. + + If its peer is multi-homed, the endpoint shall choose a size no + larger than the association Path MTU. The association Path MTU is + the smallest Path MTU of all destination addresses. + + Note: Once a message is fragmented it cannot be re-fragmented. + Instead if the PMTU has been reduced, then IP fragmentation must be + used. Please see Section 7.3 for details of PMTU discovery. + + When determining when to fragment, the SCTP implementation MUST take + into account the SCTP packet header as well as the DATA chunk + header(s). The implementation MUST also take into account the space + required for a SACK chunk if bundling a SACK chunk with the DATA + chunk. + + Fragmentation takes the following steps: + + 1) The data sender MUST break the user message into a series of DATA + chunks such that each chunk plus SCTP overhead fits into an IP + datagram smaller than or equal to the association Path MTU. + + 2) The transmitter MUST then assign, in sequence, a separate TSN to + each of the DATA chunks in the series. The transmitter assigns + the same SSN to each of the DATA chunks. If the user indicates + + + +Stewart, et al. Standards Track [Page 83] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + that the user message is to be delivered using unordered delivery, + then the U flag of each DATA chunk of the user message MUST be set + to 1. + + 3) The transmitter MUST also set the B/E bits of the first DATA chunk + in the series to '10', the B/E bits of the last DATA chunk in the + series to '01', and the B/E bits of all other DATA chunks in the + series to '00'. + + An endpoint MUST recognize fragmented DATA chunks by examining the + B/E bits in each of the received DATA chunks, and queue the + fragmented DATA chunks for re-assembly. Once the user message is + reassembled, SCTP shall pass the re-assembled user message to the + specific stream for possible re-ordering and final dispatching. + + Note: If the data receiver runs out of buffer space while still + waiting for more fragments to complete the re-assembly of the + message, it should dispatch part of its inbound message through a + partial delivery API (see Section 10), freeing some of its receive + buffer space so that the rest of the message may be received. + +6.10 Bundling + + An endpoint bundles chunks by simply including multiple chunks in one + outbound SCTP packet. The total size of the resultant IP datagram, + including the SCTP packet and IP headers, MUST be less or equal to + the current Path MTU. + + If its peer endpoint is multi-homed, the sending endpoint shall + choose a size no larger than the latest MTU of the current primary + path. + + When bundling control chunks with DATA chunks, an endpoint MUST place + control chunks first in the outbound SCTP packet. The transmitter + MUST transmit DATA chunks within a SCTP packet in increasing order of + TSN. + + Note: Since control chunks must be placed first in a packet and + since DATA chunks must be transmitted before SHUTDOWN or SHUTDOWN ACK + chunks, DATA chunks cannot be bundled with SHUTDOWN or SHUTDOWN ACK + chunks. + + Partial chunks MUST NOT be placed in an SCTP packet. + + + + + + + + +Stewart, et al. Standards Track [Page 84] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + An endpoint MUST process received chunks in their order in the + packet. The receiver uses the chunk length field to determine the end + of a chunk and beginning of the next chunk taking account of the fact + that all chunks end on a 4 byte boundary. If the receiver detects a + partial chunk, it MUST drop the chunk. + + An endpoint MUST NOT bundle INIT, INIT ACK or SHUTDOWN COMPLETE with + any other chunks. + +7. Congestion control + + Congestion control is one of the basic functions in SCTP. For some + applications, it may be likely that adequate resources will be + allocated to SCTP traffic to assure prompt delivery of time-critical + data - thus it would appear to be unlikely, during normal operations, + that transmissions encounter severe congestion conditions. However + SCTP must operate under adverse operational conditions, which can + develop upon partial network failures or unexpected traffic surges. + In such situations SCTP must follow correct congestion control steps + to recover from congestion quickly in order to get data delivered as + soon as possible. In the absence of network congestion, these + preventive congestion control algorithms should show no impact on the + protocol performance. + + IMPLEMENTATION NOTE: As far as its specific performance requirements + are met, an implementation is always allowed to adopt a more + conservative congestion control algorithm than the one defined below. + + The congestion control algorithms used by SCTP are based on + [RFC2581]. This section describes how the algorithms defined in + RFC2581 are adapted for use in SCTP. We first list differences in + protocol designs between TCP and SCTP, and then describe SCTP's + congestion control scheme. The description will use the same + terminology as in TCP congestion control whenever appropriate. + + SCTP congestion control is always applied to the entire association, + and not to individual streams. + +7.1 SCTP Differences from TCP Congestion control + + Gap Ack Blocks in the SCTP SACK carry the same semantic meaning as + the TCP SACK. TCP considers the information carried in the SACK as + advisory information only. SCTP considers the information carried in + the Gap Ack Blocks in the SACK chunk as advisory. In SCTP, any DATA + chunk that has been acknowledged by SACK, including DATA that arrived + at the receiving end out of order, are not considered fully delivered + until the Cumulative TSN Ack Point passes the TSN of the DATA chunk + (i.e., the DATA chunk has been acknowledged by the Cumulative TSN Ack + + + +Stewart, et al. Standards Track [Page 85] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + field in the SACK). Consequently, the value of cwnd controls the + amount of outstanding data, rather than (as in the case of non-SACK + TCP) the upper bound between the highest acknowledged sequence number + and the latest DATA chunk that can be sent within the congestion + window. SCTP SACK leads to different implementations of fast- + retransmit and fast-recovery than non-SACK TCP. As an example see + [FALL96]. + + The biggest difference between SCTP and TCP, however, is multi- + homing. SCTP is designed to establish robust communication + associations between two endpoints each of which may be reachable by + more than one transport address. Potentially different addresses may + lead to different data paths between the two endpoints, thus ideally + one may need a separate set of congestion control parameters for each + of the paths. The treatment here of congestion control for multi- + homed receivers is new with SCTP and may require refinement in the + future. The current algorithms make the following assumptions: + + o The sender usually uses the same destination address until being + instructed by the upper layer otherwise; however, SCTP may change + to an alternate destination in the event an address is marked + inactive (see Section 8.2). Also, SCTP may retransmit to a + different transport address than the original transmission. + + o The sender keeps a separate congestion control parameter set for + each of the destination addresses it can send to (not each + source-destination pair but for each destination). The parameters + should decay if the address is not used for a long enough time + period. + + o For each of the destination addresses, an endpoint does slow-start + upon the first transmission to that address. + + Note: TCP guarantees in-sequence delivery of data to its upper-layer + protocol within a single TCP session. This means that when TCP + notices a gap in the received sequence number, it waits until the gap + is filled before delivering the data that was received with sequence + numbers higher than that of the missing data. On the other hand, + SCTP can deliver data to its upper-layer protocol even if there is a + gap in TSN if the Stream Sequence Numbers are in sequence for a + particular stream (i.e., the missing DATA chunks are for a different + stream) or if unordered delivery is indicated. Although this does + not affect cwnd, it might affect rwnd calculation. + + + + + + + + +Stewart, et al. Standards Track [Page 86] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +7.2 SCTP Slow-Start and Congestion Avoidance + + The slow start and congestion avoidance algorithms MUST be used by an + endpoint to control the amount of data being injected into the + network. The congestion control in SCTP is employed in regard to the + association, not to an individual stream. In some situations it may + be beneficial for an SCTP sender to be more conservative than the + algorithms allow; however, an SCTP sender MUST NOT be more aggressive + than the following algorithms allow. + + Like TCP, an SCTP endpoint uses the following three control variables + to regulate its transmission rate. + + o Receiver advertised window size (rwnd, in bytes), which is set by + the receiver based on its available buffer space for incoming + packets. + + Note: This variable is kept on the entire association. + + o Congestion control window (cwnd, in bytes), which is adjusted by + the sender based on observed network conditions. + + Note: This variable is maintained on a per-destination address + basis. + + o Slow-start threshold (ssthresh, in bytes), which is used by the + sender to distinguish slow start and congestion avoidance phases. + + Note: This variable is maintained on a per-destination address + basis. + + SCTP also requires one additional control variable, + partial_bytes_acked, which is used during congestion avoidance phase + to facilitate cwnd adjustment. + + Unlike TCP, an SCTP sender MUST keep a set of these control variables + cwnd, ssthresh and partial_bytes_acked for EACH destination address + of its peer (when its peer is multi-homed). Only one rwnd is kept + for the whole association (no matter if the peer is multi-homed or + has a single address). + +7.2.1 Slow-Start + + Beginning data transmission into a network with unknown conditions or + after a sufficiently long idle period requires SCTP to probe the + network to determine the available capacity. The slow start + algorithm is used for this purpose at the beginning of a transfer, or + after repairing loss detected by the retransmission timer. + + + +Stewart, et al. Standards Track [Page 87] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + o The initial cwnd before DATA transmission or after a sufficiently + long idle period MUST be <= 2*MTU. + + o The initial cwnd after a retransmission timeout MUST be no more + than 1*MTU. + + o The initial value of ssthresh MAY be arbitrarily high (for + example, implementations MAY use the size of the receiver + advertised window). + + o Whenever cwnd is greater than zero, the endpoint is allowed to + have cwnd bytes of data outstanding on that transport address. + + o When cwnd is less than or equal to ssthresh an SCTP endpoint MUST + use the slow start algorithm to increase cwnd (assuming the + current congestion window is being fully utilized). If an + incoming SACK advances the Cumulative TSN Ack Point, cwnd MUST be + increased by at most the lesser of 1) the total size of the + previously outstanding DATA chunk(s) acknowledged, and 2) the + destination's path MTU. This protects against the ACK-Splitting + attack outlined in [SAVAGE99]. + + In instances where its peer endpoint is multi-homed, if an endpoint + receives a SACK that advances its Cumulative TSN Ack Point, then it + should update its cwnd (or cwnds) apportioned to the destination + addresses to which it transmitted the acknowledged data. However if + the received SACK does not advance the Cumulative TSN Ack Point, the + endpoint MUST NOT adjust the cwnd of any of the destination + addresses. + + Because an endpoint's cwnd is not tied to its Cumulative TSN Ack + Point, as duplicate SACKs come in, even though they may not advance + the Cumulative TSN Ack Point an endpoint can still use them to clock + out new data. That is, the data newly acknowledged by the SACK + diminishes the amount of data now in flight to less than cwnd; and so + the current, unchanged value of cwnd now allows new data to be sent. + On the other hand, the increase of cwnd must be tied to the + Cumulative TSN Ack Point advancement as specified above. Otherwise + the duplicate SACKs will not only clock out new data, but also will + adversely clock out more new data than what has just left the + network, during a time of possible congestion. + + o When the endpoint does not transmit data on a given transport + address, the cwnd of the transport address should be adjusted to + max(cwnd/2, 2*MTU) per RTO. + + + + + + +Stewart, et al. Standards Track [Page 88] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +7.2.2 Congestion Avoidance + + When cwnd is greater than ssthresh, cwnd should be incremented by + 1*MTU per RTT if the sender has cwnd or more bytes of data + outstanding for the corresponding transport address. + + In practice an implementation can achieve this goal in the following + way: + + o partial_bytes_acked is initialized to 0. + + o Whenever cwnd is greater than ssthresh, upon each SACK arrival + that advances the Cumulative TSN Ack Point, increase + partial_bytes_acked by the total number of bytes of all new chunks + acknowledged in that SACK including chunks acknowledged by the new + Cumulative TSN Ack and by Gap Ack Blocks. + + o When partial_bytes_acked is equal to or greater than cwnd and + before the arrival of the SACK the sender had cwnd or more bytes + of data outstanding (i.e., before arrival of the SACK, flightsize + was greater than or equal to cwnd), increase cwnd by MTU, and + reset partial_bytes_acked to (partial_bytes_acked - cwnd). + + o Same as in the slow start, when the sender does not transmit DATA + on a given transport address, the cwnd of the transport address + should be adjusted to max(cwnd / 2, 2*MTU) per RTO. + + o When all of the data transmitted by the sender has been + acknowledged by the receiver, partial_bytes_acked is initialized + to 0. + +7.2.3 Congestion Control + + Upon detection of packet losses from SACK (see Section 7.2.4), An + endpoint should do the following: + + ssthresh = max(cwnd/2, 2*MTU) + cwnd = ssthresh + + Basically, a packet loss causes cwnd to be cut in half. + + When the T3-rtx timer expires on an address, SCTP should perform slow + start by: + + ssthresh = max(cwnd/2, 2*MTU) + cwnd = 1*MTU + + + + + +Stewart, et al. Standards Track [Page 89] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + and assure that no more than one SCTP packet will be in flight for + that address until the endpoint receives acknowledgement for + successful delivery of data to that address. + +7.2.4 Fast Retransmit on Gap Reports + + In the absence of data loss, an endpoint performs delayed + acknowledgement. However, whenever an endpoint notices a hole in the + arriving TSN sequence, it SHOULD start sending a SACK back every time + a packet arrives carrying data until the hole is filled. + + Whenever an endpoint receives a SACK that indicates some TSN(s) + missing, it SHOULD wait for 3 further miss indications (via + subsequent SACK's) on the same TSN(s) before taking action with + regard to Fast Retransmit. + + When the TSN(s) is reported as missing in the fourth consecutive + SACK, the data sender shall: + + 1) Mark the missing DATA chunk(s) for retransmission, + + 2) Adjust the ssthresh and cwnd of the destination address(es) to + which the missing DATA chunks were last sent, according to the + formula described in Section 7.2.3. + + 3) Determine how many of the earliest (i.e., lowest TSN) DATA chunks + marked for retransmission will fit into a single packet, subject + to constraint of the path MTU of the destination transport address + to which the packet is being sent. Call this value K. Retransmit + those K DATA chunks in a single packet. + + 4) Restart T3-rtx timer only if the last SACK acknowledged the lowest + outstanding TSN number sent to that address, or the endpoint is + retransmitting the first outstanding DATA chunk sent to that + address. + + Note: Before the above adjustments, if the received SACK also + acknowledges new DATA chunks and advances the Cumulative TSN Ack + Point, the cwnd adjustment rules defined in Sections 7.2.1 and 7.2.2 + must be applied first. + + A straightforward implementation of the above keeps a counter for + each TSN hole reported by a SACK. The counter increments for each + consecutive SACK reporting the TSN hole. After reaching 4 and + starting the fast retransmit procedure, the counter resets to 0. + + + + + + +Stewart, et al. Standards Track [Page 90] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Because cwnd in SCTP indirectly bounds the number of outstanding + TSN's, the effect of TCP fast-recovery is achieved automatically with + no adjustment to the congestion control window size. + +7.3 Path MTU Discovery + + [RFC1191] specifies "Path MTU Discovery", whereby an endpoint + maintains an estimate of the maximum transmission unit (MTU) along a + given Internet path and refrains from sending packets along that path + which exceed the MTU, other than occasional attempts to probe for a + change in the Path MTU (PMTU). RFC 1191 is thorough in its + discussion of the MTU discovery mechanism and strategies for + determining the current end-to-end MTU setting as well as detecting + changes in this value. [RFC1981] specifies the same mechanisms for + IPv6. An SCTP sender using IPv6 MUST use Path MTU Discovery unless + all packets are less than the minimum IPv6 MTU [RFC2460]. + + An endpoint SHOULD apply these techniques, and SHOULD do so on a + per-destination-address basis. + + There are 4 ways in which SCTP differs from the description in RFC + 1191 of applying MTU discovery to TCP: + + 1) SCTP associations can span multiple addresses. An endpoint MUST + maintain separate MTU estimates for each destination address of + its peer. + + 2) Elsewhere in this document, when the term "MTU" is discussed, it + refers to the MTU associated with the destination address + corresponding to the context of the discussion. + + 3) Unlike TCP, SCTP does not have a notion of "Maximum Segment Size". + Accordingly, the MTU for each destination address SHOULD be + initialized to a value no larger than the link MTU for the local + interface to which packets for that remote destination address + will be routed. + + 4) Since data transmission in SCTP is naturally structured in terms + of TSNs rather than bytes (as is the case for TCP), the discussion + in Section 6.5 of RFC 1191 applies: When retransmitting an IP + datagram to a remote address for which the IP datagram appears too + large for the path MTU to that address, the IP datagram SHOULD be + retransmitted without the DF bit set, allowing it to possibly be + fragmented. Transmissions of new IP datagrams MUST have DF set. + + + + + + + +Stewart, et al. Standards Track [Page 91] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + 5) The sender should track an association PMTU which will be the + smallest PMTU discovered for all of the peer's destination + addresses. When fragmenting messages into multiple parts this + association PMTU should be used to calculate the size of each + fragment. This will allow retransmissions to be seamlessly sent + to an alternate address without encountering IP fragmentation. + + Other than these differences, the discussion of TCP's use of MTU + discovery in RFCs 1191 and 1981 applies to SCTP on a per- + destination-address basis. + + Note: For IPv6 destination addresses the DF bit does not exist, + instead the IP datagram must be fragmented as described in [RFC2460]. + +8. Fault Management + +8.1 Endpoint Failure Detection + + An endpoint shall keep a counter on the total number of consecutive + retransmissions to its peer (including retransmissions to all the + destination transport addresses of the peer if it is multi-homed). + If the value of this counter exceeds the limit indicated in the + protocol parameter 'Association.Max.Retrans', the endpoint shall + consider the peer endpoint unreachable and shall stop transmitting + any more data to it (and thus the association enters the CLOSED + state). In addition, the endpoint shall report the failure to the + upper layer, and optionally report back all outstanding user data + remaining in its outbound queue. The association is automatically + closed when the peer endpoint becomes unreachable. + + The counter shall be reset each time a DATA chunk sent to that peer + endpoint is acknowledged (by the reception of a SACK), or a + HEARTBEAT-ACK is received from the peer endpoint. + +8.2 Path Failure Detection + + When its peer endpoint is multi-homed, an endpoint should keep a + error counter for each of the destination transport addresses of the + peer endpoint. + + Each time the T3-rtx timer expires on any address, or when a + HEARTBEAT sent to an idle address is not acknowledged within a RTO, + the error counter of that destination address will be incremented. + When the value in the error counter exceeds the protocol parameter + 'Path.Max.Retrans' of that destination address, the endpoint should + mark the destination transport address as inactive, and a + notification SHOULD be sent to the upper layer. + + + + +Stewart, et al. Standards Track [Page 92] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + When an outstanding TSN is acknowledged or a HEARTBEAT sent to that + address is acknowledged with a HEARTBEAT ACK, the endpoint shall + clear the error counter of the destination transport address to which + the DATA chunk was last sent (or HEARTBEAT was sent). When the peer + endpoint is multi-homed and the last chunk sent to it was a + retransmission to an alternate address, there exists an ambiguity as + to whether or not the acknowledgement should be credited to the + address of the last chunk sent. However, this ambiguity does not + seem to bear any significant consequence to SCTP behavior. If this + ambiguity is undesirable, the transmitter may choose not to clear the + error counter if the last chunk sent was a retransmission. + + Note: When configuring the SCTP endpoint, the user should avoid + having the value of 'Association.Max.Retrans' larger than the + summation of the 'Path.Max.Retrans' of all the destination addresses + for the remote endpoint. Otherwise, all the destination addresses + may become inactive while the endpoint still considers the peer + endpoint reachable. When this condition occurs, how the SCTP chooses + to function is implementation specific. + + When the primary path is marked inactive (due to excessive + retransmissions, for instance), the sender MAY automatically transmit + new packets to an alternate destination address if one exists and is + active. If more than one alternate address is active when the + primary path is marked inactive only ONE transport address SHOULD be + chosen and used as the new destination transport address. + +8.3 Path Heartbeat + + By default, an SCTP endpoint shall monitor the reachability of the + idle destination transport address(es) of its peer by sending a + HEARTBEAT chunk periodically to the destination transport + address(es). + + A destination transport address is considered "idle" if no new chunk + which can be used for updating path RTT (usually including first + transmission DATA, INIT, COOKIE ECHO, HEARTBEAT etc.) and no + HEARTBEAT has been sent to it within the current heartbeat period of + that address. This applies to both active and inactive destination + addresses. + + The upper layer can optionally initiate the following functions: + + A) Disable heartbeat on a specific destination transport address of a + given association, + + B) Change the HB.interval, + + + + +Stewart, et al. Standards Track [Page 93] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + C) Re-enable heartbeat on a specific destination transport address of + a given association, and, + + D) Request an on-demand HEARTBEAT on a specific destination transport + address of a given association. + + The endpoint should increment the respective error counter of the + destination transport address each time a HEARTBEAT is sent to that + address and not acknowledged within one RTO. + + When the value of this counter reaches the protocol parameter ' + Path.Max.Retrans', the endpoint should mark the corresponding + destination address as inactive if it is not so marked, and may also + optionally report to the upper layer the change of reachability of + this destination address. After this, the endpoint should continue + HEARTBEAT on this destination address but should stop increasing the + counter. + + The sender of the HEARTBEAT chunk should include in the Heartbeat + Information field of the chunk the current time when the packet is + sent out and the destination address to which the packet is sent. + + IMPLEMENTATION NOTE: An alternative implementation of the heartbeat + mechanism that can be used is to increment the error counter variable + every time a HEARTBEAT is sent to a destination. Whenever a + HEARTBEAT ACK arrives, the sender SHOULD clear the error counter of + the destination that the HEARTBEAT was sent to. This in effect would + clear the previously stroked error (and any other error counts as + well). + + The receiver of the HEARTBEAT should immediately respond with a + HEARTBEAT ACK that contains the Heartbeat Information field copied + from the received HEARTBEAT chunk. + + Upon the receipt of the HEARTBEAT ACK, the sender of the HEARTBEAT + should clear the error counter of the destination transport address + to which the HEARTBEAT was sent, and mark the destination transport + address as active if it is not so marked. The endpoint may + optionally report to the upper layer when an inactive destination + address is marked as active due to the reception of the latest + HEARTBEAT ACK. The receiver of the HEARTBEAT ACK must also clear the + association overall error count as well (as defined in section 8.1). + + The receiver of the HEARTBEAT ACK should also perform an RTT + measurement for that destination transport address using the time + value carried in the HEARTBEAT ACK chunk. + + + + + +Stewart, et al. Standards Track [Page 94] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + On an idle destination address that is allowed to heartbeat, a + HEARTBEAT chunk is RECOMMENDED to be sent once per RTO of that + destination address plus the protocol parameter 'HB.interval' , with + jittering of +/- 50%, and exponential back-off of the RTO if the + previous HEARTBEAT is unanswered. + + A primitive is provided for the SCTP user to change the HB.interval + and turn on or off the heartbeat on a given destination address. The + heartbeat interval set by the SCTP user is added to the RTO of that + destination (including any exponential backoff). Only one heartbeat + should be sent each time the heartbeat timer expires (if multiple + destinations are idle). It is a implementation decision on how to + choose which of the candidate idle destinations to heartbeat to (if + more than one destination is idle). + + Note: When tuning the heartbeat interval, there is a side effect that + SHOULD be taken into account. When this value is increased, i.e. + the HEARTBEAT takes longer, the detection of lost ABORT messages + takes longer as well. If a peer endpoint ABORTs the association for + any reason and the ABORT chunk is lost, the local endpoint will only + discover the lost ABORT by sending a DATA chunk or HEARTBEAT chunk + (thus causing the peer to send another ABORT). This must be + considered when tuning the HEARTBEAT timer. If the HEARTBEAT is + disabled only sending DATA to the association will discover a lost + ABORT from the peer. + +8.4 Handle "Out of the blue" Packets + + An SCTP packet is called an "out of the blue" (OOTB) packet if it is + correctly formed, i.e., passed the receiver's Adler-32 check (see + Section 6.8), but the receiver is not able to identify the + association to which this packet belongs. + + The receiver of an OOTB packet MUST do the following: + + 1) If the OOTB packet is to or from a non-unicast address, silently + discard the packet. Otherwise, + + 2) If the OOTB packet contains an ABORT chunk, the receiver MUST + silently discard the OOTB packet and take no further action. + Otherwise, + + 3) If the packet contains an INIT chunk with a Verification Tag set + to '0', process it as described in Section 5.1. Otherwise, + + 4) If the packet contains a COOKIE ECHO in the first chunk, process + it as described in Section 5.1. Otherwise, + + + + +Stewart, et al. Standards Track [Page 95] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should + respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. + When sending the SHUTDOWN COMPLETE, the receiver of the OOTB + packet must fill in the Verification Tag field of the outbound + packet with the Verification Tag received in the SHUTDOWN ACK and + set the T-bit in the Chunk Flags to indicate that no TCB was + found. Otherwise, + + 6) If the packet contains a SHUTDOWN COMPLETE chunk, the receiver + should silently discard the packet and take no further action. + Otherwise, + + 7) If the packet contains a "Stale cookie" ERROR or a COOKIE ACK the + SCTP Packet should be silently discarded. Otherwise, + + 8) The receiver should respond to the sender of the OOTB packet with + an ABORT. When sending the ABORT, the receiver of the OOTB packet + MUST fill in the Verification Tag field of the outbound packet + with the value found in the Verification Tag field of the OOTB + packet and set the T-bit in the Chunk Flags to indicate that no + TCB was found. After sending this ABORT, the receiver of the OOTB + packet shall discard the OOTB packet and take no further action. + +8.5 Verification Tag + + The Verification Tag rules defined in this section apply when sending + or receiving SCTP packets which do not contain an INIT, SHUTDOWN + COMPLETE, COOKIE ECHO (see Section 5.1), ABORT or SHUTDOWN ACK chunk. + The rules for sending and receiving SCTP packets containing one of + these chunk types are discussed separately in Section 8.5.1. + + When sending an SCTP packet, the endpoint MUST fill in the + Verification Tag field of the outbound packet with the tag value in + the Initiate Tag parameter of the INIT or INIT ACK received from its + peer. + + When receiving an SCTP packet, the endpoint MUST ensure that the + value in the Verification Tag field of the received SCTP packet + matches its own Tag. If the received Verification Tag value does not + match the receiver's own tag value, the receiver shall silently + discard the packet and shall not process it any further except for + those cases listed in Section 8.5.1 below. + + + + + + + + + +Stewart, et al. Standards Track [Page 96] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +8.5.1 Exceptions in Verification Tag Rules + + A) Rules for packet carrying INIT: + + - The sender MUST set the Verification Tag of the packet to 0. + + - When an endpoint receives an SCTP packet with the Verification + Tag set to 0, it should verify that the packet contains only an + INIT chunk. Otherwise, the receiver MUST silently discard the + packet. + + B) Rules for packet carrying ABORT: + + - The endpoint shall always fill in the Verification Tag field of + the outbound packet with the destination endpoint's tag value + if it is known. + + - If the ABORT is sent in response to an OOTB packet, the + endpoint MUST follow the procedure described in Section 8.4. + + - The receiver MUST accept the packet if the Verification Tag + matches either its own tag, OR the tag of its peer. Otherwise, + the receiver MUST silently discard the packet and take no + further action. + + C) Rules for packet carrying SHUTDOWN COMPLETE: + + - When sending a SHUTDOWN COMPLETE, if the receiver of the + SHUTDOWN ACK has a TCB then the destination endpoint's tag MUST + be used. Only where no TCB exists should the sender use the + Verification Tag from the SHUTDOWN ACK. + + - The receiver of a SHUTDOWN COMPLETE shall accept the packet if + the Verification Tag field of the packet matches its own tag OR + it is set to its peer's tag and the T bit is set in the Chunk + Flags. Otherwise, the receiver MUST silently discard the packet + and take no further action. An endpoint MUST ignore the + SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state. + + D) Rules for packet carrying a COOKIE ECHO + + - When sending a COOKIE ECHO, the endpoint MUST use the value of + the Initial Tag received in the INIT ACK. + + - The receiver of a COOKIE ECHO follows the procedures in Section + 5. + + + + + +Stewart, et al. Standards Track [Page 97] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + E) Rules for packet carrying a SHUTDOWN ACK + + - If the receiver is in COOKIE-ECHOED or COOKIE-WAIT state the + procedures in section 8.4 SHOULD be followed, in other words it + should be treated as an Out Of The Blue packet. + +9. Termination of Association + + An endpoint should terminate its association when it exits from + service. An association can be terminated by either abort or + shutdown. An abort of an association is abortive by definition in + that any data pending on either end of the association is discarded + and not delivered to the peer. A shutdown of an association is + considered a graceful close where all data in queue by either + endpoint is delivered to the respective peers. However, in the case + of a shutdown, SCTP does not support a half-open state (like TCP) + wherein one side may continue sending data while the other end is + closed. When either endpoint performs a shutdown, the association on + each peer will stop accepting new data from its user and only deliver + data in queue at the time of sending or receiving the SHUTDOWN chunk. + +9.1 Abort of an Association + + When an endpoint decides to abort an existing association, it shall + send an ABORT chunk to its peer endpoint. The sender MUST fill in + the peer's Verification Tag in the outbound packet and MUST NOT + bundle any DATA chunk with the ABORT. + + An endpoint MUST NOT respond to any received packet that contains an + ABORT chunk (also see Section 8.4). + + An endpoint receiving an ABORT shall apply the special Verification + Tag check rules described in Section 8.5.1. + + After checking the Verification Tag, the receiving endpoint shall + remove the association from its record, and shall report the + termination to its upper layer. + +9.2 Shutdown of an Association + + Using the SHUTDOWN primitive (see Section 10.1), the upper layer of + an endpoint in an association can gracefully close the association. + This will allow all outstanding DATA chunks from the peer of the + shutdown initiator to be delivered before the association terminates. + + Upon receipt of the SHUTDOWN primitive from its upper layer, the + endpoint enters SHUTDOWN-PENDING state and remains there until all + outstanding data has been acknowledged by its peer. The endpoint + + + +Stewart, et al. Standards Track [Page 98] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + accepts no new data from its upper layer, but retransmits data to the + far end if necessary to fill gaps. + + Once all its outstanding data has been acknowledged, the endpoint + shall send a SHUTDOWN chunk to its peer including in the Cumulative + TSN Ack field the last sequential TSN it has received from the peer. + It shall then start the T2-shutdown timer and enter the SHUTDOWN-SENT + state. If the timer expires, the endpoint must re-send the SHUTDOWN + with the updated last sequential TSN received from its peer. + + The rules in Section 6.3 MUST be followed to determine the proper + timer value for T2-shutdown. To indicate any gaps in TSN, the + endpoint may also bundle a SACK with the SHUTDOWN chunk in the same + SCTP packet. + + An endpoint should limit the number of retransmissions of the + SHUTDOWN chunk to the protocol parameter 'Association.Max.Retrans'. + If this threshold is exceeded the endpoint should destroy the TCB and + MUST report the peer endpoint unreachable to the upper layer (and + thus the association enters the CLOSED state). The reception of any + packet from its peer (i.e. as the peer sends all of its queued DATA + chunks) should clear the endpoint's retransmission count and restart + the T2-Shutdown timer, giving its peer ample opportunity to transmit + all of its queued DATA chunks that have not yet been sent. + + Upon the reception of the SHUTDOWN, the peer endpoint shall + + - enter the SHUTDOWN-RECEIVED state, + + - stop accepting new data from its SCTP user + + - verify, by checking the Cumulative TSN Ack field of the chunk, + that all its outstanding DATA chunks have been received by the + SHUTDOWN sender. + + Once an endpoint as reached the SHUTDOWN-RECEIVED state it MUST NOT + send a SHUTDOWN in response to a ULP request, and should discard + subsequent SHUTDOWN chunks. + + If there are still outstanding DATA chunks left, the SHUTDOWN + receiver shall continue to follow normal data transmission procedures + defined in Section 6 until all outstanding DATA chunks are + acknowledged; however, the SHUTDOWN receiver MUST NOT accept new data + from its SCTP user. + + While in SHUTDOWN-SENT state, the SHUTDOWN sender MUST immediately + respond to each received packet containing one or more DATA chunk(s) + with a SACK, a SHUTDOWN chunk, and restart the T2-shutdown timer. If + + + +Stewart, et al. Standards Track [Page 99] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + it has no more outstanding DATA chunks, the SHUTDOWN receiver shall + send a SHUTDOWN ACK and start a T2-shutdown timer of its own, + entering the SHUTDOWN-ACK-SENT state. If the timer expires, the + endpoint must re-send the SHUTDOWN ACK. + + The sender of the SHUTDOWN ACK should limit the number of + retransmissions of the SHUTDOWN ACK chunk to the protocol parameter ' + Association.Max.Retrans'. If this threshold is exceeded the endpoint + should destroy the TCB and may report the peer endpoint unreachable + to the upper layer (and thus the association enters the CLOSED + state). + + Upon the receipt of the SHUTDOWN ACK, the SHUTDOWN sender shall stop + the T2-shutdown timer, send a SHUTDOWN COMPLETE chunk to its peer, + and remove all record of the association. + + Upon reception of the SHUTDOWN COMPLETE chunk the endpoint will + verify that it is in SHUTDOWN-ACK-SENT state, if it is not the chunk + should be discarded. If the endpoint is in the SHUTDOWN-ACK-SENT + state the endpoint should stop the T2-shutdown timer and remove all + knowledge of the association (and thus the association enters the + CLOSED state). + + An endpoint SHOULD assure that all its outstanding DATA chunks have + been acknowledged before initiating the shutdown procedure. + + An endpoint should reject any new data request from its upper layer + if it is in SHUTDOWN-PENDING, SHUTDOWN-SENT, SHUTDOWN-RECEIVED, or + SHUTDOWN-ACK-SENT state. + + If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT + chunk (e.g., if the SHUTDOWN COMPLETE was lost) with source and + destination transport addresses (either in the IP addresses or in the + INIT chunk) that belong to this association, it should discard the + INIT chunk and retransmit the SHUTDOWN ACK chunk. + + Note: Receipt of an INIT with the same source and destination IP + addresses as used in transport addresses assigned to an endpoint but + with a different port number indicates the initialization of a + separate association. + + The sender of the INIT or COOKIE ECHO should respond to the receipt + of a SHUTDOWN-ACK with a stand-alone SHUTDOWN COMPLETE in an SCTP + packet with the Verification Tag field of its common header set to + the same tag that was received in the SHUTDOWN ACK packet. This is + considered an Out of the Blue packet as defined in Section 8.4. The + sender of the INIT lets T1-init continue running and remains in the + + + + +Stewart, et al. Standards Track [Page 100] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + COOKIE-WAIT or COOKIE-ECHOED state. Normal T1-init timer expiration + will cause the INIT or COOKIE chunk to be retransmitted and thus + start a new association. + + If a SHUTDOWN is received in COOKIE WAIT or COOKIE ECHOED states the + SHUTDOWN chunk SHOULD be silently discarded. + + If an endpoint is in SHUTDOWN-SENT state and receives a SHUTDOWN + chunk from its peer, the endpoint shall respond immediately with a + SHUTDOWN ACK to its peer, and move into a SHUTDOWN-ACK-SENT state + restarting its T2-shutdown timer. + + If an endpoint is in the SHUTDOWN-ACK-SENT state and receives a + SHUTDOWN ACK, it shall stop the T2-shutdown timer, send a SHUTDOWN + COMPLETE chunk to its peer, and remove all record of the association. + +10. Interface with Upper Layer + + The Upper Layer Protocols (ULP) shall request for services by passing + primitives to SCTP and shall receive notifications from SCTP for + various events. + + The primitives and notifications described in this section should be + used as a guideline for implementing SCTP. The following functional + description of ULP interface primitives is shown for illustrative + purposes. Different SCTP implementations may have different ULP + interfaces. However, all SCTPs must provide a certain minimum set of + services to guarantee that all SCTP implementations can support the + same protocol hierarchy. + +10.1 ULP-to-SCTP + + The following sections functionally characterize a ULP/SCTP + interface. The notation used is similar to most procedure or + function calls in high level languages. + + The ULP primitives described below specify the basic functions the + SCTP must perform to support inter-process communication. Individual + implementations must define their own exact format, and may provide + combinations or subsets of the basic functions in single calls. + + A) Initialize + + Format: INITIALIZE ([local port], [local eligible address list]) -> + local SCTP instance name + + + + + + +Stewart, et al. Standards Track [Page 101] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + This primitive allows SCTP to initialize its internal data structures + and allocate necessary resources for setting up its operation + environment. Once SCTP is initialized, ULP can communicate directly + with other endpoints without re-invoking this primitive. + + SCTP will return a local SCTP instance name to the ULP. + + Mandatory attributes: + + None. + + Optional attributes: + + The following types of attributes may be passed along with the + primitive: + + o local port - SCTP port number, if ULP wants it to be specified; + + o local eligible address list - An address list that the local SCTP + endpoint should bind. By default, if an address list is not + included, all IP addresses assigned to the host should be used by + the local endpoint. + + IMPLEMENTATION NOTE: If this optional attribute is supported by an + implementation, it will be the responsibility of the implementation + to enforce that the IP source address field of any SCTP packets sent + out by this endpoint contains one of the IP addresses indicated in + the local eligible address list. + + B) Associate + + Format: ASSOCIATE(local SCTP instance name, destination transport addr, + outbound stream count) + -> association id [,destination transport addr list] [,outbound stream + count] + + This primitive allows the upper layer to initiate an association to a + specific peer endpoint. + + The peer endpoint shall be specified by one of the transport + addresses which defines the endpoint (see Section 1.4). If the local + SCTP instance has not been initialized, the ASSOCIATE is considered + an error. + + An association id, which is a local handle to the SCTP association, + will be returned on successful establishment of the association. If + SCTP is not able to open an SCTP association with the peer endpoint, + an error is returned. + + + +Stewart, et al. Standards Track [Page 102] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Other association parameters may be returned, including the complete + destination transport addresses of the peer as well as the outbound + stream count of the local endpoint. One of the transport address + from the returned destination addresses will be selected by the local + endpoint as default primary path for sending SCTP packets to this + peer. The returned "destination transport addr list" can be used by + the ULP to change the default primary path or to force sending a + packet to a specific transport address. + + IMPLEMENTATION NOTE: If ASSOCIATE primitive is implemented as a + blocking function call, the ASSOCIATE primitive can return + association parameters in addition to the association id upon + successful establishment. If ASSOCIATE primitive is implemented as a + non-blocking call, only the association id shall be returned and + association parameters shall be passed using the COMMUNICATION UP + notification. + + Mandatory attributes: + + o local SCTP instance name - obtained from the INITIALIZE operation. + + o destination transport addr - specified as one of the transport + addresses of the peer endpoint with which the association is to be + established. + + o outbound stream count - the number of outbound streams the ULP + would like to open towards this peer endpoint. + + Optional attributes: + + None. + + C) Shutdown + + Format: SHUTDOWN(association id) + -> result + + Gracefully closes an association. Any locally queued user data will + be delivered to the peer. The association will be terminated only + after the peer acknowledges all the SCTP packets sent. A success + code will be returned on successful termination of the association. + If attempting to terminate the association results in a failure, an + error code shall be returned. + + Mandatory attributes: + + o association id - local handle to the SCTP association + + + + +Stewart, et al. Standards Track [Page 103] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Optional attributes: + + None. + + D) Abort + + Format: ABORT(association id [, cause code]) + -> result + + Ungracefully closes an association. Any locally queued user data + will be discarded and an ABORT chunk is sent to the peer. A success + code will be returned on successful abortion of the association. If + attempting to abort the association results in a failure, an error + code shall be returned. + + Mandatory attributes: + + o association id - local handle to the SCTP association + + Optional attributes: + + o cause code - reason of the abort to be passed to the peer. + + None. + + E) Send + + Format: SEND(association id, buffer address, byte count [,context] + [,stream id] [,life time] [,destination transport address] + [,unorder flag] [,no-bundle flag] [,payload protocol-id] ) + -> result + + This is the main method to send user data via SCTP. + + Mandatory attributes: + + o association id - local handle to the SCTP association + + o buffer address - the location where the user message to be + transmitted is stored; + + o byte count - The size of the user data in number of bytes; + + Optional attributes: + + o context - an optional 32 bit integer that will be carried in the + sending failure notification to the ULP if the transportation of + this User Message fails. + + + +Stewart, et al. Standards Track [Page 104] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + o stream id - to indicate which stream to send the data on. If not + specified, stream 0 will be used. + + o life time - specifies the life time of the user data. The user + data will not be sent by SCTP after the life time expires. This + parameter can be used to avoid efforts to transmit stale user + messages. SCTP notifies the ULP if the data cannot be initiated + to transport (i.e. sent to the destination via SCTP's send + primitive) within the life time variable. However, the user data + will be transmitted if SCTP has attempted to transmit a chunk + before the life time expired. + + IMPLEMENTATION NOTE: In order to better support the data lifetime + option, the transmitter may hold back the assigning of the TSN number + to an outbound DATA chunk to the last moment. And, for + implementation simplicity, once a TSN number has been assigned the + sender should consider the send of this DATA chunk as committed, + overriding any lifetime option attached to the DATA chunk. + + o destination transport address - specified as one of the + destination transport addresses of the peer endpoint to which this + packet should be sent. Whenever possible, SCTP should use this + destination transport address for sending the packets, instead of + the current primary path. + + o unorder flag - this flag, if present, indicates that the user + would like the data delivered in an unordered fashion to the peer + (i.e., the U flag is set to 1 on all DATA chunks carrying this + message). + + o no-bundle flag - instructs SCTP not to bundle this user data with + other outbound DATA chunks. SCTP MAY still bundle even when this + flag is present, when faced with network congestion. + + o payload protocol-id - A 32 bit unsigned integer that is to be + passed to the peer indicating the type of payload protocol data + being transmitted. This value is passed as opaque data by SCTP. + + F) Set Primary + + Format: SETPRIMARY(association id, destination transport address, + [source transport address] ) + -> result + + Instructs the local SCTP to use the specified destination transport + address as primary path for sending packets. + + + + + +Stewart, et al. Standards Track [Page 105] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + The result of attempting this operation shall be returned. If the + specified destination transport address is not present in the + "destination transport address list" returned earlier in an associate + command or communication up notification, an error shall be returned. + + Mandatory attributes: + + o association id - local handle to the SCTP association + + o destination transport address - specified as one of the transport + addresses of the peer endpoint, which should be used as primary + address for sending packets. This overrides the current primary + address information maintained by the local SCTP endpoint. + + Optional attributes: + + o source transport address - optionally, some implementations may + allow you to set the default source address placed in all outgoing + IP datagrams. + + G) Receive + + Format: RECEIVE(association id, buffer address, buffer size + [,stream id]) + -> byte count [,transport address] [,stream id] [,stream sequence + number] [,partial flag] [,delivery number] [,payload protocol-id] + + This primitive shall read the first user message in the SCTP in-queue + into the buffer specified by ULP, if there is one available. The + size of the message read, in bytes, will be returned. It may, + depending on the specific implementation, also return other + information such as the sender's address, the stream id on which it + is received, whether there are more messages available for retrieval, + etc. For ordered messages, their stream sequence number may also be + returned. + + Depending upon the implementation, if this primitive is invoked when + no message is available the implementation should return an + indication of this condition or should block the invoking process + until data does become available. + + Mandatory attributes: + + o association id - local handle to the SCTP association + + o buffer address - the memory location indicated by the ULP to store + the received message. + + + + +Stewart, et al. Standards Track [Page 106] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + o buffer size - the maximum size of data to be received, in bytes. + + Optional attributes: + + o stream id - to indicate which stream to receive the data on. + + o stream sequence number - the stream sequence number assigned by + the sending SCTP peer. + + o partial flag - if this returned flag is set to 1, then this + Receive contains a partial delivery of the whole message. When + this flag is set, the stream id and stream sequence number MUST + accompany this receive. When this flag is set to 0, it indicates + that no more deliveries will be received for this stream sequence + number. + + o payload protocol-id - A 32 bit unsigned integer that is received + from the peer indicating the type of payload protocol of the + received data. This value is passed as opaque data by SCTP. + + H) Status + + Format: STATUS(association id) + -> status data + + This primitive should return a data block containing the following + information: + association connection state, + destination transport address list, + destination transport address reachability states, + current receiver window size, + current congestion window sizes, + number of unacknowledged DATA chunks, + number of DATA chunks pending receipt, + primary path, + most recent SRTT on primary path, + RTO on primary path, + SRTT and RTO on other destination addresses, etc. + + Mandatory attributes: + + o association id - local handle to the SCTP association + + Optional attributes: + + None. + + + + + +Stewart, et al. Standards Track [Page 107] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + I) Change Heartbeat + + Format: CHANGEHEARTBEAT(association id, destination transport address, + new state [,interval]) + -> result + + Instructs the local endpoint to enable or disable heartbeat on the + specified destination transport address. + + The result of attempting this operation shall be returned. + + Note: Even when enabled, heartbeat will not take place if the + destination transport address is not idle. + + Mandatory attributes: + + o association id - local handle to the SCTP association + + o destination transport address - specified as one of the transport + addresses of the peer endpoint. + + o new state - the new state of heartbeat for this destination + transport address (either enabled or disabled). + + Optional attributes: + + o interval - if present, indicates the frequency of the heartbeat if + this is to enable heartbeat on a destination transport address. + This value is added to the RTO of the destination transport + address. This value, if present, effects all destinations. + + J) Request HeartBeat + + Format: REQUESTHEARTBEAT(association id, destination transport + address) + -> result + + Instructs the local endpoint to perform a HeartBeat on the specified + destination transport address of the given association. The returned + result should indicate whether the transmission of the HEARTBEAT + chunk to the destination address is successful. + + Mandatory attributes: + + o association id - local handle to the SCTP association + + o destination transport address - the transport address of the + association on which a heartbeat should be issued. + + + +Stewart, et al. Standards Track [Page 108] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + K) Get SRTT Report + + Format: GETSRTTREPORT(association id, destination transport address) + -> srtt result + + Instructs the local SCTP to report the current SRTT measurement on + the specified destination transport address of the given association. + The returned result can be an integer containing the most recent SRTT + in milliseconds. + + Mandatory attributes: + + o association id - local handle to the SCTP association + + o destination transport address - the transport address of the + association on which the SRTT measurement is to be reported. + + L) Set Failure Threshold + + Format: SETFAILURETHRESHOLD(association id, destination transport + address, failure threshold) + -> result + + This primitive allows the local SCTP to customize the reachability + failure detection threshold 'Path.Max.Retrans' for the specified + destination address. + + Mandatory attributes: + + o association id - local handle to the SCTP association + + o destination transport address - the transport address of the + association on which the failure detection threshold is to be set. + + o failure threshold - the new value of 'Path.Max.Retrans' for the + destination address. + + M) Set Protocol Parameters + + Format: SETPROTOCOLPARAMETERS(association id, [,destination transport + address,] protocol parameter list) + -> result + + This primitive allows the local SCTP to customize the protocol + parameters. + + + + + + +Stewart, et al. Standards Track [Page 109] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Mandatory attributes: + + o association id - local handle to the SCTP association + + o protocol parameter list - The specific names and values of the + protocol parameters (e.g., Association.Max.Retrans [see Section + 14]) that the SCTP user wishes to customize. + + Optional attributes: + + o destination transport address - some of the protocol parameters + may be set on a per destination transport address basis. + + N) Receive unsent message + + Format: RECEIVE_UNSENT(data retrieval id, buffer address, buffer size + [,stream id] [, stream sequence number] [,partial flag] + [,payload protocol-id]) + + o data retrieval id - The identification passed to the ULP in the + failure notification. + + o buffer address - the memory location indicated by the ULP to store + the received message. + + o buffer size - the maximum size of data to be received, in bytes. + + Optional attributes: + + o stream id - this is a return value that is set to indicate + which stream the data was sent to. + + o stream sequence number - this value is returned indicating + the stream sequence number that was associated with the message. + + o partial flag - if this returned flag is set to 1, then this + message is a partial delivery of the whole message. When + this flag is set, the stream id and stream sequence number MUST + accompany this receive. When this flag is set to 0, it indicates + that no more deliveries will be received for this stream sequence + number. + + o payload protocol-id - The 32 bit unsigned integer that was sent to + be sent to the peer indicating the type of payload protocol of the + received data. + + + + + + +Stewart, et al. Standards Track [Page 110] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + O) Receive unacknowledged message + + Format: RECEIVE_UNACKED(data retrieval id, buffer address, buffer size, + [,stream id] [, stream sequence number] [,partial flag] + [,payload protocol-id]) + + o data retrieval id - The identification passed to the ULP in the + failure notification. + + o buffer address - the memory location indicated by the ULP to store + the received message. + + o buffer size - the maximum size of data to be received, in bytes. + + Optional attributes: + + o stream id - this is a return value that is set to indicate which + stream the data was sent to. + + o stream sequence number - this value is returned indicating the + stream sequence number that was associated with the message. + + o partial flag - if this returned flag is set to 1, then this + message is a partial delivery of the whole message. When this + flag is set, the stream id and stream sequence number MUST + accompany this receive. When this flag is set to 0, it indicates + that no more deliveries will be received for this stream sequence + number. + + o payload protocol-id - The 32 bit unsigned integer that was sent to + be sent to the peer indicating the type of payload protocol of the + received data. + + P) Destroy SCTP instance + + Format: DESTROY(local SCTP instance name) + + o local SCTP instance name - this is the value that was passed to + the application in the initialize primitive and it indicates which + SCTP instance to be destroyed. + +10.2 SCTP-to-ULP + + It is assumed that the operating system or application environment + provides a means for the SCTP to asynchronously signal the ULP + process. When SCTP does signal an ULP process, certain information + is passed to the ULP. + + + + +Stewart, et al. Standards Track [Page 111] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + IMPLEMENTATION NOTE: In some cases this may be done through a + separate socket or error channel. + + A) DATA ARRIVE notification + + SCTP shall invoke this notification on the ULP when a user message is + successfully received and ready for retrieval. + + The following may be optionally be passed with the notification: + + o association id - local handle to the SCTP association + + o stream id - to indicate which stream the data is received on. + + B) SEND FAILURE notification + + If a message can not be delivered SCTP shall invoke this notification + on the ULP. + + The following may be optionally be passed with the notification: + + o association id - local handle to the SCTP association + + o data retrieval id - an identification used to retrieve unsent and + unacknowledged data. + + o cause code - indicating the reason of the failure, e.g., size too + large, message life-time expiration, etc. + + o context - optional information associated with this message (see D + in Section 10.1). + + C) NETWORK STATUS CHANGE notification + + When a destination transport address is marked inactive (e.g., when + SCTP detects a failure), or marked active (e.g., when SCTP detects a + recovery), SCTP shall invoke this notification on the ULP. + + The following shall be passed with the notification: + + o association id - local handle to the SCTP association + + o destination transport address - This indicates the destination + transport address of the peer endpoint affected by the change; + + o new-status - This indicates the new status. + + + + + +Stewart, et al. Standards Track [Page 112] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + D) COMMUNICATION UP notification + + This notification is used when SCTP becomes ready to send or receive + user messages, or when a lost communication to an endpoint is + restored. + + IMPLEMENTATION NOTE: If ASSOCIATE primitive is implemented as a + blocking function call, the association parameters are returned as a + result of the ASSOCIATE primitive itself. In that case, + COMMUNICATION UP notification is optional at the association + initiator's side. + + The following shall be passed with the notification: + + o association id - local handle to the SCTP association + + o status - This indicates what type of event has occurred + + o destination transport address list - the complete set of transport + addresses of the peer + + o outbound stream count - the maximum number of streams allowed to + be used in this association by the ULP + + o inbound stream count - the number of streams the peer endpoint has + requested with this association (this may not be the same number + as 'outbound stream count'). + + E) COMMUNICATION LOST notification + + When SCTP loses communication to an endpoint completely (e.g., via + Heartbeats) or detects that the endpoint has performed an abort + operation, it shall invoke this notification on the ULP. + + The following shall be passed with the notification: + + o association id - local handle to the SCTP association + + o status - This indicates what type of event has occurred; The status + may indicate a failure OR a normal termination event + occurred in response to a shutdown or abort request. + + The following may be passed with the notification: + + o data retrieval id - an identification used to retrieve unsent and + unacknowledged data. + + o last-acked - the TSN last acked by that peer endpoint; + + + +Stewart, et al. Standards Track [Page 113] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + o last-sent - the TSN last sent to that peer endpoint; + + F) COMMUNICATION ERROR notification + + When SCTP receives an ERROR chunk from its peer and decides to notify + its ULP, it can invoke this notification on the ULP. + + The following can be passed with the notification: + + o association id - local handle to the SCTP association + + o error info - this indicates the type of error and optionally some + additional information received through the ERROR chunk. + + G) RESTART notification + + When SCTP detects that the peer has restarted, it may send this + notification to its ULP. + + The following can be passed with the notification: + + o association id - local handle to the SCTP association + + H) SHUTDOWN COMPLETE notification + + When SCTP completes the shutdown procedures (section 9.2) this + notification is passed to the upper layer. + + The following can be passed with the notification: + + o association id - local handle to the SCTP association + +11. Security Considerations + +11.1 Security Objectives + + As a common transport protocol designed to reliably carry time- + sensitive user messages, such as billing or signaling messages for + telephony services, between two networked endpoints, SCTP has the + following security objectives. + + - availability of reliable and timely data transport services + - integrity of the user-to-user information carried by SCTP + + + + + + + + +Stewart, et al. Standards Track [Page 114] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +11.2 SCTP Responses To Potential Threats + + SCTP may potentially be used in a wide variety of risk situations. + It is important for operator(s) of systems running SCTP to analyze + their particular situations and decide on the appropriate counter- + measures. + + Operators of systems running SCTP should consult [RFC2196] for + guidance in securing their site. + +11.2.1 Countering Insider Attacks + + The principles of [RFC2196] should be applied to minimize the risk of + theft of information or sabotage by insiders. Such procedures + include publication of security policies, control of access at the + physical, software, and network levels, and separation of services. + +11.2.2 Protecting against Data Corruption in the Network + + Where the risk of undetected errors in datagrams delivered by the + lower layer transport services is considered to be too great, + additional integrity protection is required. If this additional + protection were provided in the application-layer, the SCTP header + would remain vulnerable to deliberate integrity attacks. While the + existing SCTP mechanisms for detection of packet replays are + considered sufficient for normal operation, stronger protections are + needed to protect SCTP when the operating environment contains + significant risk of deliberate attacks from a sophisticated + adversary. + + In order to promote software code-reuse, to avoid re-inventing the + wheel, and to avoid gratuitous complexity to SCTP, the IP + Authentication Header [RFC2402] SHOULD be used when the threat + environment requires stronger integrity protections, but does not + require confidentiality. + + A widely implemented BSD Sockets API extension exists for + applications to request IP security services, such as AH or ESP from + an operating system kernel. Applications can use such an API to + request AH whenever AH use is appropriate. + +11.2.3 Protecting Confidentiality + + In most cases, the risk of breach of confidentiality applies to the + signaling data payload, not to the SCTP or lower-layer protocol + overheads. If that is true, encryption of the SCTP user data only + might be considered. As with the supplementary checksum service, + user data encryption MAY be performed by the SCTP user application. + + + +Stewart, et al. Standards Track [Page 115] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Alternately, the user application MAY use an implementation-specific + API to request that the IP Encapsulating Security Payload (ESP) + [RFC2406] be used to provide confidentiality and integrity. + + Particularly for mobile users, the requirement for confidentiality + might include the masking of IP addresses and ports. In this case + ESP SHOULD be used instead of application-level confidentiality. If + ESP is used to protect confidentiality of SCTP traffic, an ESP + cryptographic transform that includes cryptographic integrity + protection MUST be used, because if there is a confidentiality threat + there will also be a strong integrity threat. + + Whenever ESP is in use, application-level encryption is not generally + required. + + Regardless of where confidentiality is provided, the ISAKMP [RFC2408] + and the Internet Key Exchange (IKE) [RFC2409] SHOULD be used for key + management. + + Operators should consult [RFC2401] for more information on the + security services available at and immediately above the Internet + Protocol layer. + +11.2.4 Protecting against Blind Denial of Service Attacks + + A blind attack is one where the attacker is unable to intercept or + otherwise see the content of data flows passing to and from the + target SCTP node. Blind denial of service attacks may take the form + of flooding, masquerade, or improper monopolization of services. + +11.2.4.1 Flooding + + The objective of flooding is to cause loss of service and incorrect + behavior at target systems through resource exhaustion, interference + with legitimate transactions, and exploitation of buffer-related + software bugs. Flooding may be directed either at the SCTP node or + at resources in the intervening IP Access Links or the Internet. + Where the latter entities are the target, flooding will manifest + itself as loss of network services, including potentially the breach + of any firewalls in place. + + In general, protection against flooding begins at the equipment + design level, where it includes measures such as: + + - avoiding commitment of limited resources before determining that + the request for service is legitimate + + + + + +Stewart, et al. Standards Track [Page 116] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + - giving priority to completion of processing in progress over the + acceptance of new work + + - identification and removal of duplicate or stale queued requests + for service. + + - not responding to unexpected packets sent to non-unicast + addresses. + + Network equipment should be capable of generating an alarm and log if + a suspicious increase in traffic occurs. The log should provide + information such as the identity of the incoming link and source + address(es) used which will help the network or SCTP system operator + to take protective measures. Procedures should be in place for the + operator to act on such alarms if a clear pattern of abuse emerges. + + The design of SCTP is resistant to flooding attacks, particularly in + its use of a four-way start-up handshake, its use of a cookie to + defer commitment of resources at the responding SCTP node until the + handshake is completed, and its use of a Verification Tag to prevent + insertion of extraneous packets into the flow of an established + association. + + The IP Authentication Header and Encapsulating Security Payload might + be useful in reducing the risk of certain kinds of denial of service + attacks." + + The use of the Host Name feature in the INIT chunk could be used to + flood a target DNS server. A large backlog of DNS queries, resolving + the Host Name received in the INIT chunk to IP addresses, could be + accomplished by sending INIT's to multiple hosts in a given domain. + In addition, an attacker could use the Host Name feature in an + indirect attack on a third party by sending large numbers of INITs to + random hosts containing the host name of the target. In addition to + the strain on DNS resources, this could also result in large numbers + of INIT ACKs being sent to the target. One method to protect against + this type of attack is to verify that the IP addresses received from + DNS include the source IP address of the original INIT. If the list + of IP addresses received from DNS does not include the source IP + address of the INIT, the endpoint MAY silently discard the INIT. + This last option will not protect against the attack against the DNS. + + + + + + + + + + +Stewart, et al. Standards Track [Page 117] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +11.2.4.2 Blind Masquerade + + Masquerade can be used to deny service in several ways: + + - by tying up resources at the target SCTP node to which the + impersonated node has limited access. For example, the target + node may by policy permit a maximum of one SCTP association with + the impersonated SCTP node. The masquerading attacker may attempt + to establish an association purporting to come from the + impersonated node so that the latter cannot do so when it requires + it. + + - by deliberately allowing the impersonation to be detected, thereby + provoking counter-measures which cause the impersonated node to be + locked out of the target SCTP node. + + - by interfering with an established association by inserting + extraneous content such as a SHUTDOWN request. + + SCTP reduces the risk of blind masquerade attacks through IP spoofing + by use of the four-way startup handshake. Man-in-the-middle + masquerade attacks are discussed in Section 11.3 below. Because the + initial exchange is memoryless, no lockout mechanism is triggered by + blind masquerade attacks. In addition, the INIT ACK containing the + State Cookie is transmitted back to the IP address from which it + received the INIT. Thus the attacker would not receive the INIT ACK + containing the State Cookie. SCTP protects against insertion of + extraneous packets into the flow of an established association by use + of the Verification Tag. + + Logging of received INIT requests and abnormalities such as + unexpected INIT ACKs might be considered as a way to detect patterns + of hostile activity. However, the potential usefulness of such + logging must be weighed against the increased SCTP startup processing + it implies, rendering the SCTP node more vulnerable to flooding + attacks. Logging is pointless without the establishment of operating + procedures to review and analyze the logs on a routine basis. + +11.2.4.3 Improper Monopolization of Services + + Attacks under this heading are performed openly and legitimately by + the attacker. They are directed against fellow users of the target + SCTP node or of the shared resources between the attacker and the + target node. Possible attacks include the opening of a large number + of associations between the attacker's node and the target, or + transfer of large volumes of information within a legitimately- + established association. + + + + +Stewart, et al. Standards Track [Page 118] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Policy limits should be placed on the number of associations per + adjoining SCTP node. SCTP user applications should be capable of + detecting large volumes of illegitimate or "no-op" messages within a + given association and either logging or terminating the association + as a result, based on local policy. + +11.3 Protection against Fraud and Repudiation + + The objective of fraud is to obtain services without authorization + and specifically without paying for them. In order to achieve this + objective, the attacker must induce the SCTP user application at the + target SCTP node to provide the desired service while accepting + invalid billing data or failing to collect it. Repudiation is a + related problem, since it may occur as a deliberate act of fraud or + simply because the repudiating party kept inadequate records of + service received. + + Potential fraudulent attacks include interception and misuse of + authorizing information such as credit card numbers, blind masquerade + and replay, and man-in-the middle attacks which modify the packets + passing through a target SCTP association in real time. + + The interception attack is countered by the confidentiality measures + discussed in Section 11.2.3 above. + + Section 11.2.4.2 describes how SCTP is resistant to blind masquerade + attacks, as a result of the four-way startup handshake and the + Verification Tag. The Verification Tag and TSN together are + protections against blind replay attacks, where the replay is into an + existing association. + + However, SCTP does not protect against man-in-the-middle attacks + where the attacker is able to intercept and alter the packets sent + and received in an association. For example, the INIT ACK will have + sufficient information sent on the wire for an adversary in the + middle to hijack an existing SCTP association. Where a significant + possibility of such attacks is seen to exist, or where possible + repudiation is an issue, the use of the IPSEC AH service is + recommended to ensure both the integrity and the authenticity of the + SCTP packets passed. + + SCTP also provides no protection against attacks originating at or + beyond the SCTP node and taking place within the context of an + existing association. Prevention of such attacks should be covered + by appropriate security policies at the host site, as discussed in + Section 11.2.1. + + + + + +Stewart, et al. Standards Track [Page 119] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +12. Recommended Transmission Control Block (TCB) Parameters + + This section details a recommended set of parameters that should be + contained within the TCB for an implementation. This section is for + illustrative purposes and should not be deemed as requirements on an + implementation or as an exhaustive list of all parameters inside an + SCTP TCB. Each implementation may need its own additional parameters + for optimization. + +12.1 Parameters necessary for the SCTP instance + + Associations: A list of current associations and mappings to the data + consumers for each association. This may be in the + form of a hash table or other implementation dependent + structure. The data consumers may be process + identification information such as file descriptors, + named pipe pointer, or table pointers dependent on how + SCTP is implemented. + + Secret Key: A secret key used by this endpoint to compute the MAC. + This SHOULD be a cryptographic quality random number + with a sufficient length. Discussion in [RFC1750] can + be helpful in selection of the key. + + Address List: The list of IP addresses that this instance has bound. + This information is passed to one's peer(s) in INIT and + INIT ACK chunks. + + SCTP Port: The local SCTP port number the endpoint is bound to. + +12.2 Parameters necessary per association (i.e. the TCB) + + Peer : Tag value to be sent in every packet and is received + Verification: in the INIT or INIT ACK chunk. + Tag : + + My : Tag expected in every inbound packet and sent in the + Verification: INIT or INIT ACK chunk. + Tag : + + State : A state variable indicating what state the association + : is in, i.e. COOKIE-WAIT, COOKIE-ECHOED, ESTABLISHED, + : SHUTDOWN-PENDING, SHUTDOWN-SENT, SHUTDOWN-RECEIVED, + : SHUTDOWN-ACK-SENT. + + Note: No "CLOSED" state is illustrated since if a + association is "CLOSED" its TCB SHOULD be removed. + + + + +Stewart, et al. Standards Track [Page 120] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Peer : A list of SCTP transport addresses that the peer is + Transport : bound to. This information is derived from the INIT or + Address : INIT ACK and is used to associate an inbound packet + List : with a given association. Normally this information is + : hashed or keyed for quick lookup and access of the TCB. + + Primary : This is the current primary destination transport + Path : address of the peer endpoint. It may also specify a + : source transport address on this endpoint. + + Overall : The overall association error count. + Error Count : + + Overall : The threshold for this association that if the Overall + Error : Error Count reaches will cause this association to be + Threshold : torn down. + + Peer Rwnd : Current calculated value of the peer's rwnd. + + Next TSN : The next TSN number to be assigned to a new DATA chunk. + : This is sent in the INIT or INIT ACK chunk to the peer + : and incremented each time a DATA chunk is assigned a + : TSN (normally just prior to transmit or during + : fragmentation). + + Last Rcvd : This is the last TSN received in sequence. This value + TSN : is set initially by taking the peer's Initial TSN, + : received in the INIT or INIT ACK chunk, and + : subtracting one from it. + + Mapping : An array of bits or bytes indicating which out of + Array : order TSN's have been received (relative to the + : Last Rcvd TSN). If no gaps exist, i.e. no out of order + : packets have been received, this array will be set to + : all zero. This structure may be in the form of a + : circular buffer or bit array. + + Ack State : This flag indicates if the next received packet + : is to be responded to with a SACK. This is initialized + : to 0. When a packet is received it is incremented. + : If this value reaches 2 or more, a SACK is sent and the + : value is reset to 0. Note: This is used only when no + : DATA chunks are received out of order. When DATA chunks + : are out of order, SACK's are not delayed (see Section + : 6). + + + + + + +Stewart, et al. Standards Track [Page 121] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Inbound : An array of structures to track the inbound streams. + Streams : Normally including the next sequence number expected + : and possibly the stream number. + + Outbound : An array of structures to track the outbound streams. + Streams : Normally including the next sequence number to + : be sent on the stream. + + Reasm Queue : A re-assembly queue. + + Local : The list of local IP addresses bound in to this + Transport : association. + Address : + List : + + Association : The smallest PMTU discovered for all of the + PMTU : peer's transport addresses. + +12.3 Per Transport Address Data + + For each destination transport address in the peer's address list + derived from the INIT or INIT ACK chunk, a number of data elements + needs to be maintained including: + + Error count : The current error count for this destination. + + Error : Current error threshold for this destination i.e. + Threshold : what value marks the destination down if Error count + : reaches this value. + + cwnd : The current congestion window. + + ssthresh : The current ssthresh value. + + RTO : The current retransmission timeout value. + + SRTT : The current smoothed round trip time. + + RTTVAR : The current RTT variation. + + partial : The tracking method for increase of cwnd when in + bytes acked : congestion avoidance mode (see Section 6.2.2) + + state : The current state of this destination, i.e. DOWN, UP, + : ALLOW-HB, NO-HEARTBEAT, etc. + + PMTU : The current known path MTU. + + + + +Stewart, et al. Standards Track [Page 122] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Per : A timer used by each destination. + Destination : + Timer : + + RTO-Pending : A flag used to track if one of the DATA chunks sent to + this address is currently being used to compute a + RTT. If this flag is 0, the next DATA chunk sent to this + destination should be used to compute a RTT and this + flag should be set. Every time the RTT calculation + completes (i.e. the DATA chunk is SACK'd) clear this + flag. + + last-time : The time this destination was last sent to. This can be + used : used to determine if a HEARTBEAT is needed. + +12.4 General Parameters Needed + + Out Queue : A queue of outbound DATA chunks. + + In Queue : A queue of inbound DATA chunks. + +13. IANA Considerations + + This protocol will require port reservation like TCP for the use of + "well known" servers within the Internet. All current TCP ports + shall be automatically reserved in the SCTP port address space. New + requests should follow IANA's current mechanisms for TCP. + + This protocol may also be extended through IANA in three ways: + + -- through definition of additional chunk types, + -- through definition of additional parameter types, or + -- through definition of additional cause codes within + ERROR chunks + + In the case where a particular ULP using SCTP desires to have its own + ports, the ULP should be responsible for registering with IANA for + getting its ports assigned. + +13.1 IETF-defined Chunk Extension + + The definition and use of new chunk types is an integral part of + SCTP. Thus, new chunk types are assigned by IANA through an IETF + Consensus action as defined in [RFC2434]. + + The documentation for a new chunk code type must include the + following information: + + + + +Stewart, et al. Standards Track [Page 123] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + a) A long and short name for the new chunk type; + + b) A detailed description of the structure of the chunk, which MUST + conform to the basic structure defined in Section 3.2; + + c) A detailed definition and description of intended use of each + field within the chunk, including the chunk flags if any; + + d) A detailed procedural description of the use of the new chunk type + within the operation of the protocol. + + The last chunk type (255) is reserved for future extension if + necessary. + +13.2 IETF-defined Chunk Parameter Extension + + The assignment of new chunk parameter type codes is done through an + IETF Consensus action as defined in [RFC2434]. Documentation of the + chunk parameter MUST contain the following information: + + a) Name of the parameter type. + + b) Detailed description of the structure of the parameter field. + This structure MUST conform to the general type-length-value + format described in Section 3.2.1. + + c) Detailed definition of each component of the parameter value. + + d) Detailed description of the intended use of this parameter type, + and an indication of whether and under what circumstances multiple + instances of this parameter type may be found within the same + chunk. + +13.3 IETF-defined Additional Error Causes + + Additional cause codes may be allocated in the range 11 to 65535 + through a Specification Required action as defined in [RFC2434]. + Provided documentation must include the following information: + + a) Name of the error condition. + + b) Detailed description of the conditions under which an SCTP + endpoint should issue an ERROR (or ABORT) with this cause code. + + c) Expected action by the SCTP endpoint which receives an ERROR (or + ABORT) chunk containing this cause code. + + + + + +Stewart, et al. Standards Track [Page 124] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + d) Detailed description of the structure and content of data fields + which accompany this cause code. + + The initial word (32 bits) of a cause code parameter MUST conform to + the format shown in Section 3.3.10, i.e.: + + -- first two bytes contain the cause code value + -- last two bytes contain length of the Cause Parameter. + +13.4 Payload Protocol Identifiers + + Except for value 0 which is reserved by SCTP to indicate an + unspecified payload protocol identifier in a DATA chunk, SCTP will + not be responsible for standardizing or verifying any payload + protocol identifiers; SCTP simply receives the identifier from the + upper layer and carries it with the corresponding payload data. + + The upper layer, i.e., the SCTP user, SHOULD standardize any specific + protocol identifier with IANA if it is so desired. The use of any + specific payload protocol identifier is out of the scope of SCTP. + +14. Suggested SCTP Protocol Parameter Values + + The following protocol parameters are RECOMMENDED: + + RTO.Initial - 3 seconds + RTO.Min - 1 second + RTO.Max - 60 seconds + RTO.Alpha - 1/8 + RTO.Beta - 1/4 + Valid.Cookie.Life - 60 seconds + Association.Max.Retrans - 10 attempts + Path.Max.Retrans - 5 attempts (per destination address) + Max.Init.Retransmits - 8 attempts + HB.interval - 30 seconds + + IMPLEMENTATION NOTE: The SCTP implementation may allow ULP to + customize some of these protocol parameters (see Section 10). + + Note: RTO.Min SHOULD be set as recommended above. + + + + + + + + + + + +Stewart, et al. Standards Track [Page 125] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +15. Acknowledgements + + The authors wish to thank Mark Allman, R.J. Atkinson, Richard Band, + Scott Bradner, Steve Bellovin, Peter Butler, Ram Dantu, R. + Ezhirpavai, Mike Fisk, Sally Floyd, Atsushi Fukumoto, Matt Holdrege, + Henry Houh, Christian Huitema, Gary Lehecka, Jonathan Lee, David + Lehmann, John Loughney, Daniel Luan, Barry Nagelberg, Thomas Narten, + Erik Nordmark, Lyndon Ong, Shyamal Prasad, Kelvin Porter, Heinz + Prantner, Jarno Rajahalme, Raymond E. Reeves, Renee Revis, Ivan Arias + Rodriguez, A. Sankar, Greg Sidebottom, Brian Wyld, La Monte Yarroll, + and many others for their invaluable comments. + +16. Authors' Addresses + + Randall R. Stewart + 24 Burning Bush Trail. + Crystal Lake, IL 60012 + USA + + Phone: +1-815-477-2127 + EMail: rrs@cisco.com + + + Qiaobing Xie + Motorola, Inc. + 1501 W. Shure Drive, #2309 + Arlington Heights, IL 60004 + USA + + Phone: +1-847-632-3028 + EMail: qxie1@email.mot.com + + + Ken Morneault + Cisco Systems Inc. + 13615 Dulles Technology Drive + Herndon, VA. 20171 + USA + + Phone: +1-703-484-3323 + EMail: kmorneau@cisco.com + + + + + + + + + + +Stewart, et al. Standards Track [Page 126] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Chip Sharp + Cisco Systems Inc. + 7025 Kit Creek Road + Research Triangle Park, NC 27709 + USA + + Phone: +1-919-392-3121 + EMail: chsharp@cisco.com + + + Hanns Juergen Schwarzbauer + SIEMENS AG + Hofmannstr. 51 + 81359 Munich + Germany + + Phone: +49-89-722-24236 + EMail: HannsJuergen.Schwarzbauer@icn.siemens.de + + + Tom Taylor + Nortel Networks + 1852 Lorraine Ave. + Ottawa, Ontario + Canada K1H 6Z8 + + Phone: +1-613-736-0961 + EMail: taylor@nortelnetworks.com + + + Ian Rytina + Ericsson Australia + 37/360 Elizabeth Street + Melbourne, Victoria 3000 + Australia + + Phone: +61-3-9301-6164 + EMail: ian.rytina@ericsson.com + + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 127] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + Malleswar Kalla + Telcordia Technologies + 3 Corporate Place + PYA-2J-341 + Piscataway, NJ 08854 + USA + + Phone: +1-732-699-3728 + EMail: mkalla@telcordia.com + + Lixia Zhang + UCLA Computer Science Department + 4531G Boelter Hall + Los Angeles, CA 90095-1596 + USA + + Phone: +1-310-825-2695 + EMail: lixia@cs.ucla.edu + + Vern Paxson + ACIRI + 1947 Center St., Suite 600, + Berkeley, CA 94704-1198 + USA + + Phone: +1-510-666-2882 + EMail: vern@aciri.org + +17. References + + [RFC768] Postel, J. (ed.), "User Datagram Protocol", STD 6, RFC + 768, August 1980. + + [RFC793] Postel, J. (ed.), "Transmission Control Protocol", STD 7, + RFC 793, September 1981. + + [RFC1123] Braden, R., "Requirements for Internet hosts - application + and support", STD 3, RFC 1123, October 1989. + + [RFC1191] Mogul, J. and S. Deering, "Path MTU Discovery", RFC 1191, + November 1990. + + [RFC1700] Reynolds, J. and J. Postel, "Assigned Numbers", STD 2, RFC + 1700, October 1994. + + [RFC1981] McCann, J., Deering, S. and J. Mogul, "Path MTU Discovery + for IP version 6", RFC 1981, August 1996. + + + + +Stewart, et al. Standards Track [Page 128] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + [RFC1982] Elz, R. and R. Bush, "Serial Number Arithmetic", RFC 1982, + August 1996. + + [RFC2026] Bradner, S., "The Internet Standards Process -- Revision + 3", BCP 9, RFC 2026, October 1996. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC2401] Kent, S. and R. Atkinson, "Security Architecture for the + Internet Protocol", RFC 2401, November 1998. + + [RFC2402] Kent, S. and R. Atkinson, "IP Authentication Header", RFC + 2402, November 1998. + + [RFC2406] Kent, S. and R. Atkinson, "IP Encapsulating Security + Payload (ESP)", RFC 2406, November 1998. + + [RFC2408] Maughan, D., Schertler, M., Schneider, M. and J. Turner, + "Internet Security Association and Key Management + Protocol", RFC 2408, November 1998. + + [RFC2409] Harkins, D. and D. Carrel, "The Internet Key Exchange + (IKE)", RFC 2409, November 1998. + + [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an + IANA Considerations Section in RFCs", BCP 26, RFC 2434, + October 1998. + + [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6 + (IPv6) Specification", RFC 2460, December 1998. + + [RFC2581] Allman, M., Paxson, V. and W. Stevens, "TCP Congestion + Control", RFC 2581, April 1999. + +18. Bibliography + + [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End + Network Path Properties", Proc. SIGCOMM'99, 1999. + + [FALL96] Fall, K. and Floyd, S., Simulation-based Comparisons of + Tahoe, Reno, and SACK TCP, Computer Communications Review, + V. 26 N. 3, July 1996, pp. 5-21. + + [RFC1750] Eastlake, D. (ed.), "Randomness Recommendations for + Security", RFC 1750, December 1994. + + + + + +Stewart, et al. Standards Track [Page 129] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + [RFC1950] Deutsch P. and J. Gailly, "ZLIB Compressed Data Format + Specification version 3.3", RFC 1950, May 1996. + + [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed- + Hashing for Message Authentication", RFC 2104, March 1997. + + [RFC2196] Fraser, B., "Site Security Handbook", FYI 8, RFC 2196, + September 1997. + + [RFC2522] Karn, P. and W. Simpson, "Photuris: Session-Key Management + Protocol", RFC 2522, March 1999. + + [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T., + "TCP Congestion Control with a Misbehaving Receiver", ACM + Computer Communication Review, 29(5), October 1999. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 130] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +Appendix A: Explicit Congestion Notification + + ECN (Ramakrishnan, K., Floyd, S., "Explicit Congestion Notification", + RFC 2481, January 1999) describes a proposed extension to IP that + details a method to become aware of congestion outside of datagram + loss. This is an optional feature that an implementation MAY choose + to add to SCTP. This appendix details the minor differences + implementers will need to be aware of if they choose to implement + this feature. In general RFC 2481 should be followed with the + following exceptions. + + Negotiation: + + RFC2481 details negotiation of ECN during the SYN and SYN-ACK stages + of a TCP connection. The sender of the SYN sets two bits in the TCP + flags, and the sender of the SYN-ACK sets only 1 bit. The reasoning + behind this is to assure both sides are truly ECN capable. For SCTP + this is not necessary. To indicate that an endpoint is ECN capable + an endpoint SHOULD add to the INIT and or INIT ACK chunk the TLV + reserved for ECN. This TLV contains no parameters, and thus has the + following format: + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Parameter Type = 32768 | Parameter Length = 4 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + ECN-Echo: + + RFC 2481 details a specific bit for a receiver to send back in its + TCP acknowledgements to notify the sender of the Congestion + Experienced (CE) bit having arrived from the network. For SCTP this + same indication is made by including the ECNE chunk. This chunk + contains one data element, i.e. the lowest TSN associated with the IP + datagram marked with the CE bit, and looks as follows: + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Chunk Type=12 | Flags=00000000| Chunk Length = 8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Lowest TSN Number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Note: The ECNE is considered a Control chunk. + + + + + +Stewart, et al. Standards Track [Page 131] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + CWR: + + RFC 2481 details a specific bit for a sender to send in the header of + its next outbound TCP segment to indicate to its peer that it has + reduced its congestion window. This is termed the CWR bit. For + SCTP the same indication is made by including the CWR chunk. + This chunk contains one data element, i.e. the TSN number that + was sent in the ECNE chunk. This element represents the lowest + TSN number in the datagram that was originally marked with the + CE bit. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Chunk Type=13 | Flags=00000000| Chunk Length = 8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Lowest TSN Number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Note: The CWR is considered a Control chunk. + +Appendix B Alder 32 bit checksum calculation + + The Adler-32 checksum calculation given in this appendix is copied from + [RFC1950]. + + Adler-32 is composed of two sums accumulated per byte: s1 is the sum + of all bytes, s2 is the sum of all s1 values. Both sums are done + modulo 65521. s1 is initialized to 1, s2 to zero. The Adler-32 + checksum is stored as s2*65536 + s1 in network byte order. + + The following C code computes the Adler-32 checksum of a data buffer. + It is written for clarity, not for speed. The sample code is in the + ANSI C programming language. Non C users may find it easier to read + with these hints: + + + + + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 132] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + + & Bitwise AND operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero bit(s) + at the left. + << Bitwise left shift operator. Left shift inserts zero + bit(s) at the right. + ++ "n++" increments the variable n. + % modulo operator: a % b is the remainder of a divided by b. + #define BASE 65521 /* largest prime smaller than 65536 */ + /* + Update a running Adler-32 checksum with the bytes buf[0..len-1] + and return the updated checksum. The Adler-32 checksum should be + initialized to 1. + + Usage example: + + unsigned long adler = 1L; + + while (read_buffer(buffer, length) != EOF) { + adler = update_adler32(adler, buffer, length); + } + if (adler != original_adler) error(); + */ + unsigned long update_adler32(unsigned long adler, + unsigned char *buf, int len) + { + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int n; + + for (n = 0; n < len; n++) { + s1 = (s1 + buf[n]) % BASE; + s2 = (s2 + s1) % BASE; + } + return (s2 << 16) + s1; + } + + /* Return the adler32 of the bytes buf[0..len-1] */ + unsigned long adler32(unsigned char *buf, int len) + { + return update_adler32(1L, buf, len); + } + + + + + + + + + +Stewart, et al. Standards Track [Page 133] + +RFC 2960 Stream Control Transmission Protocol October 2000 + + +Full Copyright Statement + + Copyright (C) The Internet Society (2000). 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. + + + + + + + + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 134] + diff --git a/doc/rfc3257.txt b/doc/rfc3257.txt new file mode 100644 index 0000000..c2df92b --- /dev/null +++ b/doc/rfc3257.txt @@ -0,0 +1,731 @@ + + + + + + +Network Working Group L. Coene +Request for Comments: 3257 Siemens +Category: Informational April 2002 + + + Stream Control Transmission Protocol Applicability Statement + +Status of this Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2002). All Rights Reserved. + +Abstract + + This document describes the applicability of the Stream Control + Transmission Protocol (SCTP). It also contrasts SCTP with the two + dominant transport protocols, User Datagram Protocol (UDP) & + Transmission Control Protocol (TCP), and gives some guidelines for + when best to use SCTP and when not best to use SCTP. + +Table of contents + + 1. Introduction .................................................. 2 + 1.1 Terminology .................................................. 2 + 2 Transport protocols ............................................ 2 + 2.1 TCP service model ............................................ 2 + 2.2 SCTP service model ........................................... 3 + 2.3 UDP service model ............................................ 4 + 3 SCTP Multihoming issues ........................................ 4 + 4 SCTP Network Address Translators (NAT) issues [RFC2663] ........ 5 + 5 Security Considerations ........................................ 6 + 5.1 Security issues with TCP ..................................... 6 + 5.2 Security issues with SCTP .................................... 7 + 5.3 Security issues with both TCP and SCTP ....................... 8 + 6 References and related work .................................... 9 + 7 Acknowledgments ................................................ 10 + Appendix A: Major functions provided by SCTP ..................... 11 + Editor's Address ................................................. 12 + Full Copyright Statement ......................................... 13 + + + + + + + +Coene Informational [Page 1] + +RFC 3257 SCTP Applicability Statement April 2002 + + +1 Introduction + + SCTP is a reliable transport protocol [RFC2960], which along with TCP + [RFC793], RTP [RFC1889], and UDP [RFC768], provides transport-layer + services for upper layer protocols and services. UDP, RTP, TCP, and + SCTP are currently the IETF standards-track transport-layer + protocols. Each protocol has a domain of applicability and services + it provides, albeit with some overlaps. + + By clarifying the situations where the functionality of these + protocols are applicable, this document can guide implementers and + protocol designers in selecting which protocol to use. + + Special attention is given to services SCTP provides which would make + a decision to use SCTP the right one. + + Major functions provided by SCTP can be found in Appendix A. + +1.1 Terminology + + The following terms are commonly identified in this work: + + Association: SCTP connection between two endpoints. + + Transport address: A combination of IP address and SCTP port number. + + Upper layer: The user of the SCTP protocol, which may be an + adaptation layer, a session layer protocol, or the user application + directly. + + Multihoming: Assigning more than one IP network interface to a single + endpoint. + +2 Transport protocols + +2.1 TCP service model + + TCP is a connection-oriented (a.k.a., session-oriented) transport + protocol. This means that it requires both the establishment of a + connection prior to the exchange of application data and a connection + tear-down to release system resources after the completion of data + transfer. + + TCP is currently the most widely used connection-oriented transport + protocol for the Internet. + + + + + + +Coene Informational [Page 2] + +RFC 3257 SCTP Applicability Statement April 2002 + + + TCP provides the upper layer with the following transport services: + + - data reliability; + + - data sequence preservation; and + + - flow and congestion control. + +2.2 SCTP service model + + SCTP is also connection-oriented and provides all the transport + services that TCP provides. Many Internet applications therefore + should find that either TCP or SCTP will meet their transport + requirements. Note, for applications conscious about processing + cost, there might be a difference in processing cost associated with + running SCTP with only a single ordered stream and one address pair + in comparison to running TCP. + + However, SCTP has some additional capabilities that TCP lacks and + This can make SCTP a better choice for some applications and + environments: + + - multi-streams support: + + SCTP supports the delivery of multiple independent user message + streams within a single SCTP association. This capability, when + properly used, can alleviate the so-called head-of-line-blocking + problem caused by the strict sequence delivery constraint imposed to + the user data by TCP. + + This can be particularly useful for applications that need to + exchange multiple, logically separate message streams between two + endpoints. + + - multi-homing support: + + SCTP provides transparent support for communications between two + endpoints of which one or both is multi-homed. + + SCTP provides monitoring of the reachability of the addresses on the + remote endpoint and in the case of failure can transparently failover + from the primary address to an alternate address, without upper layer + intervention. + + + + + + + + +Coene Informational [Page 3] + +RFC 3257 SCTP Applicability Statement April 2002 + + + This capability can be used to build redundant paths between two SCTP + endpoints and can be particularly useful for applications that seek + transport-level fault tolerance. + + Achieving path redundancy between two SCTP endpoints normally + requires that the two endpoints being equipped with multiple + interfaces assigned with multiple addresses and that routing is + configured appropriately (see Section 3). + + - preservation of message boundaries: + + SCTP preserves application messages boundaries. This is useful when + the application data is not a continuous byte stream but comes in + logical chunks that the receiver handles separately. + + In contrast, TCP offers a reliable data stream that has no indication + of what an application may consider logical chunks of the data. + + - unordered reliable message delivery: + + SCTP supports the transportation of user messages that have no + application-specified order, yet need guaranteed reliable delivery. + + Applications that need to send un-ordered reliable messages or prefer + using their own message sequencing and ordering mechanisms may find + this SCTP capability useful. + +2.3 UDP Service model + + UDP is connectionless. This means that applications that use UDP do + not need to perform connection establishment or tear-down. + + As transport services to its upper layer, UDP provides only: + + - best-effort data delivery, and + + - preservation of message boundaries. + + Applications that do not require a reliable transfer of more than a + packet's worth of data will find UDP adequate. Some transaction- + based applications fall into this category. + +3 SCTP Multihoming Issues + + SCTP provides transport-layer support for multihoming. Multihoming + has the potential of providing additional robustness against network + failures. In some applications, this may be extremely important, for + example, in signaling transport of PSTN signaling messages [RFC2719]. + + + +Coene Informational [Page 4] + +RFC 3257 SCTP Applicability Statement April 2002 + + + It should be noted that SCTP multihoming support only deals with + communication between two endpoints of which one or both is assigned + with multiple IP addresses on possibly multiple network interfaces. + It does NOT deal with communication ends that contain multiple + endpoints (i.e., clustered endpoints) that can switch over to an + alternate endpoint in case of failure of the original endpoint. + + Generally, for truly fault resilient communication between two end- + points, the multihoming feature needs more than one IP network + interface for each endpoint. The number of paths used is the minimum + of network interfaces used by any of the endpoints. When an endpoint + selects its source address, careful consideration must be taken. If + the same source address is always used, then it is possible that the + endpoint will be subject to the same single point of failure. When + the endpoint chooses a source address, it should always select the + source address of the packet to correspond to the IP address of the + Network interface where the packet will be emitted subject to the + binding address constraint. The binding address constraint is, put + simply, that the endpoint must never choose a source address that is + not part of the association i.e., the peer endpoint must recognize + any source address used as being part of the association. + + The availability of the association will benefit greatly from having + multiple addresses bound to the association endpoint when the + endpoint is on a multi-homed host. + +4 SCTP Network Address Translators (NAT) issues [RFC2663] + + When two endpoints are to setup an SCTP association and one (or both) + of them is behind a NAT (i.e., it does not have any publicly + available network addresses), the endpoint(s) behind the NAT should + consider one of the following options: + + (1) When single homed sessions are to be used, no transport addresses + should be sent in the INIT or INIT ACK chunk(Refer to section 3.3 of + RFC2960 for chunk definitions). This will force the endpoint that + receives this initiation message to use the source address in the IP + header as the only destination address for this association. This + method can be used for a NAT, but any multi-homing configuration at + the endpoint that is behind the NAT will not be visible to its peer, + and thus not be taken advantage of. See figure 1. + + + + + + + + + + +Coene Informational [Page 5] + +RFC 3257 SCTP Applicability Statement April 2002 + + + +-------+ +---------+ *~~~~~~~~~~* +------+ + |Host A | | NAT | * Cloud * |Host B| + | 10.2 +--|10.1|2.1 |----|--------------|---------+ 1.2 | + | | | | | * * | | + +-------+ +---------+ *~~~~~~~~~~* +------+ + + Fig 1: SCTP through NAT without multihoming + + For multihoming the NAT must have a public IP address for each + represented internal IP address. The host can preconfigure an IP + address that the NAT can substitute, or, the NAT can have internal + Application Layer Gateway (ALG) which will intelligently translate + the IP addresses in the INIT and INIT ACK chunks. See Figure 2. + + If Network Address Port Translation is used with a multihomed SCTP + endpoint, then any port translation must be applied on a per- + association basis such that an SCTP endpoint continues to receive the + same port number for all messages within a given association. + + +-------+ +----------+ *~~~~~~~~~~* +------+ + |Host A | | NAT | * Cloud * |Host B| + | 10.2 +---+ 10.1|5.2 +-----+ 1.1<+->3.1--+---------+ 1.2 | + | 11.2 +---+ 11.1|6.2 | | +->4.2--+---------+ 2.2 | + | | | | * * | | + +-------+ +----------+ *~~~~~~~~~* +------+ + + Fig 2: SCTP through NAT with multihoming + + (2) Another alternative is to use the hostname feature and DNS to + resolve the addresses. The hostname is included in the INIT of the + association or in the INIT ACK. The hostname must be resolved by DNS + before the association is completely set up. There are special + issues regarding NAT and DNS, refer to RFC2694 for details. + +5 Security Considerations + + In this section, some relevant security issues found in the + deployment of the connection-oriented transport protocols will be + discussed. + +5.1 Security issues with TCP + + Some TCP implementations have been known to be vulnerable to blind + denial of service attacks, i.e., attacks that had been executed by an + attacker that could not see most of the traffic to or from the target + host. + + + + + +Coene Informational [Page 6] + +RFC 3257 SCTP Applicability Statement April 2002 + + + The attacker would send a large number of connection establishment + requests (TCP-SYN packets) to the attacked target, possibly from + faked IP source addresses. The attacked host would reply by sending + SYN-ACK packets and entering SYN-received state, thereby allocating + space for a TCB. At some point the SYN-queue would fill up, (i.e., + the number of connections waiting to be established would rise to a + limit) and the host under attack would have to start turning down new + connection establishment requests. + + TCP implementations with SYN-cookies algorithm [SYN-COOK] reduce the + risk of such blind denial of service attacks. TCP implementations + can switch to using this algorithm in times when their SYN-queues are + filled up while still fully conforming to the TCP specification + [RFC793]. However, use of options such as a window scale [RFC1323], + is not possible, then. With the SYN-cookie mechanism, a TCB is only + created when the client sends back a valid ACK packet to the server, + and the 3-way handshake has thus been successfully completed. + + Blind connection forgery is another potential threat to TCP. By + guessing valid sequence numbers, an attacker would be able to forge a + connection. However, with a secure hashsum algorithm, for some of + the current SYN-cookie implementations the likelihood of achieving + this attack is on the order of magnitude of 1 in 2^24, i.e., the + attacker would have to send 2^24 packets before obtaining one forged + connection when SYN-cookies are used. + +5.2 Security issues with SCTP + + SCTP has been designed with the experiences made with TCP in mind. + To make it hard for blind attackers (i.e., attackers that are not + man-in-the-middle) to inject forged SCTP datagrams into existing + associations, each side of an SCTP association uses a 32 bit value + called "Verification Tag" to ensure that a datagram really belongs to + the existing association. So in addition to a combination of source + and destination transport addresses that belong to an established + association, a valid SCTP datagram must also have the correct tag to + be accepted by the recipient. + + Unlike in TCP, usage of cookie in association establishment is made + mandatory in SCTP. For the server, a new association is fully + established after three messages (containing INIT, INIT-ACK, COOKIE- + ECHO chunks) have been exchanged. The cookie is a variable length + parameter that contains all relevant data to initialize the TCB on + the server side, plus a HMAC used to secure it. This HMAC (MD5 as + per [RFC1321] or SHA-1 [SHA1]) is computed over the cookie and a + secret, server-owned key. + + + + + +Coene Informational [Page 7] + +RFC 3257 SCTP Applicability Statement April 2002 + + + As specifically prescribed for SCTP implementations [RFC2960], + additional resources for new associations may only be reserved in + case a valid COOKIE-ECHO chunk is received by a client, and the + computed HMAC for this new cookie matches that contained in the + cookie. + + With SCTP the chances of an attacker being able to blindly forge a + connection are even lower than in the case of TCP using SYN-cookies, + since the attacker would have to guess a correct value for the HMAC + contained in the cookie, i.e., lower than 1 in 2^128 which for all + practical purposes is negligible. + + It should be noted that SCTP only tries to increase the availability + of a network. SCTP does not contain any protocol mechanisms that are + directly related to user message authentication, integrity and + confidentiality functions. For such features, it depends on the + IPsec protocols and architecture and/or on security features of the + application protocols. + + Transport Layer security(TLS)[RFC2246] using SCTP must always use + in-order streams. + + Currently the IPSEC working group is investigating the support of + multi-homing by IPSEC protocols. At the present time to use IPSEC, + one must use 2 * N * M security associations if one endpoint uses N + addresses and the other M addresses. + +5.3 Security Issues with both TCP and SCTP + + It is important to note that neither TCP nor SCTP protect itself from + man-in-the-middle attacks where an established session might be + hijacked (assuming the attacker can see the traffic from and inject + its own packets to either endpoints). + + Also, to prevent blind connection/session setup forgery, both TCP + implementations supporting SYN-cookies and SCTP implementations rely + on a server-known, secret key to protect the HMAC data. It must be + ensured that this key is created subject to the recommendations + mentioned in [RFC1750]. + + Although SCTP has been designed carefully as to avoid some of the + problems that have appeared with TCP, it has as of yet not been + widely deployed. It is therefore possible that new security issues + will be identified that will have to be addressed in further + revisions of [RFC2960]. + + + + + + +Coene Informational [Page 8] + +RFC 3257 SCTP Applicability Statement April 2002 + + +6 References and related work + + [RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C., + Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M., + Zhang, L. and V. Paxson, "Stream Control Transmission + Protocol", RFC 2960, October 2000. + + [RFC2401] Kent, S. and R. Atkinson, "Security Architecture for the + Internet Protocol", RFC 2401, November 1998. + + [RFC2663] Srisuresh, P. and M. Holdrege, "IP Network Address + Translator (NAT) Terminology and Considerations", RFC + 2663, August 1999. + + [RFC2694] Srisuresh, P., Tsirtsis, G., Akkiraju, P. and A. + Heffernan, "DNS extensions to Network Address Translators + (DNS_ALG)", RFC 2694, September 1999. + + [RFC768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, + August 1980. + + [RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC + 793, September 1981. + + [RFC2719] Ong, L., Rytina, I., Garcia, M., Schwarzbauer, H., Coene, + L., Lin, H., Juhasz, I., Holdrege, M. and C. Sharp, + "Architectural Framework for Signaling Transport", RFC + 2719, October 1999. + + [RFC1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, + April 1992. + + [RFC1323] Jacobson, V., Braden, R. and D. Borman, "TCP Extensions + for High Performance", RFC 1323, May 1992. + + [RFC1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness + Recommendations for Security", RFC 1750, December 1994. + + [SHA1] NIST FIPS PUB 180-1, "Secure Hash Standard," National + Institute of Standards and Technology, U.S. Department of + Commerce, April 1995. + + [SYNCOOK] Dan J. Bernstein, SYN cookies, 1997, see also + + + [RFC2246] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", + RFC 2246, January 1999. + + + + +Coene Informational [Page 9] + +RFC 3257 SCTP Applicability Statement April 2002 + + + [RFC1889] Schulzrinne, H., Casner, S., Frederick, R. and V. + Jacobson, "RTP: A Transport Protocol for Real-Time + Applications", RFC 1889, January 1996. + +7 Acknowledgments + + This document was initially developed by a design team consisting of + Lode Coene, John Loughney, Michel Tuexen, Randall R. Stewart, + Qiaobing Xie, Matt Holdrege, Maria-Carmen Belinchon, Andreas + Jungmaier, Gery Verwimp and Lyndon Ong. + + The authors wish to thank Renee Revis, I. Rytina, H.J. Schwarzbauer, + J.P. Martin-Flatin, T. Taylor, G. Sidebottom, K. Morneault, T. + George, M. Stillman, N. Makinae, S. Bradner, A. Mankin, G. Camarillo, + H. Schulzrinne, R. Kantola, J. Rosenberg, R.J. Atkinson, and many + others for their invaluable comments. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Coene Informational [Page 10] + +RFC 3257 SCTP Applicability Statement April 2002 + + +Appendix A: Major functions provided by SCTP + + - Reliable Data Transfer + + - Multiple streams to help avoid head-of-line blocking + + - Ordered and unordered data delivery on a per-stream basis + + - Bundling and fragmentation of user data + + - TCP friendly Congestion and flow control + + - Support continuous monitoring of reachability + + - Graceful termination of association + + - Support of multi-homing for added reliability + + - Some protection against blind denial-of-service attacks + + - Some protection against blind masquerade attacks + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Coene Informational [Page 11] + +RFC 3257 SCTP Applicability Statement April 2002 + + +8 Editor's Address + + Lode Coene + Siemens Atea + Atealaan 34 + B-2200 Herentals + Belgium + + Phone: +32-14-252081 + EMail: lode.coene@siemens.atea.be + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Coene Informational [Page 12] + +RFC 3257 SCTP Applicability Statement April 2002 + + +9. 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 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. + + + + + + + + + + + + + + + + + + + +Coene Informational [Page 13] + diff --git a/doc/rfc3286.txt b/doc/rfc3286.txt new file mode 100644 index 0000000..aa446a4 --- /dev/null +++ b/doc/rfc3286.txt @@ -0,0 +1,563 @@ + + + + + + +Network Working Group L. Ong +Request for Comments: 3286 Ciena Corporation +Category: Informational J. Yoakum + Nortel Networks + May 2002 + + + An Introduction to the Stream Control Transmission Protocol (SCTP) + +Status of this Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2002). All Rights Reserved. + +Abstract + + This document provides a high level introduction to the capabilities + supported by the Stream Control Transmission Protocol (SCTP). It is + intended as a guide for potential users of SCTP as a general purpose + transport protocol. + +1. Introduction + + The Stream Control Transmission Protocol (SCTP) is a new IP transport + protocol, existing at an equivalent level with UDP (User Datagram + Protocol) and TCP (Transmission Control Protocol), which provide + transport layer functions to many Internet applications. SCTP has + been approved by the IETF as a Proposed Standard [1]. The error + check algorithm has since been modified [2]. Future changes and + updates will be reflected in the IETF RFC index. + + Like TCP, SCTP provides a reliable transport service, ensuring that + data is transported across the network without error and in sequence. + Like TCP, SCTP is a session-oriented mechanism, meaning that a + relationship is created between the endpoints of an SCTP association + prior to data being transmitted, and this relationship is maintained + until all data transmission has been successfully completed. + + Unlike TCP, SCTP provides a number of functions that are critical for + telephony signaling transport, and at the same time can potentially + benefit other applications needing transport with additional + performance and reliability. The original framework for the SCTP + definition is described in [3]. + + + +Ong & Yoakum Informational [Page 1] + +RFC 3286 SCTP Overview May 2002 + + +2. Basic SCTP Features + + SCTP is a unicast protocol, and supports data exchange between + exactly 2 endpoints, although these may be represented by multiple IP + addresses. + + SCTP provides reliable transmission, detecting when data is + discarded, reordered, duplicated or corrupted, and retransmitting + damaged data as necessary. SCTP transmission is full duplex. + + SCTP is message oriented and supports framing of individual message + boundaries. In comparison, TCP is byte oriented and does not + preserve any implicit structure within a transmitted byte stream + without enhancement. + + SCTP is rate adaptive similar to TCP, and will scale back data + transfer to the prevailing load conditions in the network. It is + designed to behave cooperatively with TCP sessions attempting to use + the same bandwidth. + +3. SCTP Multi-Streaming Feature + + The name Stream Control Transmission Protocol is derived from the + multi-streaming function provided by SCTP. This feature allows data + to be partitioned into multiple streams that have the property of + independently sequenced delivery, so that message loss in any one + stream will only initially affect delivery within that stream, and + not delivery in other streams. + + In contrast, TCP assumes a single stream of data and ensures that + delivery of that stream takes place with byte sequence preservation. + While this is desirable for delivery of a file or record, it causes + additional delay when message loss or sequence error occurs within + the network. When this happens, TCP must delay delivery of data + until the correct sequencing is restored, either by receipt of an + out-of-sequence message, or by retransmission of a lost message. + + For a number of applications, the characteristic of strict sequence + preservation is not truly necessary. In telephony signaling, it is + only necessary to maintain sequencing of messages that affect the + same resource (e.g., the same call, or the same channel). Other + messages are only loosely correlated and can be delivered without + having to maintain overall sequence integrity. + + Another example of possible use of multi-streaming is the delivery of + multimedia documents, such as a web page, when done over a single + session. Since multimedia documents consist of objects of different + sizes and types, multi-streaming allows transport of these components + + + +Ong & Yoakum Informational [Page 2] + +RFC 3286 SCTP Overview May 2002 + + + to be partially ordered rather than strictly ordered, and may result + in improved user perception of transport. + + At the same time, transport is done within a single SCTP association, + so that all streams are subjected to a common flow and congestion + control mechanism, reducing the overhead required at the transport + level. + + SCTP accomplishes multi-streaming by creating independence between + data transmission and data delivery. In particular, each payload + DATA "chunk" in the protocol uses two sets of sequence numbers, a + Transmission Sequence Number that governs the transmission of + messages and the detection of message loss, and the Stream ID/Stream + Sequence Number pair, which is used to determine the sequence of + delivery of received data. + + This independence of mechanisms allows the receiver to determine + immediately when a gap in the transmission sequence occurs (e.g., due + to message loss), and also whether or not messages received following + the gap are within an affected stream. If a message is received + within the affected stream, there will be a corresponding gap in the + Stream Sequence Number, while messages from other streams will not + show a gap. The receiver can therefore continue to deliver messages + to the unaffected streams while buffering messages in the affected + stream until retransmission occurs. + +4. SCTP Multi-Homing Feature + + Another core feature of SCTP is multi-homing, or the ability for a + single SCTP endpoint to support multiple IP addresses. The benefit + of multi-homing is potentially greater survivability of the session + in the presence of network failures. In a conventional single-homed + session, the failure of a local LAN access can isolate the end + system, while failures within the core network can cause temporary + unavailability of transport until the IP routing protocols can + reconverge around the point of failure. Using multi-homed SCTP, + redundant LANs can be used to reinforce the local access, while + various options are possible in the core network to reduce the + dependency of failures for different addresses. Use of addresses + with different prefixes can force routing to go through different + carriers, for example, route-pinning techniques or even redundant + core networks can also be used if there is control over the network + architecture and protocols. + + In its current form, SCTP does not do load sharing, that is, multi- + homing is used for redundancy purposes only. A single address is + chosen as the "primary" address and is used as the destination for + all DATA chunks for normal transmission. Retransmitted DATA chunks + + + +Ong & Yoakum Informational [Page 3] + +RFC 3286 SCTP Overview May 2002 + + + use the alternate address(es) to improve the probability of reaching + the remote endpoint, while continued failure to send to the primary + address ultimately results in the decision to transmit all DATA + chunks to the alternate until heartbeats can reestablish the + reachability of the primary. + + To support multi-homing, SCTP endpoints exchange lists of addresses + during initiation of the association. Each endpoint must be able to + receive messages from any of the addresses associated with the remote + endpoint; in practice, certain operating systems may utilize + available source addresses in round robin fashion, in which case + receipt of messages from different source addresses will be the + normal case. A single port number is used across the entire address + list at an endpoint for a specific session. + + In order to reduce the potential for security issues, it is required + that some response messages be sent specifically to the source + address in the message that caused the response. For example, when + the server receives an INIT chunk from a client to initiate an SCTP + association, the server always sends the response INIT ACK chunk to + the source address that was in the IP header of the INIT. + +5. Features of the SCTP Initiation Procedure + + The SCTP Initiation Procedure relies on a 4-message sequence, where + DATA can be included on the 3rd and 4th messages of the sequence, as + these messages are sent when the association has already been + validated. A "cookie" mechanism has been incorporated into the + sequence to guard against some types of denial of service attacks. + +5.1 Cookie Mechanism + + The "cookie" mechanism guards specifically against a blind attacker + generating INIT chunks to try to overload the resources of an SCTP + server by causing it to use up memory and resources handling new INIT + requests. Rather than allocating memory for a Transmission Control + Block (TCB), the server instead creates a Cookie parameter with the + TCB information, together with a valid lifetime and a signature for + authentication, and sends this back in the INIT ACK. Since the INIT + ACK always goes back to the source address of the INIT, the blind + attacker will not get the Cookie. A valid SCTP client will get the + Cookie and return it in the COOKIE ECHO chunk, where the SCTP server + can validate the Cookie and use it to rebuild the TCB. Since the + server creates the Cookie, only it needs to know the format and + secret key, this is not exchanged with the client. + + + + + + +Ong & Yoakum Informational [Page 4] + +RFC 3286 SCTP Overview May 2002 + + + Otherwise, the SCTP Initiation Procedure follows many TCP + conventions, so that the endpoints exchange receiver windows, initial + sequence numbers, etc. In addition to this, the endpoints may + exchange address lists as discussed above, and also mutually confirm + the number of streams to be opened on each side. + +5.2 INIT Collision Resolution + + Multi-homing adds to the potential that messages will be received out + of sequence or with different address pairs. This is a particular + concern during initiation of the association, where without + procedures for resolving the collision of messages, you may easily + end up with multiple parallel associations between the same + endpoints. To avoid this, SCTP incorporates a number of procedures + to resolve parallel initiation attempts into a single association. + +6. SCTP DATA Exchange Features + + DATA chunk exchange in SCTP follows TCP's Selective ACK procedure. + Receipt of DATA chunks is acknowledged by sending SACK chunks, which + indicate not only the cumulative Transmission Sequence Number (TSN) + range received, but also any non-cumulative TSNs, implying gaps in + the received TSN sequence. Following TCP procedures, SACKs are sent + using the "delayed ack" method, normally one SACK per every other + received packet, but with an upper limit on the delay between SACKs + and an increase to once per received packet when there are gaps + detected. + + Flow and Congestion Control follow TCP algorithms. The advertised + receive window indicates buffer occupancy at the receiver, while a + per-path congestion window is maintained to manage the packets in + flight. Slow start, Congestion avoidance, Fast recovery and Fast + retransmit are incorporated into the procedures as described in RFC + 2581, with the one change being that the endpoints must manage the + conversion between bytes sent and received and TSNs sent and + received, since TSN is per chunk rather than per byte. + + The application can specify a lifetime for data to be transmitted, so + that if the lifetime has expired and the data has not yet been + transmitted, it can be discarded (e.g., time-sensitive signaling + messages). If the data has been transmitted, it must continue to be + delivered to avoid creating a hole in the TSN sequence. + + + + + + + + + +Ong & Yoakum Informational [Page 5] + +RFC 3286 SCTP Overview May 2002 + + +7. SCTP Shutdown Features + + SCTP Shutdown uses a 3-message procedure to allow graceful shutdown, + where each endpoint has confirmation of the DATA chunks received by + the remote endpoint prior to completion of the shutdown. An Abort + procedure is also provided for error cases when an immediate shutdown + must take place. + + Note that SCTP does not support the function of a "half-open" + connection as can occur in TCP, when one side indicates that it has + no more data to send, but the other side can continue to send data + indefinitely. SCTP assumes that once the shutdown procedure begins, + both sides will stop sending new data across the association, and + only need to clear up acknowledgements of previously sent data. + +8. SCTP Message Format + + The SCTP Message includes a common header plus one or more chunks, + which can be control or data. The common header has source and + destination port numbers to allow multiplexing of different SCTP + associations at the same address, a 32-bit verification tag that + guards against insertion of an out-of-date or false message into the + SCTP association, and a 32-bit checksum (this has been modified to + use the CRC-32c polynomial [2]) for error detection. + + Each chunk includes chunk type, flag field, length and value. + Control chunks incorporate different flags and parameters depending + on the chunk type. DATA chunks in particular incorporate flags for + control of segmentation and reassembly, and parameters for the TSN, + Stream ID and Stream Sequence Number, and a Payload Protocol + Identifier. + + The Payload Protocol ID has been included for future flexibility. It + is envisioned that the functions of protocol identification and port + number multiplexing will not be as closely linked in the future as + they are in current usage. Payload Protocol ID will allow the + protocol being carried by SCTP to be identified independent of the + port numbers being used. + + The SCTP message format naturally allows support of bundling of + multiple DATA and control chunks in a single message, to improve + transport efficiency. Use of bundling is controllable by the + application, so that bundling of initial transmission can be + prohibited. Bundling will naturally occur on retransmission of DATA + chunks, to further reduce any chance of congestion. + + + + + + +Ong & Yoakum Informational [Page 6] + +RFC 3286 SCTP Overview May 2002 + + +9. Error Handling + +9.1 Retransmission + + Retransmission of DATA chunks occurs from either (a) timeout of the + retransmission timer; or (b) receipt of SACKs indicating the DATA + chunk has not been received. To reduce the potential for congestion, + the rate of retransmission of DATA chunks is limited. The + retransmission timeout (RTO) is adjusted based on estimates of the + round trip delay and backs off exponentially as message loss + increases. + + In an active association with fairly constant DATA transmission, + SACKs are more likely to cause retransmission than the timeout. To + reduce the chance of an unnecessary retransmission, a 4 SACK rule is + used, so that retransmission only occurs on receipt of the 4th SACK + that indicates that the chunk is missing. This is intended to avoid + retransmits due to normal occurrences such as packets received out of + sequence. + +9.2 Path Failure + + A count is maintained of the number of retransmissions to a + particular destination address without successful acknowledgement. + When this count exceeds a configured maximum, the address is declared + inactive, notification is given to the application, and the SCTP + begins to use an alternate address for the sending of DATA chunks. + + Also, Heartbeat chunks are sent periodically to all idle destinations + (i.e., alternate addresses), and a counter is maintained on the + number of Heartbeats sent to an inactive destination without receipt + of a corresponding Heartbeat Ack. When this counter exceeds a + configured maximum, that destination address is also declared + inactive. + + Heartbeats continue to be sent to inactive destination addresses + until an Ack is received, at which point the address can be made + active again. The rate of sending Heartbeats is tied to the RTO + estimation plus an additional delay parameter that allows Heartbeat + traffic to be tailored according to the needs of the user + application. + +9.3 Endpoint Failure + + A count is maintained across all destination addresses on the number + of retransmits or Heartbeats sent to the remote endpoint without a + successful Ack. When this exceeds a configured maximum, the endpoint + is declared unreachable, and the SCTP association is closed. + + + +Ong & Yoakum Informational [Page 7] + +RFC 3286 SCTP Overview May 2002 + + +10. API + + The specification includes a model of the primitives exchanged + between the application and the SCTP layer, intended as informational + material rather than a formal API statement. A socket-based API is + being defined to simplify migration of TCP or UDP applications to the + use of SCTP. + +11. Security Considerations + + In addition to the verification tag and cookie mechanisms, SCTP + specifies the use of IPSec if strong security and integrity + protection is required. The SCTP specification does not itself + define any new security protocols or procedures. + + Extensions to IPSec are under discussion to reduce the overhead + required to support multi-homing. Also, work is in progress on the + use of Transport Layer Security (TLS) over SCTP [4]. + +12. Extensions + + The SCTP format allows new chunk types, flags and parameter fields to + be defined as extensions to the protocol. Any extensions must be + based on standard agreements within the IETF, as no vendor-specific + extensions are supported in the protocol. + + Chunk Type values are organized into four ranges to allow extensions + to be made with a pre-defined procedure for responding if a new Chunk + Type is not recognized at the remote endpoint. Responses include: + whole packet discard; packet discard with reporting; ignoring the + chunk; ignoring with reporting. Similar pre-defined responses are + specified for unrecognized Parameter Type values. + + Chunk Parameter Type values are in principle independent ranges for + each Chunk Type. In practice, the values defined in the SCTP + specification have been coordinated so that a particular parameter + type will have the same Chunk Parameter Type value across all Chunk + Types. Further experience will determine if this alignment needs to + be maintained or formalized. + + + + + + + + + + + + +Ong & Yoakum Informational [Page 8] + +RFC 3286 SCTP Overview May 2002 + + +13. Informative References + + [1] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer, H., + Taylor, T., Rytina, I., Kalla, M., Zhang, L. and V. Paxson, + "Stream Control Transmission Protocol", RFC 2960, October 2000. + + [2] Stewart, Sharp, et. al., "SCTP Checksum Change", Work in + Progress. + + [3] Ong, L., Rytina, I., Garcia, M., Schwarzbauer, H., Coene, L., + Lin, H., Juhasz, I., Holdrege, M. and C. Sharp, "Framework + Architecture for Signaling Transport", RFC 2719, October 1999. + + [4] Jungmeier, Rescorla and Tuexen, "TLS Over SCTP", Work in + Progress. + +14. Authors' Addresses + + Lyndon Ong + Ciena Corporation + 10480 Ridgeview Drive + Cupertino, CA 95014 + + EMail: lyong@ciena.com + + + John Yoakum + Emerging Opportunities + Nortel Networks + + EMail: yoakum@nortelnetworks.com + + + + + + + + + + + + + + + + + + + + +Ong & Yoakum Informational [Page 9] + +RFC 3286 SCTP Overview May 2002 + + +15. 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 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. + + + + + + + + + + + + + + + + + + + +Ong & Yoakum Informational [Page 10] + diff --git a/doc/rfc3309.txt b/doc/rfc3309.txt new file mode 100644 index 0000000..494fee1 --- /dev/null +++ b/doc/rfc3309.txt @@ -0,0 +1,955 @@ + + + + + + +Network Working Group J. Stone +Request for Comments: 3309 Stanford +Updates: 2960 R. Stewart +Category: Standards Cisco Systems + D. Otis + SANlight + September 2002 + + + Stream Control Transmission Protocol (SCTP) Checksum Change + +Status of this Memo + + This document specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" (STD 1) for the standardization state + and status of this protocol. Distribution of this memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2002). All Rights Reserved. + +Abstract + + Stream Control Transmission Protocol (SCTP) currently uses an Adler- + 32 checksum. For small packets Adler-32 provides weak detection of + errors. This document changes that checksum and updates SCTP to use + a 32 bit CRC checksum. + +Table of Contents + + 1 Introduction ................................................... 2 + 2 Checksum Procedures ............................................ 3 + 3 Security Considerations......................................... 6 + 4 IANA Considerations............................................. 6 + 5 Acknowledgments ................................................ 6 + 6 References ..................................................... 7 + Appendix ......................................................... 9 + Authors' Addresses ............................................... 16 + Full Copyright Statement ......................................... 17 + + + + + + + + + + +Stone, et. al. Standards Track [Page 1] + +RFC 3309 SCTP Checksum Change September 2002 + + +1 Introduction + + A fundamental weakness has been detected in SCTP's current Adler-32 + checksum algorithm [STONE]. This document updates and replaces the + Adler-32 checksum definition in [RFC 2960]. Note that there is no + graceful transition mechanism for migrating to the new checksum. + Implementations are expected to immediately switch to the new + algorithm; use of the old algorithm is deprecated. + + One requirement of an effective checksum is that it evenly and + smoothly spreads its input packets over the available check bits. + + From an email from Jonathan Stone, who analyzed the Adler-32 as part + of his doctoral thesis: + + "Briefly, the problem is that, for very short packets, Adler32 is + guaranteed to give poor coverage of the available bits. Don't take + my word for it, ask Mark Adler. :-) + + Adler-32 uses two 16-bit counters, s1 and s2. s1 is the sum of the + input, taken as 8-bit bytes. s2 is a running sum of each value of + s1. Both s1 and s2 are computed mod-65521 (the largest prime less + than 2^16). Consider a packet of 128 bytes. The *most* that each + byte can be is 255. There are only 128 bytes of input, so the + greatest value which the s1 accumulator can have is 255 * 128 = + 32640. So, for 128-byte packets, s1 never wraps. That is critical. + Why? + + The key is to consider the distribution of the s1 values, over some + distribution of the values of the individual input bytes in each + packet. Because s1 never wraps, s1 is simply the sum of the + individual input bytes. (Even Doug's trick of adding 0x5555 doesn't + help here, and an even larger value doesn't really help: we can get + at most one mod-65521 reduction.) + + Given the further assumption that the input bytes are drawn + independently from some distribution (they probably aren't: for file + system data, it's even worse than that!), the Central Limit Theorem + tells us that that s1 will tend to have a normal distribution. + That's bad: it tells us that the value of s1 will have hot-spots at + around 128 times the mean of the input distribution: around 16k, + assuming a uniform distribution. That's bad. We want the + accumulator to wrap as many times as possible, so that the resulting + sum has as close to a uniform distribution as possible. (I call this + "fairness".) + + + + + + +Stone, et. al. Standards Track [Page 2] + +RFC 3309 SCTP Checksum Change September 2002 + + + So, for short packets, the Adler-32 s1 sum is guaranteed to be + unfair. Why is that bad? It's bad because the space of valid + packets -- input data, plus checksum values -- is also small. If all + packets have checksum values very close to 32640, then the likelihood + of even a 'small' error leaving a damaged packet with a valid + checksum is higher than if all checksum values are equally likely." + + Due to this inherent weakness, exacerbated by the fact that SCTP will + first be used as a signaling transport protocol where signaling + messages are usually less than 128 bytes, a new checksum algorithm is + specified by this document, replacing the current Adler-32 algorithm + with CRC-32c. + +1.1 Conventions + + The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, + SHOULD,SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, + when they appear in this document, are to be interpreted as described + in [RFC2119]. + + Bit number order is defined in [RFC1700]. + +2 Checksum Procedures + + The procedures described in section 2.1 of this document MUST be + followed, replacing the current checksum defined in [RFC2960]. + + Furthermore any references within [RFC2960] to Adler-32 MUST be + treated as a reference to CRC-32c. Section 2.1 of this document + describes the new calculation and verification procedures that MUST + be followed. + +2.1 Checksum Calculation + + When sending an SCTP packet, the endpoint MUST strengthen the data + integrity of the transmission by including the CRC-32c checksum value + calculated on the packet, as described below. + + After the packet is constructed (containing the SCTP common header + and one or more control or DATA chunks), the transmitter shall: + + 1) Fill in the proper Verification Tag in the SCTP common header and + initialize the Checksum field to 0's. + + 2) Calculate the CRC-32c of the whole packet, including the SCTP + common header and all the chunks. + + + + + +Stone, et. al. Standards Track [Page 3] + +RFC 3309 SCTP Checksum Change September 2002 + + + 3) Put the resulting value into the Checksum field in the common + header, and leave the rest of the bits unchanged. + + When an SCTP packet is received, the receiver MUST first check the + CRC-32c checksum: + + 1) Store the received CRC-32c value, + + 2) Replace the 32 bits of the Checksum field in the received SCTP + packet with all '0's and calculate a CRC-32c value of the whole + received packet. And, + + 3) Verify that the calculated CRC-32c value is the same as the + received CRC-32c value. If not, the receiver MUST treat the + packet as an invalid SCTP packet. + + The default procedure for handling invalid SCTP packets is to + silently discard them. + + Any hardware implementation SHOULD be done in a way that is + verifiable by the software. + + We define a 'reflected value' as one that is the opposite of the + normal bit order of the machine. The 32 bit CRC is calculated as + described for CRC-32c and uses the polynomial code 0x11EDC6F41 + (Castagnoli93) or x^32+x^28+x^27+x^26+x^25 + +x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+x^8+x^6+x^0. The + CRC is computed using a procedure similar to ETHERNET CRC [ITU32], + modified to reflect transport level usage. + + CRC computation uses polynomial division. A message bit-string M is + transformed to a polynomial, M(X), and the CRC is calculated from + M(X) using polynomial arithmetic [Peterson 72]. + + When CRCs are used at the link layer, the polynomial is derived from + on-the-wire bit ordering: the first bit 'on the wire' is the high- + order coefficient. Since SCTP is a transport-level protocol, it + cannot know the actual serial-media bit ordering. Moreover, + different links in the path between SCTP endpoints may use different + link-level bit orders. + + A convention must therefore be established for mapping SCTP transport + messages to polynomials for purposes of CRC computation. The bit- + ordering for mapping SCTP messages to polynomials is that bytes are + taken most-significant first; but within each byte, bits are taken + least-significant first. The first byte of the message provides the + eight highest coefficients. Within each byte, the least-significant + SCTP bit gives the most significant polynomial coefficient within + + + +Stone, et. al. Standards Track [Page 4] + +RFC 3309 SCTP Checksum Change September 2002 + + + that byte, and the most-significant SCTP bit is the least significant + polynomial coefficient in that byte. (This bit ordering is sometimes + called 'mirrored' or 'reflected' [Williams93].) CRC polynomials are + to be transformed back into SCTP transport-level byte values, using a + consistent mapping. + + The SCTP transport-level CRC value should be calculated as follows: + + - CRC input data are assigned to a byte stream, numbered from 0 + to N-1. + + - the transport-level byte-stream is mapped to a polynomial + value. An N-byte PDU with j bytes numbered 0 to N-1, is + considered as coefficients of a polynomial M(x) of order 8N-1, + with bit 0 of byte j being coefficient x^(8(N-j)-8), bit 7 of + byte j being coefficient x^(8(N-j)-1). + + - the CRC remainder register is initialized with all 1s and the + CRC is computed with an algorithm that simultaneously + multiplies by x^32 and divides by the CRC polynomial. + + - the polynomial is multiplied by x^32 and divided by G(x), the + generator polynomial, producing a remainder R(x) of degree less + than or equal to 31. + + - the coefficients of R(x) are considered a 32 bit sequence. + + - the bit sequence is complemented. The result is the CRC + polynomial. + + - The CRC polynomial is mapped back into SCTP transport-level + bytes. Coefficient of x^31 gives the value of bit 7 of SCTP + byte 0, the coefficient of x^24 gives the value of bit 0 of + byte 0. The coefficient of x^7 gives bit 7 of byte 3 and the + coefficient of x^0 gives bit 0 of byte 3. The resulting four- + byte transport-level sequence is the 32-bit SCTP checksum + value. + + IMPLEMENTATION NOTE: Standards documents, textbooks, and vendor + literature on CRCs often follow an alternative formulation, in which + the register used to hold the remainder of the long-division + algorithm is initialized to zero rather than all-1s, and instead the + first 32 bits of the message are complemented. The long-division + algorithm used in our formulation is specified, such that the the + initial multiplication by 2^32 and the long-division are combined + into one simultaneous operation. For such algorithms, and for + messages longer than 64 bits, the two specifications are precisely + equivalent. That equivalence is the intent of this document. + + + +Stone, et. al. Standards Track [Page 5] + +RFC 3309 SCTP Checksum Change September 2002 + + + Implementors of SCTP are warned that both specifications are to be + found in the literature, sometimes with no restriction on the long- + division algorithm. The choice of formulation in this document is to + permit non-SCTP usage, where the same CRC algorithm may be used to + protect messages shorter than 64 bits. + + If SCTP could follow link level CRC use, the CRC would be computed + over the link-level bit-stream. The first bit on the link mapping to + the highest-order coefficient, and so on, down to the last link-level + bit as the lowest-order coefficient. The CRC value would be + transmitted immediately after the input message as a link-level + 'trailer'. The resulting link-level bit-stream would be (M(X)x) * + x^32) + (M(X)*x^32))/ G(x), which is divisible by G(X). There would + thus be a constant CRC remainder for 'good' packets. However, given + that implementations of RFC 2960 have already proliferated, the IETF + discussions considered that the benefit of a 'trailer' CRC did not + outweigh the cost of making a very large change in the protocol + processing. Further, packets accepted by the SCTP 'header' CRC are + in one-to-one correspondence with packets accepted by a modified + procedure using a 'trailer' CRC value, and where the SCTP common + checksum header is set to zero on transmission and is received as + zero. + + There may be a computational advantage in validating the Association + against the Verification Tag, prior to performing a checksum, as + invalid tags will result in the same action as a bad checksum in most + cases. The exceptions for this technique would be INIT and some + SHUTDOWN-COMPLETE exchanges, as well as a stale COOKIE-ECHO. These + special case exchanges must represent small packets and will minimize + the effect of the checksum calculation. + +3 Security Considerations + + In general, the security considerations of RFC 2960 apply to the + protocol with the new checksum as well. + +4 IANA Considerations + + There are no IANA considerations required in this document. + + + + + + + + + + + + +Stone, et. al. Standards Track [Page 6] + +RFC 3309 SCTP Checksum Change September 2002 + + +5 Acknowledgments + + The authors would like to thank the following people that have + provided comments and input on the checksum issue: + + Mark Adler, Ran Atkinson, Stephen Bailey, David Black, Scott Bradner, + Mikael Degermark, Laurent Glaude, Klaus Gradischnig, Alf Heidermark, + Jacob Heitz, Gareth Kiely, David Lehmann, Allision Mankin, Lyndon + Ong, Craig Partridge, Vern Paxson, Kacheong Poon, Michael Ramalho, + David Reed, Ian Rytina, Hanns Juergen Schwarzbauer, Chip Sharp, Bill + Sommerfeld, Michael Tuexen, Jim Williams, Jim Wendt, Michael Welzl, + Jonathan Wood, Lloyd Wood, Qiaobing Xie, La Monte Yarroll. + + Special thanks to Dafna Scheinwald, Julian Satran, Pat Thaler, Matt + Wakeley, and Vince Cavanna, for selection criteria of polynomials and + examination of CRC polynomials, particularly CRC-32c [Castagnoli93]. + + Special thanks to Mr. Ross Williams and his document [Williams93]. + This non-formal perspective on software aspects of CRCs furthered + understanding of authors previously unfamiliar with CRC computation. + More formal treatments of [Blahut 94] or [Peterson 72], was also + essential. + +6 References + + [Castagnoli93] G. Castagnoli, S. Braeuer and M. Herrman, + "Optimization of Cyclic Redundancy-Check Codes with + 24 and 32 Parity Bits", IEEE Transactions on + Communications, Vol. 41, No. 6, June 1993 + + [McKee75] H. McKee, "Improved {CRC} techniques detects + erroneous leading and trailing 0's in transmitted + data blocks", Computer Design Volume 14 Number 10 + Pages 102-4,106, October 1975 + + [RFC1700] Reynolds, J. and J. Postel, "ASSIGNED NUMBERS", RFC + 1700, October 1994. + + [RFC2026] Bradner, S., "The Internet Standards Process -- + Revision 3", BCP 9, RFC 2026, October 1996. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C., + Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M., + Zhang, L. and V. Paxson, "Stream Control Transmission + Protocol," RFC 2960, October 2000. + + + +Stone, et. al. Standards Track [Page 7] + +RFC 3309 SCTP Checksum Change September 2002 + + + [ITU32] ITU-T Recommendation V.42, "Error-correcting + procedures for DCEs using asynchronous-to-synchronous + conversion", section 8.1.1.6.2, October 1996. + +7.1 Informative References + + [STONE] Stone, J., "Checksums in the Internet", Doctoral + dissertation - August 2001. + + [Williams93] Williams, R., "A PAINLESS GUIDE TO CRC ERROR + DETECTION ALGORITHMS" - Internet publication, August + 1993, + http://www.geocities.com/SiliconValley/Pines/ + 8659/crc.htm. + + [Blahut 1994] R.E. Blahut, Theory and Practice of Error Control + Codes, Addison-Wesley, 1994. + + [Easics 2001] http://www.easics.be/webtools/crctool. Online tools + for synthesis of CRC Verilog and VHDL. + + [Feldmeier 95] David C. Feldmeier, Fast software implementation of + error detection codes, IEEE Transactions on + Networking, vol 3 no 6, pp 640-651, December, 1995. + + [Glaise 1997] R. J. Glaise, A two-step computation of cyclic + redundancy code CRC-32 for ATM networks, IBM Journal + of Research and Development} vol 41 no 6, 1997. + http://www.research.ibm.com/journal/rd/416/ + glaise.html. + + [Prange 1957] E. Prange, Cyclic Error-Correcting codes in two + symbols, Technical report AFCRC-TN-57-103, Air Force + Cambridge Research Center, Cambridge, Mass. 1957. + + [Peterson 1972] W. W. Peterson and E.J Weldon, Error Correcting + Codes, 2nd. edition, MIT Press, Cambridge, + Massachusetts. + + [Shie2001] Ming-Der Shieh et. al, A Systematic Approach for + Parallel CRC Computations. Journal of Information + Science and Engineering, Vol.17 No.3, pp.445-461 + + [Sprachman2001] Michael Sprachman, Automatic Generation of Parallel + CRC Circuits, IEEE Design & Test May-June 2001 + + + + + + +Stone, et. al. Standards Track [Page 8] + +RFC 3309 SCTP Checksum Change September 2002 + + +Appendix + + This appendix is for information only and is NOT part of the + standard. + + The anticipated deployment of SCTP ranges over several orders of + magnitude of link speed: from cellular-power telephony devices at + tens of kilobits, to local links at tens of gigabits. Implementors + of SCTP should consider their link speed and choose, from the wide + range of CRC implementations, one which matches their own design + point for size, cost, and throughput. Many techniques for computing + CRCs are known. This Appendix surveys just a few, to give a feel for + the range of techniques available. + + CRCs are derived from early work by Prange in the 1950s [Prange 57]. + The theory underlying CRCs and choice of generator polynomial can be + introduced by either the theory of Galois fields [Blahut 94] or as + ideals of an algebra over cyclic codes [cite Peterson 72]. + + One of the simplest techniques is direct bit-serial hardware + implementations, using the generator polynomial as the taps of a + linear feedback shift register (LSFR). LSFR computation follows + directly from the mathematics, and is generally attributed to Prange. + Tools exist which, a CRC generator polynomial, will produce + synthesizable Verilog code for CRC hardware [Easics 2001]. + + Since LSFRs do not scale well in speed, a variety of other techniques + have been explored. One technique exploits the fact that the divisor + of the polynomial long-division, G, is known in advance. It is thus + possible to pre-compute lookup tables giving the polynomial remainder + of multiple input bits --- typically 2, 4, or 8 bits of input at a + time. This technique can be used either in software or in hardware. + Software to compute lookup tables yielding 2, 4, or 8 bits of result + is freely available. [Williams93] + + For multi-gigabit links, the above techniques may still not be fast + enough. One technique for computing CRCS at OC-48 rates is 'two- + stage' CRC computation [Glaise 1997]. Here, some multiple of G(x), + G(x)H(x), is chosen so as to minimize the number of nonzero + coefficients, or weight, of the product G(x)H(x). The low weight of + the product polynomial makes it susceptible to efficient hardware + divide-by-constant implementations. This first stage gives M(x)/ + (G(x)H(x)), as its result. The second stage then divides the result + of the first stage by H(x), yielding (M(x)/(G(x)H(x)))/H(x). If H(x) + is also relatively prime to G(x), this gives M(x)/G(x). Further + developments on this approach can be found in [Shie2001] and + [Sprachman2001]. + + + + +Stone, et. al. Standards Track [Page 9] + +RFC 3309 SCTP Checksum Change September 2002 + + + The literature also includes a variety of software CRC + implementations. One approach is to use a carefully-tuned assembly + code for direct polynomial division. [Feldmeier 95] reports that for + low-weight polynomials, tuned polynomial arithmetic gives higher + throughput than table-lookup algorithms. Even within table-lookup + algorithms, the size of the table can be tuned, either for total + cache footprint, or (for space-restricted environments) to minimize + total size. + + Implementors should keep in mind, the bit ordering described in + Section 2: the ordering of bits within bytes for computing CRCs in + SCTP is the least significant bit of each byte is the most- + significant polynomial coefficient(and vice-versa). This 'reflected' + SCTP CRC bit ordering matches on-the-wire bit order for Ethernet and + other serial media, but is the reverse of traditional Internet bit + ordering. + + One technique to accommodate this bit-reversal can be explained as + follows: sketch out a hardware implementation, assuming the bits are + in CRC bit order; then perform a left-to-right inversion (mirror + image) on the entire algorithm. (We defer, for a moment, the issue + of byte order within words.) Then compute that "mirror image" in + software. The CRC from the "mirror image" algorithm will be the + bit-reversal of a correct hardware implementation. When the link- + level media sends each byte, the byte is sent in the reverse of the + host CPU bit-order. Serialization of each byte of the "reflected" + CRC value re-reverses the bit order, so in the end, each byte will be + transmitted on-the-wire in the specified bit order. + + The following non-normative sample code is taken from an open-source + CRC generator [Williams93], using the "mirroring" technique and + yielding a lookup table for SCTP CRC32-c with 256 entries, each 32 + bits wide. While neither especially slow nor especially fast, as + software table-lookup CRCs go, it has the advantage of working on + both big-endian and little-endian CPUs, using the same (host-order) + lookup tables, and using only the pre-defined ntohl() and htonl() + operations. The code is somewhat modified from [Williams93], to + ensure portability between big-endian and little-endian + architectures. (Note that if the byte endian-ness of the target + architecture is known to be little-endian the final bit-reversal and + byte-reversal steps can be folded into a single operation.) + + + + + + + + + + +Stone, et. al. Standards Track [Page 10] + +RFC 3309 SCTP Checksum Change September 2002 + + +/*************************************************************/ +/* Note Definition for Ross Williams table generator would */ +/* be: TB_WIDTH=4, TB_POLLY=0x1EDC6F41, TB_REVER=TRUE */ +/* For Mr. Williams direct calculation code use the settings */ +/* cm_width=32, cm_poly=0x1EDC6F41, cm_init=0xFFFFFFFF, */ +/* cm_refin=TRUE, cm_refot=TRUE, cm_xorort=0x00000000 */ +/*************************************************************/ + +/* Example of the crc table file */ +#ifndef __crc32cr_table_h__ +#define __crc32cr_table_h__ + +#define CRC32C_POLY 0x1EDC6F41 +#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF]) + +unsigned long crc_c[256] = +{ +0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, +0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, +0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, +0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, +0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, +0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, +0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, +0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, +0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, +0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, +0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, +0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, +0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, +0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, +0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, +0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, +0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, +0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, +0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, +0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, +0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, +0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, +0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, +0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, +0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, +0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, +0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, +0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, +0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, +0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, +0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, + + + +Stone, et. al. Standards Track [Page 11] + +RFC 3309 SCTP Checksum Change September 2002 + + +0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, +0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, +0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, +0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, +0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, +0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, +0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, +0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, +0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, +0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, +0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, +0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, +0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, +0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, +0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, +0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, +0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, +0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, +0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, +0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, +0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, +0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, +0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, +0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, +0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, +0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, +0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, +0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, +0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, +0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, +0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, +0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, +0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L, +}; + +#endif + + /* Example of table build routine */ + + + +#include +#include + +#define OUTPUT_FILE "crc32cr.h" +#define CRC32C_POLY 0x1EDC6F41L +FILE *tf; + + + + +Stone, et. al. Standards Track [Page 12] + +RFC 3309 SCTP Checksum Change September 2002 + + +unsigned long +reflect_32 (unsigned long b) +{ + int i; + unsigned long rw = 0L; + + for (i = 0; i < 32; i++){ + if (b & 1) + rw |= 1 << (31 - i); + b >>= 1; + } + return (rw); +} + +unsigned long +build_crc_table (int index) +{ + int i; + unsigned long rb; + + rb = reflect_32 (index); + + for (i = 0; i < 8; i++){ + if (rb & 0x80000000L) + rb = (rb << 1) ^ CRC32C_POLY; + else + rb <<= 1; + } + return (reflect_32 (rb)); +} + +main () +{ + int i; + + printf ("\nGenerating CRC-32c table file <%s>\n", OUTPUT_FILE); + if ((tf = fopen (OUTPUT_FILE, "w")) == NULL){ + printf ("Unable to open %s\n", OUTPUT_FILE); + exit (1); + } + fprintf (tf, "#ifndef __crc32cr_table_h__\n"); + fprintf (tf, "#define __crc32cr_table_h__\n\n"); + fprintf (tf, "#define CRC32C_POLY 0x%08lX\n", CRC32C_POLY); + fprintf (tf, "#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])\n"); + fprintf (tf, "\nunsigned long crc_c[256] =\n{\n"); + for (i = 0; i < 256; i++){ + fprintf (tf, "0x%08lXL, ", build_crc_table (i)); + if ((i & 3) == 3) + + + +Stone, et. al. Standards Track [Page 13] + +RFC 3309 SCTP Checksum Change September 2002 + + + fprintf (tf, "\n"); + } + fprintf (tf, "};\n\n#endif\n"); + + if (fclose (tf) != 0) + printf ("Unable to close <%s>." OUTPUT_FILE); + else + printf ("\nThe CRC-32c table has been written to <%s>.\n", + OUTPUT_FILE); +} + + + +/* Example of crc insertion */ + +#include "crc32cr.h" + +unsigned long +generate_crc32c(unsigned char *buffer, unsigned int length) +{ + unsigned int i; + unsigned long crc32 = ~0L; + unsigned long result; + unsigned char byte0,byte1,byte2,byte3; + + for (i = 0; i < length; i++){ + CRC32C(crc32, buffer[i]); + } + result = ~crc32; + + /* result now holds the negated polynomial remainder; + * since the table and algorithm is "reflected" [williams95]. + * That is, result has the same value as if we mapped the message + * to a polynomial, computed the host-bit-order polynomial + * remainder, performed final negation, then did an end-for-end + * bit-reversal. + * Note that a 32-bit bit-reversal is identical to four inplace + * 8-bit reversals followed by an end-for-end byteswap. + * In other words, the bytes of each bit are in the right order, + * but the bytes have been byteswapped. So we now do an explicit + * byteswap. On a little-endian machine, this byteswap and + * the final ntohl cancel out and could be elided. + */ + + byte0 = result & 0xff; + byte1 = (result>>8) & 0xff; + byte2 = (result>>16) & 0xff; + byte3 = (result>>24) & 0xff; + + + +Stone, et. al. Standards Track [Page 14] + +RFC 3309 SCTP Checksum Change September 2002 + + + crc32 = ((byte0 << 24) | + (byte1 << 16) | + (byte2 << 8) | + byte3); + return ( crc32 ); +} + +int +insert_crc32(unsigned char *buffer, unsigned int length) +{ + SCTP_message *message; + unsigned long crc32; + message = (SCTP_message *) buffer; + message->common_header.checksum = 0L; + crc32 = generate_crc32c(buffer,length); + /* and insert it into the message */ + message->common_header.checksum = htonl(crc32); + return 1; +} + +int +validate_crc32(unsigned char *buffer, unsigned int length) +{ + SCTP_message *message; + unsigned int i; + unsigned long original_crc32; + unsigned long crc32 = ~0L; + + /* save and zero checksum */ + message = (SCTP_message *) buffer; + original_crc32 = ntohl(message->common_header.checksum); + message->common_header.checksum = 0L; + crc32 = generate_crc32c(buffer,length); + return ((original_crc32 == crc32)? 1 : -1); +} + + + + + + + + + + + + + + + + +Stone, et. al. Standards Track [Page 15] + +RFC 3309 SCTP Checksum Change September 2002 + + +Authors' Addresses + + Jonathan Stone + Room 446, Mail code 9040 + Gates building 4A + Stanford, Ca 94305 + + EMail: jonathan@dsg.stanford.edu + + + Randall R. Stewart + 24 Burning Bush Trail. + Crystal Lake, IL 60012 + USA + + EMail: rrs@cisco.com + + + Douglas Otis + 800 E. Middlefield + Mountain View, CA 94043 + USA + + EMail: dotis@sanlight.net + + + + + + + + + + + + + + + + + + + + + + + + + + + +Stone, et. al. Standards Track [Page 16] + +RFC 3309 SCTP Checksum Change September 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 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. + + + + + + + + + + + + + + + + + + + +Stone, et. al. Standards Track [Page 17] + diff --git a/doc/rfc3758.txt b/doc/rfc3758.txt new file mode 100644 index 0000000..1c0dc15 --- /dev/null +++ b/doc/rfc3758.txt @@ -0,0 +1,1235 @@ + + + + + + +Network Working Group R. Stewart +Request for Comments: 3758 M. Ramalho +Category: Standards Track Cisco Systems, Inc. + Q. Xie + Motorola, Inc. + M. Tuexen + Univ. of Applied Sciences Muenster + P. Conrad + University of Delaware + May 2004 + + + Stream Control Transmission Protocol (SCTP) + Partial Reliability Extension + +Status of this Memo + + This document specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" (STD 1) for the standardization state + and status of this protocol. Distribution of this memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2004). All Rights Reserved. + +Abstract + + This memo describes an extension to the Stream Control Transmission + Protocol (SCTP) that allows an SCTP endpoint to signal to its peer + that it should move the cumulative ack point forward. When both + sides of an SCTP association support this extension, it can be used + by an SCTP implementation to provide partially reliable data + transmission service to an upper layer protocol. This memo describes + the protocol extensions, which consist of a new parameter for INIT + and INIT ACK, and a new FORWARD TSN chunk type, and provides one + example of a partially reliable service that can be provided to the + upper layer via this mechanism. + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 1] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2 + 1.1. Overview of Protocol Extensions. . . . . . . . . . . . . 2 + 1.2. Overview of New Services Provided to the Upper Layer . . 3 + 1.3. Benefits of PR-SCTP . . . . . . . . . . . . . . . . . . 4 + 2. Conventions. . . . . . . . . . . . . . . . . . . . . . . . . . 5 + 3. Protocol Changes to support PR-SCTP . . . . . . . . . . . . . 5 + 3.1. Forward-TSN-Supported Parameter For INIT and INIT ACK. . 5 + 3.2. Forward Cumulative TSN Chunk Definition (FORWARD TSN). . 5 + 3.3. Negotiation of Forward-TSN-Supported parameter . . . . . 7 + 3.3.1. Sending Forward-TSN-Supported param in INIT . . . 7 + 3.3.2. Receipt of Forward-TSN-Supported parameter in + INIT or INIT-ACK. . . . . . . . . . . . . . . . . 7 + 3.3.3. Receipt of Op. Error for Forward-TSN-Supported + Param . . . . . . . . . . . . . . . . . . . . . . 8 + 3.4. Definition of "abandoned" in the context of PR-SCTP. . . 8 + 3.5. Sender Side Implementation of PR-SCTP. . . . . . . . . . 9 + 3.6. Receiver Side Implementation of PR-SCTP. . . . . . . . . 12 + 4. Services provided by PR-SCTP to the upper layer. . . . . . . . 14 + 4.1. PR-SCTP Service Definition for "timed reliability" . . . 15 + 4.2. PR-SCTP Association Establishment. . . . . . . . . . . . 16 + 4.3. Guidelines for defining other PR-SCTP Services . . . . . 17 + 4.4. Usage Notes. . . . . . . . . . . . . . . . . . . . . . . 19 + 5. Variables. . . . . . . . . . . . . . . . . . . . . . . . . . . 19 + 6. Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . 19 + 7. Security Considerations. . . . . . . . . . . . . . . . . . . . 19 + 8. IANA Considerations. . . . . . . . . . . . . . . . . . . . . . 20 + 9. References . . . . . . . . . . . . . . . . . . . . . . . . . . 20 + 9.1. Normative References . . . . . . . . . . . . . . . . . . 20 + 9.2. Informative References . . . . . . . . . . . . . . . . . 20 + 10. Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 20 + 11. Full Copyright Statement . . . . . . . . . . . . . . . . . . . + +1. Introduction + + This memo describes an extension to the Stream Control Transmission + Protocol (SCTP) RFC 2960 [2] that allows an SCTP sender to signal to + its peer that it should no longer expect to receive one or more DATA + chunks. + +1.1. Overview of Protocol Extensions + + The protocol extension described in this document consists of two new + elements: + + 1. a single new parameter in the INIT/INIT-ACK exchange that + indicates whether the endpoint supports the extension + + + +Stewart, et al. Standards Track [Page 2] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + 2. a single new chunk type, FORWARD TSN, that indicates that the + receiver should move its cumulative ack point forward (possibly + skipping past one or more DATA chunks that may not yet have been + received and/or acknowledged.) + +1.2. Overview of New Services Provided to the Upper Layer + + When this extension is supported by both sides of an SCTP + association, it can be used to provide partially reliable transport + service over an SCTP association. We define partially reliable + transport service as a service that allows the user to specify, on a + per message basis, the rules governing how persistent the transport + service should be in attempting to send the message to the receiver. + + One example of partially reliable service is specified in this + document, namely a "timed reliability" service. This service allows + the service user to indicate a limit on the duration of time that the + sender should try to transmit/retransmit the message (this is a + natural extension of the "lifetime" parameter already in the base + protocol). + + In addition to this example, we will also show that defining the + semantics of a particular partially reliable service involves two + elements, namely: + + 1. how the service user indicates the level of reliability required + for a particular message, and + + 2. how the sender side implementation uses that reliability level to + determine when to give up on further retransmissions of that + message. + + Note that other than the fact that the FORWARD-TSN chunk is required, + neither of these two elements impacts the "on-the-wire" protocol; + only the API and the sender side implementation are affected by the + way in which the service is defined to the upper layer. Therefore, + in principle, it is feasible to implement many varieties of partially + reliable services in a particular SCTP implementation without + changing the on-the-wire protocol. Also, the SCTP receiver does not + necessarily need to know which semantics of partially reliable + service are being used by the sender, since the receiver's only role + is to correctly interpret FORWARD TSN chunks, thereby skipping past + messages that the sender has decided to no longer transmit (or + retransmit). + + Nevertheless, it is recommended that a limited number of standard + definitions of partially reliable services be standardized by the + IETF so that the designers of IETF application layer protocols can + + + +Stewart, et al. Standards Track [Page 3] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + match the requirements of their upper layer protocols to standard + service definitions provided by a particular SCTP implementation. + One such definition, "timed reliability", is included in this + document. Given the extensions proposed in this document, other + definitions may be standardized as the need arises without further + changes to the on-the-wire protocol. + +1.3. Benefits of PR-SCTP + + Hereafter, we use the notation "Partial Reliable Stream Control + Transmission Protocol (PR-SCTP)" to refer to the SCTP protocol, + extended as defined in this document. + + The following are some of the advantages for integrating partially + reliable data service into SCTP, i.e., benefits of PR-SCTP: + + 1. Some application layer protocols may benefit from being able to + use a single SCTP association to carry both reliable content, -- + such as text pages, billing and accounting information, setup + signaling -- and unreliable content, e.g., state that is highly + sensitive to timeliness, where generating a new packet is more + advantageous than transmitting an old one [3]. + + 2. Partially reliable data traffic carried by PR-SCTP will enjoy the + same communication failure detection and protection capabilities + as the normal reliable SCTP data traffic does. This includes the + ability to quickly detect a failed destination address, fail-over + to an alternate destination address, and be notified if the data + receiver becomes unreachable. + + 3. In addition to providing unordered, unreliable data transfer as + UDP does, PR-SCTP can provide ordered, unreliable data transfer + service. + + 4. PR-SCTP employs the same congestion control and congestion + avoidance for all data traffic, whether reliable or partially + reliable - this is very desirable since SCTP enforces TCP- + friendliness (unlike UDP.) + + 5. Because of the chunk bundling function of SCTP, reliable and + unreliable messages can be multiplexed over a single PR-SCTP + association. Therefore, the number of IP datagrams (and hence the + network overhead) can be reduced instead of having to send these + different types of data using separate protocols. Additionally, + this multiplexing allows for port savings versus using different + ports for reliable and unreliable connections. + + + + + +Stewart, et al. Standards Track [Page 4] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + +2. Conventions + + The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, + SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when + they appear in this document, are to be interpreted as described in + BCP 14, RFC 2119 [1]. + + Comparisons and arithmetic on Transport Sequence Numbers (TSNs) are + governed by the rules in Section 1.6 of RFC 2960 [2]. + +3. Protocol Changes to support PR-SCTP + +3.1. Forward-TSN-Supported Parameter For INIT and INIT ACK + + The following new OPTIONAL parameter is added to the INIT and INIT + ACK chunks. + + Parameter Name Status Type Value + ------------------------------------------------------------- + Forward-TSN-Supported OPTIONAL 49152 (0xC000) + + At the initialization of the association, the sender of the INIT or + INIT ACK chunk MAY include this OPTIONAL parameter to inform its peer + that it is able to support the Forward TSN chunk (see Section 3.3 for + further details). The format of this parameter is defined as + follows: + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Parameter Type = 49152 | Parameter Length = 4 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Type: 16 bit u_int + + 49152, indicating Forward-TSN-Supported parameter + + Length: 16 bit u_int + + Indicates the size of the parameter, i.e., 4. + +3.2 Forward Cumulative TSN Chunk Definition (FORWARD TSN) + + The following new chunk type is defined: + + Chunk Type Chunk Name + ------------------------------------------------------ + 192 (0xC0) Forward Cumulative TSN (FORWARD TSN) + + + + +Stewart, et al. Standards Track [Page 5] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + This chunk shall be used by the data sender to inform the data + receiver to adjust its cumulative received TSN point forward because + some missing TSNs are associated with data chunks that SHOULD NOT be + transmitted or retransmitted by the sender. + + Forward Cumulative TSN chunk has the following format: + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 192 | Flags = 0x00 | Length = Variable | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | New Cumulative TSN | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Stream-1 | Stream Sequence-1 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ / + / \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Stream-N | Stream Sequence-N | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Chunk Flags: + + Set to all zeros on transmit and ignored on receipt. + + New Cumulative TSN: 32 bit u_int + + This indicates the new cumulative TSN to the data receiver. Upon + the reception of this value, the data receiver MUST consider + any missing TSNs earlier than or equal to this value as received, + and stop reporting them as gaps in any subsequent SACKs. + + Stream-N: 16 bit u_int + + This field holds a stream number that was skipped by this + FWD-TSN. + + Stream Sequence-N: 16 bit u_int + + This field holds the sequence number associated with the stream + that was skipped. The stream sequence field holds the largest + stream sequence number in this stream being skipped. The receiver + of the FWD-TSN's can use the Stream-N and Stream Sequence-N fields + to enable delivery of any stranded TSN's that remain on the stream + re-ordering queues. This field MUST NOT report TSN's corresponding + to DATA chunks that are marked as unordered. For ordered DATA + chunks this field MUST be filled in. + + + +Stewart, et al. Standards Track [Page 6] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + +3.3. Negotiation of Forward-TSN-Supported parameter + +3.3.1. Sending Forward-TSN-Supported param in INIT + + If an SCTP endpoint supports the FORWARD TSN chunk, then any time it + sends an INIT during association establishment, it MAY include the + Forward-TSN-supported parameter in the INIT chunk to indicate this + fact to its peer. + + Note that if the endpoint chooses NOT to include the parameter, then + at no time during the life of the association can it send or process + a FORWARD TSN. It MUST instead act as if it does NOT support the + FORWARD TSN chunk, returning an ERROR to the peer upon receipt of any + FORWARD TSN. + +3.3.2. Receipt of Forward-TSN-Supported parameter in INIT or INIT-ACK + + When a receiver of an INIT detects a Forward-TSN-Supported parameter + and does not support the Forward-TSN chunk type, the receiver MUST + follow the rules defined in Section 3.3.3 of RFC 2960 [2]. + + When a receiver of an INIT-ACK detects a Forward-TSN-Supported + parameter and it does not support the Forward-TSN chunk type, the + receiver MUST follow the rules defined in Section 3.3.3 of RFC 2960 + [2]. + + When a receiver of an INIT detects a Forward-TSN-Supported parameter + and it does support the Forward-TSN chunk type, the receiver MAY + respond with a Forward-TSN-supported parameter in the INIT-ACK chunk. + + Note that if the endpoint chooses NOT to include the parameter, then + at no time during the life of the association can it send or process + a FORWARD TSN. It MUST instead act as if it does NOT support the + FORWARD TSN chunk, returning an ERROR to the peer upon receipt of any + FORWARD TSN. + + When an endpoint that supports the FORWARD TSN chunk receives an INIT + that does not contain the Forward-TSN-Supported Parameter, that + endpoint: + + o MAY include the Forward-TSN-Supported parameter in the INIT-ACK, + o SHOULD record the fact that the peer does not support the FORWARD + TSN chunk, + o MUST NOT send a FORWARD TSN chunk at any time during the + associations life, + o SHOULD inform the upper layer if the upper layer has requested + such notification. + + + + +Stewart, et al. Standards Track [Page 7] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + +3.3.3. Receipt of Op. Error for Forward-TSN-Supported Param + + When an SCTP endpoint that desires to use the FORWARD TSN chunk + feature for partially reliable data transfer receives an operational + error from the remote endpoint (either bundled with the COOKIE or as + an unrecognized parameter in the INIT-ACK), indicating that the + remote endpoint does not recognize the Forward-TSN-Supported + parameter, the local endpoint SHOULD inform its upper layer of the + remote endpoint's inability to support partially reliable data + transfer. + + The local endpoint may then choose to either: + + 1) end the initiation process (in cases where the initiation process + has already ended, the endpoint may need to send an ABORT) in + consideration of the peer's inability to supply the requested + features for the new association, or + + 2) continue the initiation process (in cases where the initiation + process has already completed, the endpoint MUST just mark the + association as not supporting partial reliability), but with the + understanding that partially reliable data transmission is not + supported. In this case, the endpoint receiving the operational + error SHOULD note that the FORWARD TSN chunk is not supported, and + MUST NOT transmit a FORWARD TSN chunk at any time during the life + of the association. + +3.4. Definition of "abandoned" in the context of PR-SCTP + + At some point, a sending PR-SCTP implementation MAY determine that a + particular data chunk SHOULD NOT be transmitted or retransmitted + further, in accordance with the rules governing some particular PR- + SCTP service definition (such as the definition of "timed + reliability" in Section 4.1.) For purposes of this document, we + define the term "abandoned" to refer to any data chunk about which + the SCTP sender has made this determination. + + Each PR-SCTP service defines the rules for determining when a TSN is + "abandoned", and accordingly, the rules that govern how, whether, and + when to "abandon" a TSN may vary from one service definition to + another. However, the rules governing the actions taken when a TSN + is "abandoned" do NOT vary between service definitions; these rules + are included in Section 3.5. + + + + + + + + +Stewart, et al. Standards Track [Page 8] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + +3.5. Sender Side Implementation of PR-SCTP + + The sender side implementation of PR-SCTP is identical to that of the + base SCTP protocol, except for: + + o actions a sending side PR-SCTP implementation must take when a TSN + is "abandoned" (as per the rules of whatever PR-SCTP service + definition is in effect) + o special actions that a PR-SCTP implementation must take upon + receipt of SACK + o rules governing the generation of FORWARD TSN chunks. + + In detail, these exceptions are as follows: + + A1) The sender maintains an "Advanced.Peer.Ack.Point" for each peer + to track a theoretical cumulative TSN point of the peer (Note, + this is a _new_ protocol variable and its value is NOT + necessarily the same as the SCTP "Cumulative TSN Ack Point" as + defined in Section 1.4 of RFC 2960 [2], and as discussed + throughout that document.) + + A2) From time to time, as governed by the rules of a particular PR- + SCTP service definition (see Section 4), the SCTP data sender may + make a determination that a particular data chunk that has + already been assigned a TSN SHOULD be "abandoned". + + When a data chunk is "abandoned", the sender MUST treat the data + chunk as being finally acked and no longer outstanding. + + The sender MUST NOT credit an "abandoned" data chunk to the + partial_bytes_acked as defined in Section 7.2.2 of RFC 2960 [2], + and MUST NOT advance the cwnd based on this "abandoned" data + chunk. + + A3) When a TSN is "abandoned", if it is part of a fragmented message, + all other TSN's within that fragmented message MUST be abandoned + at the same time. + + A4) Whenever the data sender receives a SACK from the data receiver, + it MUST first process the SACK using the normal procedures as + defined in Section 6.2.1 of RFC 2960 [2]. + + + + + + + + + + +Stewart, et al. Standards Track [Page 9] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + The data sender MUST then perform the following additional steps: + + C1) Let SackCumAck be the Cumulative TSN ACK carried in the + received SACK. + + If (Advanced.Peer.Ack.Point < SackCumAck), then update + Advanced.Peer.Ack.Point to be equal to SackCumAck. + + C2) Try to further advance the "Advanced.Peer.Ack.Point" locally, + that is, to move "Advanced.Peer.Ack.Point" up as long as the + chunk next in the out-queue space is marked as "abandoned", + as shown in the following example: + + Assuming that a SACK arrived with the Cumulative TSN ACK = + 102 and the Advanced.Peer.Ack.Point is updated to this + value: + + out-queue at the end of ==> out-queue after Adv.Ack.Point + normal SACK processing local advancement + + ... ... + Adv.Ack.Pt-> 102 acked 102 acked + 103 abandoned 103 abandoned + 104 abandoned Adv.Ack.P-> 104 abandoned + 105 105 + 106 acked 106 acked + ... ... + + In this example, the data sender successfully advanced the + "Advanced.Peer.Ack.Point" from 102 to 104 locally. + + C3) If, after step C1 and C2, the "Advanced.Peer.Ack.Point" is + greater than the Cumulative TSN ACK carried in the received + SACK, the data sender MUST send the data receiver a FORWARD + TSN chunk containing the latest value of the + "Advanced.Peer.Ack.Point". Note that the sender MAY delay + the sending of a FORWARD TSN as defined in rule F2 below. + IMPLEMENTATION NOTE: It is an implementation decision as to + which destination address it is to be sent to, the only + restriction being that the address MUST be one that is + CONFIRMED. + + C4) For each "abandoned" TSN, the sender of the FORWARD TSN MUST + determine if the chunk has a valid stream and sequence number + (i.e., it was ordered). If the chunk has a valid stream and + sequence number, the sender MUST include the stream and + sequence number in the FORWARD TSN. This information will + enable the receiver to easily find any stranded TSN's waiting + + + +Stewart, et al. Standards Track [Page 10] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + on stream reorder queues. Each stream SHOULD only be + reported once; this means that if multiple abandoned messages + occur in the same stream, then only the highest abandoned + stream sequence number is reported. If the total size of the + FORWARD TSN does NOT fit in a single MTU, then the sender of + the FORWARD TSN SHOULD lower the Advanced.Peer.Ack.Point to + the last TSN that will fit in a single MTU. + + C5) If a FORWARD TSN is sent, the sender MUST assure that at + least one T3-rtx timer is running. IMPLEMENTATION NOTE: Any + destination's timer may be used for the purposes of rule C5. + + A5) Any time the T3-rtx timer expires, on any destination, the sender + SHOULD try to advance the "Advanced.Peer.Ack.Point" by following + the procedures outlined in C2 - C5. + + The following additional rules govern the generation of FORWARD TSN + chunks: + + F1) An endpoint MUST NOT use the FORWARD TSN for any purposes other + than circumstances described in this document. + + F2) The data sender SHOULD always attempt to bundle an outgoing + FORWARD TSN with outbound DATA chunks for efficiency. + + A sender MAY even choose to delay the sending of the FORWARD TSN + in the hope of bundling it with an outbound DATA chunk. + + IMPLEMENTATION NOTE: An implementation may wish to limit the + number of duplicate FORWARD TSN chunks it sends by either only + sending a duplicate FORWARD TSN every other SACK or waiting a + full RTT before sending a duplicate FORWARD TSN. + + IMPLEMENTATION NOTE: An implementation may allow the maximum + delay for generating a FORWARD TSN to be configured either + statically or dynamically in order to meet the specific timing + requirements of the protocol being carried, but see the next + rule: + + F3) Any delay applied to the sending of FORWARD TSN chunk SHOULD NOT + exceed 200ms and MUST NOT exceed 500ms. In other words, an + implementation MAY lower this value below 500ms but MUST NOT + raise it above 500ms. + + NOTE: Delaying the sending of FORWARD TSN chunks may cause delays + in the receiver's ability to deliver other data being held at the + receiver for re-ordering. The values of 200ms and 500ms match + + + + +Stewart, et al. Standards Track [Page 11] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + the required values for the delayed acknowledgement in RFC 2960 + [2] since delaying a FORWARD TSN has the same consequences but in + the reverse direction. + + F4) The detection criterion for out-of-order SACKs MUST remain the + same as stated in RFC 2960, that is, a SACK is only considered + out-of-order if the Cumulative TSN ACK carried in the SACK is + earlier than that of the previous received SACK (i.e., the + comparison MUST NOT be made against "Advanced.Peer.Ack.Point"). + + F5) If the decision to "abandon" a chunk is made, no matter how such + a decision is made, the appropriate congestion adjustment MUST be + made as specified in RFC 2960 if the chunk would have been marked + for retransmission later (e.g., either by T3-Timeout or by Fast + Retransmit). + +3.6. Receiver Side Implementation of PR-SCTP + + The receiver side implementation of PR-SCTP at an SCTP endpoint A is + capable of supporting any PR-SCTP service definition used by the + sender at endpoint B, even if that service definition is not + supported by the sending side functionality of host A. All that is + necessary is that the receiving side correctly handle the Forward- + TSN-Supported parameter as specified in Section 3.3, and correctly + handle the receipt of FORWARD TSN chunks as specified below. + + DATA chunk arrival at a PR-SCTP receiver proceeds exactly as for DATA + chunk arrival at a base protocol SCTP receiver---that is, the + receiver MUST perform the same TSN handling, including duplicate + detection, gap detection, SACK generation, cumulative TSN + advancement, etc. as defined in RFC 2960 [2]---with the following + exceptions and additions. + + When a FORWARD TSN chunk arrives, the data receiver MUST first update + its cumulative TSN point to the value carried in the FORWARD TSN + chunk, and then MUST further advance its cumulative TSN point locally + if possible, as shown by the following example: + + Assuming that the new cumulative TSN carried in the arrived + FORWARD TSN is 103: + + in-queue before processing in-queue after processing + the FORWARD TSN ==> the FORWARD TSN and further + advancement + + + + + + + +Stewart, et al. Standards Track [Page 12] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + cum.TSN.Pt-> 102 received 102 -- + 103 missing 103 -- + 104 received 104 -- + 105 received cum.TSN.Pt-> 105 received + 106 missing 106 missing + 107 received 107 received + ... ... + + In this example, the receiver's cumulative TSN point is first + updated to 103 and then further advanced to 105. + + After the above processing, the data receiver MUST stop reporting any + missing TSNs earlier than or equal to the new cumulative TSN point. + + Note, if the "New Cumulative TSN" value carried in the arrived + FORWARD TSN chunk is found to be behind or at the current cumulative + TSN point, the data receiver MUST treat this FORWARD TSN as out-of- + date and MUST NOT update its Cumulative TSN. The receiver SHOULD + send a SACK to its peer (the sender of the FORWARD TSN) since such a + duplicate may indicate the previous SACK was lost in the network. + + Any time a FORWARD TSN chunk arrives, for the purposes of sending a + SACK, the receiver MUST follow the same rules as if a DATA chunk had + been received (i.e., follow the delayed sack rules specified in RFC + 2960 [2] section 6.2). + + Whenever a DATA chunk arrives with the 'U' bit set to '0' (indicating + ordered delivery) and is out of order, the receiver must hold the + chunk for reordering. Since it is possible with PR-SCTP that a DATA + chunk being waited upon will not be retransmitted, special actions + will need to be taken upon the arrival of a FORWARD TSN. + + In particular, during processing of a FORWARD TSN, the receiver MUST + use the stream sequence information to examine all of the listed + stream reordering queues, and immediately make available for delivery + stream sequence numbers earlier than or equal to the stream sequence + number listed inside the FORWARD TSN. Any such stranded data SHOULD + be made immediately available to the upper layer application. + + An application using PR-SCTP receiving data should be aware of + possible missing messages. The stream sequence number can be used, + in such a case, to determine that an intervening message has been + skipped. When intervening messages are missing, it is an application + decision to process the messages or to take some other corrective + action. + + + + + + +Stewart, et al. Standards Track [Page 13] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + After receiving and processing a FORWARD TSN, the data receiver MUST + take cautions in updating its re-assembly queue. The receiver MUST + remove any partially reassembled message, which is still missing one + or more TSNs earlier than or equal to the new cumulative TSN point. + In the event that the receiver has invoked the partial delivery API, + a notification SHOULD also be generated to inform the upper layer API + that the message being partially delivered will NOT be completed. + + Note that after receiving a FORWARD TSN and updating the cumulative + acknowledgement point, if a TSN that was skipped does arrive (i.e., + due to network reordering), then the receiver will follow the normal + rules defined in RFC 2960 [2] for handling duplicate data. This + implies that the receiver will drop the chunk and report it as a + duplicate in the next outbound SACK chunk. + +4. Services provided by PR-SCTP to the upper layer + + As described in Section 1.2, it is feasible to implement a variety of + partially reliable transport services using the new protocol + mechanisms introduced in Section 3; introducing these new services + requires making changes only at the sending side API, and the sending + side protocol implementation. Thus, there may be a temptation to + standardize only the protocol, and leave the service definition as + "implementation specific" or leave it to be defined in + "informational" documents. + + However, for those who may wish to write IETF standards for upper + layer protocols implemented over PR-SCTP, it is important to be able + to refer to a standard definition of services provided. Therefore, + this section provides example definitions of one such service, while + also providing guidelines for the definition of additional services + as required. Each such service may be proposed as a separate new + RFC. + + Section 4 is organized as follows: + + o Section 4.1 provides the definition of one specific PR-SCTP + service: timed reliability. + + o Section 4.2 describes how a particular PR-SCTP service definition + is requested by the upper layer during association establishment, + and how the upper layer is notified if that request cannot be + satisfied. + + o Section 4.3 then provides guidelines for the specification of PR- + SCTP services other then the one defined in this memo. + + + + + +Stewart, et al. Standards Track [Page 14] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + o Finally, Section 4.4 describes some additional usage notes that + upper layer protocol designers and implementors may find helpful. + +4.1. PR-SCTP Service Definition for "timed reliability" + + The "timed reliability" service is a natural extension of the + "lifetime" concept already present in the base SCTP protocol. + + When this service is requested for an SCTP association, it changes + the meaning of the lifetime parameter specified in the SEND primitive + (see Section 10.1, part (E) of RFC 2960 [2]; note that the parameter + is spelled "life time" in that document.) + + In the base SCTP protocol, the lifetime parameter is used to avoid + sending stale data. When a lifetime value is indicated for a + particular message and that lifetime expires, SCTP cancels the + sending of this message, and notifies the ULP if the first + transmission of the data does not take place (because of rwnd or cwnd + limitations, or for any other reason). However, in the base + protocol, if SCTP has sent the first transmission before the lifetime + expires, then the message MUST be sent as a normal reliable message. + During episodes of congestion this is particularly unfortunate, as + retransmission wastes bandwidth that could have been used for other + (non-lifetime expired) messages. + + When the "timed reliability" service is invoked, this latter + restriction is removed. Specifically, when the "timed reliability" + service is in effect, the following rules govern all messages that + are sent with a lifetime parameter: + + TR1) If the lifetime parameter of a message is SCTP_LIFETIME_RELIABLE + (or unspecified see Section 5), that message is treated as a + normal reliable SCTP message, just as in the base SCTP protocol. + + TR2) If the lifetime parameter is not SCTP_LIFETIME_RELIABLE (see + Section 5), then the SCTP sender MUST treat the message just as + if it were a normal reliable SCTP message, as long as the + lifetime has not yet expired. + + TR3) Before assigning a TSN to any message, the SCTP sender MUST + evaluate the lifetime of that message. If it is expired, the + SCTP sender MUST NOT assign a TSN to that message, but instead, + SHOULD issue a notification to the upper layer and abandon the + message. + + TR4) Before transmitting or retransmitting a message for which a TSN + is already assigned, the SCTP sender MUST evaluate the lifetime + of the message. If the lifetime of the message is expired, the + + + +Stewart, et al. Standards Track [Page 15] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + SCTP sender MUST "abandon" the message, as per the rules + specified in Section 3.5 marking that TSN as eligible for + forward TSN. Note that this meets the requirement G1 defined in + Section 4.3. IMPLEMENTATION NOTE: An implementation SHOULD + delay TSN assignment as mentioned in RFC 2960 [2] Section 10.1. + In such a case, the lifetime parameter should be checked BEFORE + assigning a TSN, thus allowing a message to be abandoned without + the need to send a FORWARD TSN. + + TR5) The sending SCTP MAY evaluate the lifetime of messages at + anytime. Expired messages that have not been assigned a TSN MAY + be handled as per rule TR3. Expired messages that HAVE been + assigned a TSN MAY be handled as per rule TR4. + + TR6) The sending application MUST NOT change the lifetime parameter + once the message is passed to the sending SCTP. + + Implementation Note: Rules TR1 through TR4 are designed in such a way + as to avoid requiring the implementer to maintain a separate timer + for each message; instead, the lifetime need only be evaluated at + points in the life of the message where actions are already being + taken, such as TSN assignment, transmission, or expiration of a + retransmission timeout. Rule TR5 is intended to give the SCTP + implementor flexibility to evaluate lifetime at any other convenient + opportunity, WITHOUT requiring that lifetime be evaluated immediately + at the point in time where it expires. + +4.2. PR-SCTP Association Establishment + + An upper layer protocol (ULP) that uses PR-SCTP may need to know + whether PR-SCTP can be supported on a given association. Therefore, + the ULP needs to have some indication of whether the FORWARD-TSN + chunk is supported by its peer. + + Section 10.1 of RFC 2960 [2] describes abstract primitives for the + ULP-to-SCTP interface, while noting that "individual implementations + must define their own exact format, and may provide combinations or + subsets of the basic functions in single calls." + + In this section, we describe one additional return value that may be + added to the ASSOCIATE primitive to allow an SCTP service user to + indicate whether the FORWARD-TSN chunk is supported by its peer. + + RFC 2960 indicates that the ASSOCIATE primitive "allows the upper + layer to initiate an association to a specific peer endpoint". It is + structured as follows: + + + + + +Stewart, et al. Standards Track [Page 16] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + Format: ASSOCIATE(local SCTP instance name, destination transport + addr, outbound stream count) + -> association id [,destination transport addr list] + [,outbound stream count] + + This extension adds one new OPTIONAL return value, such that the new + primitive reads as follows: + + Format: ASSOCIATE(local SCTP instance name, destination transport + addr, outbound stream count ) + -> association id [,destination transport addr list] + [,outbound stream count] [,forward tsn supported] + + NOTE: As per RFC 2960, if the ASSOCIATE primitive is implemented as a + non-blocking call, the new OPTIONAL return value shall be passed with + the association parameters using the COMMUNICATION UP notification. + + The new OPTIONAL parameter "forward tsn supported" is a boolean flag: + + (0) false [default] indicates that FORWARD TSN is not enabled by both + endpoints. + + (1) true indicates that FORWARD TSN is enabled on both endpoints. + + We also add a new primitive to allow the user application to enable/ + disable the PR-SCTP service on its endpoint before an association is + established. + + Format: ENABLE_PRSCTP(local SCTP instance name, boolean enable) + + The boolean parameter enable, if set to true, will enable PR-SCTP + upon future endpoint associations. If the boolean parameter is set + to false, then the local endpoint will not advertise support of PR- + SCTP and thus disable the feature on future associations. It is + recommended that this option be disabled by default, i.e., in order + to enable PR-SCTP, the user will need to call this API option with + the enable flag set to "true". + +4.3. Guidelines for defining other PR-SCTP Services + + Other PR-SCTP services may be defined and implemented as dictated by + the needs of upper layer protocols. If such upper layer protocols + are to be standardized and require some particular PR-SCTP service + other than the one defined in this document (i.e., "timed + reliability"), then those additional PR-SCTP services should also be + specified and standardized in a new RFC. + + + + + +Stewart, et al. Standards Track [Page 17] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + It is suggested that any such additional service definitions be + modeled after the contents of Section 4.1. In particular, the + service definition should provide: + + 1. A description of how the service user specifies any parameters + that need to be associated with a particular message (and/or any + other communication that takes place between the application and + the SCTP transport sender) that provides the SCTP transport sender + with the information needed to determine when to give up on + transmission of a particular message. + + Preferably, this description should reference the primitives in + the abstract API provided in Section 10 of RFC 2960 [2], + indicating any: + + * changes to the interpretation of the existing parameters of + existing primitives, + + * additional parameters to be added to existing primitives (these + should be OPTIONAL, and default values should be indicated), + + * additional primitives that may be needed. + + 2. A description of the rules used by the sender side implementation + to determine when to give up on messages that have not yet been + assigned a TSN. This description should also indicate what + protocol events trigger the evaluation, and what actions to take + (e.g., notifications.) + + 3. A description of the rules used by the sender side implementation + to determine when to give up on the transmission or retransmission + of messages that have already been assigned a TSN, and may have + been transmitted and possibly retransmitted zero or more times. + + Items (2) and (3) in the list above should also indicate what + protocol events trigger the evaluation, and what actions to take if + the determination is made that the sender should give up on + transmitting the message (e.g., notifications to the ULP.) + + Note that in any PR-SCTP service, the following rule MUST be + specified to avoid a protocol deadlock: + + (G1) When the sender side implementation gives up on transmitting a + message that has been assigned a TSN (i.e., when that message is + "abandoned", as defined in Section 3.4), the sender side MUST + mark that TSN as eligible for forward TSN, and the rules in + Section 3.4 regarding the sending of FORWARD TSN chunks MUST be + followed. + + + +Stewart, et al. Standards Track [Page 18] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + Finally, a PR-SCTP service definition should specify a "canonical + service name" to uniquely identify the service, and distinguish it + from other PR-SCTP services. This name can then be used in upper + layer protocol standards to indicate which PR-SCTP service definition + is required by that upper layer protocol. It can also be used in the + documentation of APIs of PR-SCTP implementations to indicate how an + upper layer indicates which definition of PR-SCTP service should + apply. The canonical service name for the PR-SCTP service defined in + Section 4.1 is "timed reliability". + +4.4. Usage Notes + + Detecting missing data in a PR-SCTP stream is useful for some + applications (e.g., Fibre channel or SCSI over IP). With PR-SCTP, + this becomes possible - the upper layer simply needs to examine the + stream sequence number of the arrived user messages of that stream to + detect any missing data. Note, this detection only works when all + the messages on that stream are sent in order, i.e., the "U" bit is + not set. + +5. Variables + + This section defines variables used throughout this document: + + SCTP_LIFETIME_RELIABLE - A user interface indication defined by an + implementation and used to indicate when a message is to be + considered fully reliable. + +6. Acknowledgments + + The authors would like to thank Brian Bidulock, Scott Bradner, Jon + Berger, Armando L. Caro Jr., John Loughney, Jon Peterson, Ivan Arias + Rodriguez, Ian Rytina, Chip Sharp, and others for their comments. + +7. Security Considerations + + This document does not introduce any new security concerns to SCTP + other than the ones already documented in RFC 2960 [2]. In + particular, this document shares the same security issues as + unordered data within RFC 2960 [2] identified by RFC 3436 [4]. An + application using the PR-SCTP extension should not use transport + layer security; further details can be found in RFC 3436 [4]. + + Note that the ability to cause a message to be skipped (i.e, the + FORWARD TSN chunk) does not provide any new attack for a Man-In-the- + Middle (MIM), since the MIM already is capable of changing and/or + withholding data, thus effectively skipping messages. However, the + FORWARD TSN chunk does provide a mechanism to make it easier for a + + + +Stewart, et al. Standards Track [Page 19] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + MIM to skip selective messages when the application has this feature + enabled since the MIM would have less state to maintain. + +8. IANA Considerations + + IANA has assigned 192 as a new chunk type to SCTP. + + IANA has assigned 49152 as a new parameter type code to SCTP. + +9. References + +9.1. Normative References + + [1] Bradner, S., "Key words for use in RFCs to Indicate Requirement + Levels", BCP 14, RFC 2119, March 1997. + + [2] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer, + H., Taylor, T., Rytina, I., Kalla, M., Zhang, L. and V. Paxson, + "Stream Control Transmission Protocol", RFC 2960, October 2000. + +9.2. Informative References + + [3] Clark, D. and D. Tennenhouse, "Architectural Considerations for + a New Generation of Protocols", SIGCOMM 1990 pp. 200-208, + September 1990. + + [4] Jungmaier, A., Rescorla, E. and M. Tuexen, "Transport Layer + Security over Stream Control Transmission Protocol", RFC 3436, + December 2002. + +10. Authors' Addresses + + Randall R. Stewart + Cisco Systems, Inc. + 8725 West Higgins Road + Suite 300 + Chicago, IL 60631 + USA + + Phone: +1-815-477-2127 + EMail: rrs@cisco.com + + + + + + + + + + +Stewart, et al. Standards Track [Page 20] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + + Michael A. Ramalho + Cisco Systems, Inc. + 1802 Rue de la Porte + Wall Township, NJ 07719-3784 + USA + + Phone: +1.732.449.5762 + EMail: mramalho@cisco.com + + + Qiaobing Xie + Motorola, Inc. + 1501 W. Shure Drive, #2309 + Arlington Heights, IL 60004 + USA + + Phone: +1-847-632-3028 + EMail: qxie1@email.mot.com + + + Michael Tuexen + Univ. of Applied Sciences Muenster + Stegerwaldstr. 39 + 48565 Steinfurt + Germany + + EMail: tuexen@fh-muenster.de + + + Phillip T. Conrad + University of Delaware + Department of Computer and Information Sciences + Newark, DE 19716 + USA + + Phone: +1 302 831 8622 + EMail: conrad@acm.org + URI: http://www.cis.udel.edu/~pconrad + + + + + + + + + + + + + +Stewart, et al. Standards Track [Page 21] + +RFC 3758 SCTP Partial Reliability Extension May 2004 + + +11. Full Copyright Statement + + Copyright (C) The Internet Society (2004). This document is subject + to the rights, licenses and restrictions contained in BCP 78, and + except as set forth therein, the authors retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM 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. + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at ietf- + ipr@ietf.org. + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + + + + + + +Stewart, et al. Standards Track [Page 22] + diff --git a/doc/rfc3873.txt b/doc/rfc3873.txt new file mode 100644 index 0000000..c583226 --- /dev/null +++ b/doc/rfc3873.txt @@ -0,0 +1,2579 @@ + + + + + + +Network Working Group J. Pastor +Request for Comments: 3873 M. Belinchon +Category: Standards Track Ericsson + September 2004 + + + Stream Control Transmission Protocol (SCTP) + Management Information Base (MIB) + +Status of this Memo + + This document specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" (STD 1) for the standardization state + and status of this protocol. Distribution of this memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2004). + + +Abstract + + The Stream Control Transmission Protocol (SCTP) is a reliable + transport protocol operating on top of a connectionless packet + network such as IP. It is designed to transport public switched + telephone network (PSTN) signaling messages over the connectionless + packet network, but is capable of broader applications. + + This memo defines the Management Information Base (MIB) module which + describes the minimum set of objects needed to manage the + implementation of the SCTP. + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2 + 1.1. Abbreviations. . . . . . . . . . . . . . . . . . . . . . 2 + 2. The Internet-Standard Management Framework . . . . . . . . . . 3 + 3. MIB Structure. . . . . . . . . . . . . . . . . . . . . . . . . 3 + 3.1. SCTP Objects . . . . . . . . . . . . . . . . . . . . . . 4 + 3.1.1. SCTP Statistics. . . . . . . . . . . . . . . . . 4 + 3.1.2. SCTP Parameters. . . . . . . . . . . . . . . . . 5 + 3.1.3. MIB Tables . . . . . . . . . . . . . . . . . . . 5 + 3.1.3.1. Association Table. . . . . . . . . . . 5 + 3.1.3.2. Reverse Lookup Table . . . . . . . . . 8 + 3.2. Conformance. . . . . . . . . . . . . . . . . . . . . . . 9 + 4. Definitions. . . . . . . . . . . . . . . . . . . . . . . . . . 9 + + + +Pastor & Belinchon Standards Track [Page 1] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + 5. Compiling Notes. . . . . . . . . . . . . . . . . . . . . . . . 42 + 6. References . . . . . . . . . . . . . . . . . . . . . . . . . . 42 + 6.1. Normative References . . . . . . . . . . . . . . . . . . 42 + 6.2. Informative References . . . . . . . . . . . . . . . . . 43 + 7. Security Considerations. . . . . . . . . . . . . . . . . . . . 44 + 8. Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . 45 + 9. Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 45 + 10. Full Copyright Statement . . . . . . . . . . . . . . . . . . . 46 + +1. Introduction + + This memo defines the Management Information Base (MIB) module which + describes managed objects for implementations of the SCTP. + + The document starts with a brief description of the SNMP framework + and continues with the MIB explanation and security consideration + sections among others. + + The managed objects in this MIB module are based on [RFC2012] update: + "Management Information Base for the Transmission Control Protocol + (TCP)" referred as [TCPMIB] (work in progress), and RFC 3291 "Textual + Conventions for Internet Network Addresses" [RFC3291]. + + Terms related to the SCTP architecture are explained in [RFC2960]. + Other specific abbreviations are listed below. + + 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]. + +1.1. Abbreviations + + DNS - Domain Name System + IANA - Internet Assigned Numbers Authority + IETF - Internet Engineering Task Force + IP - Internet Protocol + MIB - Management Information Base + RFC - Request For Comments + RTO - Retransmission Time Out + SCTP - Stream Control Transmission Protocol + SMI - Structure of Management Information + SNMP - Simple Network Management Protocol + TCB - Transmission Control Block + TCP - Transmission Control Protocol + + + + + + + +Pastor & Belinchon Standards Track [Page 2] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + +2. The Internet-Standard Management Framework + + For a detailed overview of the documents that describe the current + Internet-Standard Management Framework, please refer to section 7 of + RFC 3410 [RFC3410]. + + Managed objects are accessed via a virtual information store, termed + the Management Information Base or MIB. MIB objects are generally + accessed through the Simple Network Management Protocol (SNMP). + Objects in the MIB are defined using the mechanisms defined in the + Structure of Management Information (SMI). This memo specifies a MIB + module that is compliant to the SMIv2, which is described in STD 58, + RFC 2578 [RFC2578], STD 58, RFC 2579 [RFC2579] and STD 58, RFC 2580 + [RFC2580]. + +3. MIB Structure + + This chapter explains the main objects this MIB defines. A detailed + view of the MIB structure with the OID values is below. + + MIB-2 {1 3 6 1 2 1} + +--(104)sctpMIB + | + +--(1) sctpObjects + | | + | +--(1) sctpStats + | | | + | | +-- + | | + | +--(2)sctpParameters + | | | + | | +-- + | | + | +--(3) sctpAssocTable + | | + | +--(4) sctpAssocLocalAddrTable + | | + | +--(5) sctpAssocRemAddrTable + | | + | +--(6) sctpLookupLocalPortTable + | | + | +--(7) sctpLookupRemPortTable + | | + | +--(8) sctpLookupRemHostNameTable + | | + | +--(9) sctpLookupRemPrimIPAddrTable + | | + | +--(10) sctpLookupRemIPAddrTable + + + +Pastor & Belinchon Standards Track [Page 3] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + | + | + +--(2)sctpMibConformance + | + +--(1) sctpMibCompliances + | | + | +--(1) sctpMibCompliance + | + +--(2) sctpMibGroups + | + +--(1) sctpLayerParamsGroup + | + +--(2) sctpStatsGroup + | + +--(3) sctpPerAssocParamsGroup + | + +--(4) sctpInverseGroup + + + The main groups are explained further in the MIB definition. + +3.1. SCTP Objects + + This branch contains the SCTP statistics and general parameters (both + of them scalars) and the SCTP MIB tables. + +3.1.1. SCTP Statistics + + The SCTP MIB includes both Counter32s and Counter64s to deal with + statistics. Counter64s are used for those counters, which are likely + to wrap around in less than one hour, according to [RFC2863]. + + In addition Gauge32 is also used. + +3.1.1.1. State-Related Statistics + + These statistics are based on the TCP model, but adapted to the SCTP + states. They store the number of successful association attempts, + how many associations have been initiated by the local or the remote + SCTP layer, and the number of associations terminated in a graceful + (by means of SHUTDOWN procedure) or ungraceful way (by means of CLOSE + procedure). + +3.1.1.2. Statistics for traffic Measurements + + This set of objects specifies statistics related to the whole SCTP + layer. There are, e.g., statistics related to both SCTP packets and + SCTP chunks. + + + +Pastor & Belinchon Standards Track [Page 4] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + Statistics related to a specific association, or local/remote IP + addresses are defined inside their associated table. + +3.1.2. SCTP Parameters + + This section of the MIB contains the general variables for the SCTP + protocol. Maximum, minimum, initial and default values are listed + here. + + SCTP RTO mechanism definition is based on the TCP MIB [TCPMIB]. In + SCTP, only options 'other' and 'vanj' are valid since SCTP defines + Van Jacobson's algorithm (vanj) as the one to be used to calculate + RTO. 'Other' is left for future use. + +3.1.3. MIB Tables + + There are several tables included in the SCTP MIB. The first group + deals with the SCTP association variables and is composed of a main + and two extended tables. The second group is a bunch of tables used + to perform reverse lookups. + + It is NOT possible to create rows in any table (sctpAssocTable, + sctpAssocLocalAddrTable, sctpRemAddrTable and Reverse Lookup tables) + using SNMP. + + It is NOT possible to delete rows in any table using SNMP except in + sctpAssocTable under the particular conditions explained below. + +3.1.3.1. Association Table + + The sctpAssocTable is the main MIB table, where all the association + related information is stored on a per association basis. It is + structured according to expanded tables. The main table is called + sctpAssocTable and is indexed by sctpAssocId (the association + identification). This is a value that uniquely identifies an + association. The MIB does not restrict what value must be written + here, however it must be unique within the table. + + The sctpAssoc index is also shared by two more tables: + - sctpAssocLocalAddrTable: to store the local IP address(es). + - sctpAssocRemAddrTable: to store the remote addresses and the + per-remote-address related information. + + Entries in the sctpAssocTable are created when trying to establish + the association, i.e., when sending the COOKIE-ECHO message + (originating side) or the COOKIE-ACK message (server side). At this + point, i.e., at established state, all entry fields are filled in + with valid values. + + + +Pastor & Belinchon Standards Track [Page 5] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + Note: The following representation is a conceptual mode of describing + the relationship between the tables in this MIB. Note that the real + relationship of the tables is by sharing an index, so tables are not + truly within tables. Every entry is explained when defining the + corresponding objects in the MIB. + + mib-2 {1 3 6 1 2 1} + +--(104)sctpMIB + | + +--(1) sctpObjects + | | + . . + . . + | + +--(3) sctpAssocTable + | | + | +--(1) sctpAssocId (index) + | | + | +--(2) sctpAssocRemHostName + | | + | +--(3) sctpAssocLocalPort + | | + | +--(4) sctpAssocRemPort + | | + | +--(5) sctpAssocRemPrimAddrType + | | + | +--(6) sctpAssocRemPrimAddr + | | + | +--(7) sctpAssocHeartBeatInterval + | | + | +--(8) sctpAssocState + | | + | +--(9) sctpAssocInStreams + | | + | +--(10) sctpAssocOutStreams + | | + | +--(11) sctpAssocMaxRetr + | | + | +--(12) sctpAssocPrimProcess + | | + | +--(13) sctpAssocT1expireds + | | + | +--(14) sctpAssocT2expireds + | | + | +--(15) sctpAssocRtxChunks + | | + | +--(16) sctpAssocStartTime + | | + + + +Pastor & Belinchon Standards Track [Page 6] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + | +--(17) sctpAssocDiscontinuityTime + | + | + +--(4) sctpAssocLocalAddrTable + | | + | |--(-) sctpAssocId (shared index) + | | + | +--(1) sctpAssocLocalAddrType(index) + | | + | +--(2) sctpAssocLocalAddr (index) + | | + | +--(3) sctpAssocLocalAddrStartTime + | + | + +--(5) sctpAssocRemAddrTable + | | + | |--(-) sctpAssocId (shared index) + | | + | +--(1) sctpAssocRemAddrType (index) + . | + . +--(2) sctpAssocRemAddr (index) + . | + +--(3) sctpAssocRemAddrActive + | + +--(4) sctpAssocRemAddrHBActive + | + +--(5) sctpAssocRemAddrRTO + | + +--(6) sctpAssocRemAddrMaxPathRtx + | + +--(7) sctpAssocRemAddrRtx + | + +--(8) sctpAssocRemAddrStartTime + + Both sctpAssocLocalAddrTable and sctpAssocRemAddrTable are indexed by + addresses. 'Addr' and 'AddrType' use the syntax InetAddress and + InetAddressType defined in the Textual Conventions for Internet + Network Address (RFC3291). The InetAddressType TC has codepoints for + unknown, IPv4, IPv6, non-global IPv4, non-global IPv6, and DNS + addresses, but only the IPv4 and IPv6 address types are required to + be supported by implementations of this MIB module. Implementations + that connect multiple zones are expected to support the non-global + IPv4 and non-global IPv6 address types as well. + + Note that DNS addresses are not used in this MIB module. They are + always resolved to the on-the-wire form prior to connection setup, + and the on-the-wire form is what appears in the MIB objects. + + + + +Pastor & Belinchon Standards Track [Page 7] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + The sctpAssocLocalAddrTable table will have as many entries as local + IP addresses have been defined for the association. The + sctpAssocRemAddrTable table will contain as many entries as remote IP + addresses are known to reach the peer. For the multihoming concept + see reference RFC2960. + + To keep the name of the remote peer (when provided by the peer at + initialization time), an entry has been created in the sctpAssocTable + called sctpAssocRemHostName. When no DNS name is provided by the + remote endpoint, this value will be NULL (zero-length string). + Otherwise, the received DNS name will be stored here. + + If it is necessary to abort an existing association, the value + deleteTCB(9) must be written in the variable sctpAssocState. That is + the only way to delete rows in any of the mentioned tables. + +3.1.3.2. Reverse Lookup Table + + There are five reverse lookup tables to help management applications + efficiently access conceptual rows in other tables. These tables + allow management applications to avoid expensive tree walks through + large numbers of associations. + + All of these tables are optional. If these tables are implemented, + an entry in them must be created after the entry in the main table + (sctpAssocTable) associated with it has been created. This ensures + that the field indexing the lookup table exists. + + The defined reverse lookup tables allow for performing a lookup using + the following variables: + + - Local Port: It allows a management application to find all the + associations that use a specific local port + - Remote Port: It allows a management application to find all the + associations that use a specific remote port + - Remote Host Name: It allows a management application to find + all the associations with a specific host name. + - Remote Primary IP Address: It allows a management application + to find all the associations that use a specific remote IP + address as primary. + - Remote IP address: a management application to find all the + associations that use a specific remote IP address. + + As an example the picture below shows the table to look up by local + port. + + + + + + +Pastor & Belinchon Standards Track [Page 8] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + MIB-2 {1 3 6 1 2 1} + +--(104)sctpMIB + | + +--(1) sctpObjects + | | + . . + . . + | | + | +--(6) sctpLookupLocalPortTable + | | | + . . +--(-) sctpAssocLocalPort (shared index) + . . | + +--(-) sctpAssocId (shared index) + | + +--(1) sctpLookupLocalPortStartTime + + It is not possible for the operator to either create or delete rows + in these tables. The rows in this table will dynamically appear and + be removed as the corresponding entries in sctpAssocTable are. + +3.2. Conformance + + The conformance section recommends all the inverse lookup tables in + this MIB as optional. General layer and per association parameters + and statistics are considered mandatory. + + IP addresses use the global IPv4 and global IPv6 address formats. + Unknown value and DNS name formats are not used. Names, if present, + are stored in the sctpRemoteHostName variable. + +4. Definitions + + SCTP-MIB DEFINITIONS ::= BEGIN + + IMPORTS + MODULE-IDENTITY, OBJECT-TYPE, Integer32, Unsigned32, Gauge32, + Counter32, Counter64, mib-2 + FROM SNMPv2-SMI -- [RFC2578] + TimeStamp, TruthValue + FROM SNMPv2-TC -- [RFC2579] + MODULE-COMPLIANCE, OBJECT-GROUP + FROM SNMPv2-CONF -- [RFC2580] + InetAddressType, InetAddress, InetPortNumber + FROM INET-ADDRESS-MIB; -- [RFC3291] + + + + + + + +Pastor & Belinchon Standards Track [Page 9] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + sctpMIB MODULE-IDENTITY + LAST-UPDATED "200409020000Z" -- 2nd September 2004 + ORGANIZATION "IETF SIGTRAN Working Group" + CONTACT-INFO + " + WG EMail: sigtran@ietf.org + + Web Page: + http://www.ietf.org/html.charters/sigtran-charter.html + + Chair: Lyndon Ong + Ciena Corporation + 0480 Ridgeview Drive + Cupertino, CA 95014 + USA + Tel: + Email: lyong@ciena.com + + Editors: Maria-Carmen Belinchon + R&D Department + Ericsson Espana S. A. + Via de los Poblados, 13 + 28033 Madrid + Spain + Tel: +34 91 339 3535 + Email: Maria.C.Belinchon@ericsson.com + + Jose-Javier Pastor-Balbas + R&D Department + Ericsson Espana S. A. + Via de los Poblados, 13 + 28033 Madrid + Spain + Tel: +34 91 339 1397 + Email: J.Javier.Pastor@ericsson.com + " + DESCRIPTION + "The MIB module for managing SCTP implementations. + + Copyright (C) The Internet Society (2004). This version of + this MIB module is part of RFC 3873; see the RFC itself for + full legal notices. " + + REVISION "200409020000Z" -- 2nd September 2004 + + DESCRIPTION " Initial version, published as RFC 3873" + + ::= { mib-2 104 } + + + +Pastor & Belinchon Standards Track [Page 10] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + -- the SCTP base variables group + + sctpObjects OBJECT IDENTIFIER ::= { sctpMIB 1 } + + sctpStats OBJECT IDENTIFIER ::= { sctpObjects 1 } + sctpParams OBJECT IDENTIFIER ::= { sctpObjects 2 } + + -- STATISTICS + -- ********** + + -- STATE-RELATED STATISTICS + + sctpCurrEstab OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of associations for which the current state is + either ESTABLISHED, SHUTDOWN-RECEIVED or SHUTDOWN-PENDING." + REFERENCE + "Section 4 in RFC2960 covers the SCTP Association state + diagram." + + ::= { sctpStats 1 } + + + sctpActiveEstabs OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of times that associations have made a direct + transition to the ESTABLISHED state from the COOKIE-ECHOED + state: COOKIE-ECHOED -> ESTABLISHED. The upper layer initiated + the association attempt." + REFERENCE + "Section 4 in RFC2960 covers the SCTP Association state + diagram." + + ::= { sctpStats 2 } + + + + + + + + + + + +Pastor & Belinchon Standards Track [Page 11] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + sctpPassiveEstabs OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of times that associations have made a direct + transition to the ESTABLISHED state from the CLOSED state: + CLOSED -> ESTABLISHED. The remote endpoint initiated the + association attempt." + REFERENCE + "Section 4 in RFC2960 covers the SCTP Association state + diagram." + + ::= { sctpStats 3 } + + + sctpAborteds OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of times that associations have made a direct + transition to the CLOSED state from any state using the + primitive 'ABORT': AnyState --Abort--> CLOSED. Ungraceful + termination of the association." + REFERENCE + "Section 4 in RFC2960 covers the SCTP Association state + diagram." + + ::= { sctpStats 4 } + + + sctpShutdowns OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of times that associations have made a direct + transition to the CLOSED state from either the SHUTDOWN-SENT + state or the SHUTDOWN-ACK-SENT state. Graceful termination of + the association." + REFERENCE + "Section 4 in RFC2960 covers the SCTP Association state + diagram." + + ::= { sctpStats 5 } + + + + + +Pastor & Belinchon Standards Track [Page 12] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + -- OTHER LAYER STATISTICS + + sctpOutOfBlues OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of out of the blue packets received by the host. + An out of the blue packet is an SCTP packet correctly formed, + including the proper checksum, but for which the receiver was + unable to identify an appropriate association." + REFERENCE + "Section 8.4 in RFC2960 deals with the Out-Of-The-Blue + (OOTB) packet definition and procedures." + + ::= { sctpStats 6 } + + sctpChecksumErrors OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of SCTP packets received with an invalid + checksum." + REFERENCE + "The checksum is located at the end of the SCTP packet as per + Section 3.1 in RFC2960. RFC3309 updates SCTP to use a 32 bit + CRC checksum." + + ::= { sctpStats 7 } + + sctpOutCtrlChunks OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of SCTP control chunks sent (retransmissions are + not included). Control chunks are those chunks different from + DATA." + REFERENCE + "Sections 1.3.5 and 1.4 in RFC2960 refer to control chunk as + those chunks different from those that contain user + information, i.e., DATA chunks." + + ::= { sctpStats 8 } + + + + + + +Pastor & Belinchon Standards Track [Page 13] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + sctpOutOrderChunks OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of SCTP ordered data chunks sent (retransmissions + are not included)." + REFERENCE + "Section 3.3.1 in RFC2960 defines the ordered data chunk." + + ::= { sctpStats 9 } + + sctpOutUnorderChunks OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of SCTP unordered chunks (data chunks in which the + U bit is set to 1) sent (retransmissions are not included)." + REFERENCE + "Section 3.3.1 in RFC2960 defines the unordered data chunk." + + ::= { sctpStats 10 } + + sctpInCtrlChunks OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of SCTP control chunks received (no duplicate + chunks included)." + REFERENCE + "Sections 1.3.5 and 1.4 in RFC2960 refer to control chunk as + those chunks different from those that contain user + information, i.e., DATA chunks." + + ::= { sctpStats 11 } + + + sctpInOrderChunks OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of SCTP ordered data chunks received (no duplicate + chunks included)." + + + + + +Pastor & Belinchon Standards Track [Page 14] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + REFERENCE + "Section 3.3.1 in RFC2960 defines the ordered data chunk." + + ::= { sctpStats 12 } + + + sctpInUnorderChunks OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of SCTP unordered chunks (data chunks in which the + U bit is set to 1) received (no duplicate chunks included)." + REFERENCE + "Section 3.3.1 in RFC2960 defines the unordered data chunk." + + ::= { sctpStats 13 } + + + + sctpFragUsrMsgs OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + + "The number of user messages that have to be fragmented + because of the MTU." + + ::= { sctpStats 14 } + + + sctpReasmUsrMsgs OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of user messages reassembled, after conversion + into DATA chunks." + REFERENCE + "Section 6.9 in RFC2960 includes a description of the + reassembly process." + + ::= { sctpStats 15 } + + + + + + + +Pastor & Belinchon Standards Track [Page 15] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + sctpOutSCTPPacks OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of SCTP packets sent. Retransmitted DATA chunks + are included." + + ::= { sctpStats 16 } + + + sctpInSCTPPacks OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of SCTP packets received. Duplicates are + included." + + ::= { sctpStats 17 } + + sctpDiscontinuityTime OBJECT-TYPE + SYNTAX TimeStamp + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of sysUpTime on the most recent occasion at which + any one or more of this general statistics counters suffered a + discontinuity. The relevant counters are the specific + instances associated with this interface of any Counter32 or + Counter64 object contained in the SCTP layer statistics + (defined below sctpStats branch). If no such discontinuities + have occurred since the last re-initialization of the local + management subsystem, then this object contains a zero value." + REFERENCE + "The inclusion of this object is recommended by RFC2578." + + ::= { sctpStats 18 } + + + -- PROTOCOL GENERAL VARIABLES + -- ************************** + + sctpRtoAlgorithm OBJECT-TYPE + SYNTAX INTEGER { + other(1), -- Other new one. Future use + vanj(2) -- Van Jacobson's algorithm + } + + + +Pastor & Belinchon Standards Track [Page 16] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The algorithm used to determine the timeout value (T3-rtx) + used for re-transmitting unacknowledged chunks." + REFERENCE + "Section 6.3.1 and 6.3.2 in RFC2960 cover the RTO calculation + and retransmission timer rules." + DEFVAL {vanj} -- vanj(2) + + ::= { sctpParams 1 } + + + sctpRtoMin OBJECT-TYPE + SYNTAX Unsigned32 + UNITS "milliseconds" + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The minimum value permitted by a SCTP implementation for the + retransmission timeout value, measured in milliseconds. More + refined semantics for objects of this type depend upon the + algorithm used to determine the retransmission timeout value. + + A retransmission time value of zero means immediate + retransmission. + + The value of this object has to be lower than or equal to + stcpRtoMax's value." + DEFVAL {1000} -- milliseconds + + ::= { sctpParams 2 } + + sctpRtoMax OBJECT-TYPE + SYNTAX Unsigned32 + UNITS "milliseconds" + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The maximum value permitted by a SCTP implementation for the + retransmission timeout value, measured in milliseconds. More + refined semantics for objects of this type depend upon the + algorithm used to determine the retransmission timeout value. + + A retransmission time value of zero means immediate re- + transmission. + + + + + +Pastor & Belinchon Standards Track [Page 17] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + The value of this object has to be greater than or equal to + stcpRtoMin's value." + DEFVAL {60000} -- milliseconds + + ::= { sctpParams 3 } + + + sctpRtoInitial OBJECT-TYPE + SYNTAX Unsigned32 + UNITS "milliseconds" + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The initial value for the retransmission timer. + + A retransmission time value of zero means immediate re- + transmission." + DEFVAL {3000} -- milliseconds + + ::= { sctpParams 4 } + + + sctpMaxAssocs OBJECT-TYPE + SYNTAX Integer32 (-1 | 0..2147483647) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The limit on the total number of associations the entity can + support. In entities where the maximum number of associations + is dynamic, this object should contain the value -1." + + ::= { sctpParams 5 } + + + sctpValCookieLife OBJECT-TYPE + SYNTAX Unsigned32 + UNITS "milliseconds" + + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Valid cookie life in the 4-way start-up handshake procedure." + REFERENCE + "Section 5.1.3 in RFC2960 explains the cookie generation + process. Recommended value is per section 14 in RFC2960." + DEFVAL {60000} -- milliseconds + + ::= { sctpParams 6 } + + + +Pastor & Belinchon Standards Track [Page 18] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + sctpMaxInitRetr OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The maximum number of retransmissions at the start-up phase + (INIT and COOKIE ECHO chunks). " + REFERENCE + "Section 5.1.4, 5.1.6 in RFC2960 refers to Max.Init.Retransmit + parameter. Recommended value is per section 14 in RFC2960." + DEFVAL {8} -- number of attempts + + ::= { sctpParams 7 } + + + -- TABLES + -- ****** + + -- the SCTP Association TABLE + + -- The SCTP association table contains information about each + -- association in which the local endpoint is involved. + + + sctpAssocTable OBJECT-TYPE + SYNTAX SEQUENCE OF SctpAssocEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table containing SCTP association-specific information." + + ::= { sctpObjects 3 } + + + sctpAssocEntry OBJECT-TYPE + SYNTAX SctpAssocEntry + MAX-ACCESS not-accessible + + STATUS current + DESCRIPTION + "General common variables and statistics for the whole + association." + INDEX { sctpAssocId } + + ::= { sctpAssocTable 1 } + + + + + + +Pastor & Belinchon Standards Track [Page 19] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + SctpAssocEntry ::= SEQUENCE { + sctpAssocId Unsigned32, + sctpAssocRemHostName OCTET STRING, + sctpAssocLocalPort InetPortNumber, + sctpAssocRemPort InetPortNumber, + sctpAssocRemPrimAddrType InetAddressType, + sctpAssocRemPrimAddr InetAddress, + sctpAssocHeartBeatInterval Unsigned32, + sctpAssocState INTEGER, + sctpAssocInStreams Unsigned32, + sctpAssocOutStreams Unsigned32, + sctpAssocMaxRetr Unsigned32, + sctpAssocPrimProcess Unsigned32, + sctpAssocT1expireds Counter32, -- Statistic + sctpAssocT2expireds Counter32, -- Statistic + sctpAssocRtxChunks Counter32, -- Statistic + sctpAssocStartTime TimeStamp, + sctpAssocDiscontinuityTime TimeStamp + } + + + sctpAssocId OBJECT-TYPE + SYNTAX Unsigned32 (1..4294967295) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Association Identification. Value identifying the + association. " + + ::= { sctpAssocEntry 1 } + + + sctpAssocRemHostName OBJECT-TYPE + SYNTAX OCTET STRING (SIZE(0..255)) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The peer's DNS name. This object needs to have the same + format as the encoding in the DNS protocol. This implies that + the domain name can be up to 255 octets long, each octet being + 0<=x<=255 as value with US-ASCII A-Z having a case insensitive + matching. + + If no DNS domain name was received from the peer at init time + (embedded in the INIT or INIT-ACK chunk), this object is + meaningless. In such cases the object MUST contain a zero- + length string value. Otherwise, it contains the remote host + name received at init time." + + + +Pastor & Belinchon Standards Track [Page 20] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + ::= { sctpAssocEntry 2 } + + + sctpAssocLocalPort OBJECT-TYPE + SYNTAX InetPortNumber (1..65535) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The local SCTP port number used for this association." + + ::= { sctpAssocEntry 3 } + + + sctpAssocRemPort OBJECT-TYPE + SYNTAX InetPortNumber (1..65535) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The remote SCTP port number used for this association." + + ::= { sctpAssocEntry 4 } + + + sctpAssocRemPrimAddrType OBJECT-TYPE + SYNTAX InetAddressType + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The internet type of primary remote IP address. " + + ::= { sctpAssocEntry 5 } + + sctpAssocRemPrimAddr OBJECT-TYPE + SYNTAX InetAddress + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The primary remote IP address. The type of this address is + determined by the value of sctpAssocRemPrimAddrType. + + The client side will know this value after INIT_ACK message + reception, the server side will know this value when sending + INIT_ACK message. However, values will be filled in at + established(4) state." + + ::= { sctpAssocEntry 6 } + + + + + +Pastor & Belinchon Standards Track [Page 21] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + sctpAssocHeartBeatInterval OBJECT-TYPE + SYNTAX Unsigned32 + UNITS "milliseconds" + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The current heartbeat interval.. + + Zero value means no HeartBeat, even when the concerned + sctpAssocRemAddrHBFlag object is true." + DEFVAL {30000} -- milliseconds + + ::= { sctpAssocEntry 7 } + + + sctpAssocState OBJECT-TYPE + SYNTAX INTEGER { + closed(1), + cookieWait(2), + cookieEchoed(3), + established(4), + shutdownPending(5), + shutdownSent(6), + shutdownReceived(7), + shutdownAckSent(8), + deleteTCB(9) + } + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The state of this SCTP association. + + As in TCP, deleteTCB(9) is the only value that may be set by a + management station. If any other value is received, then the + agent must return a wrongValue error. + + If a management station sets this object to the value + deleteTCB(9), then this has the effect of deleting the TCB (as + defined in SCTP) of the corresponding association on the + managed node, resulting in immediate termination of the + association. + + As an implementation-specific option, an ABORT chunk may be + sent from the managed node to the other SCTP endpoint as a + result of setting the deleteTCB(9) value. The ABORT chunk + implies an ungraceful association shutdown." + + + + + +Pastor & Belinchon Standards Track [Page 22] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + REFERENCE + + "Section 4 in RFC2960 covers the SCTP Association state + diagram." + + ::= { sctpAssocEntry 8 } + + + sctpAssocInStreams OBJECT-TYPE + SYNTAX Unsigned32 (1..65535) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Inbound Streams according to the negotiation at association + start up." + REFERENCE + "Section 1.3 in RFC2960 includes a definition of stream. + Section 5.1.1 in RFC2960 covers the streams negotiation + process." + + ::= { sctpAssocEntry 9 } + + sctpAssocOutStreams OBJECT-TYPE + SYNTAX Unsigned32 (1..65535) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Outbound Streams according to the negotiation at association + start up. " + REFERENCE + "Section 1.3 in RFC2960 includes a definition of stream. + Section 5.1.1 in RFC2960 covers the streams negotiation + process." + + ::= { sctpAssocEntry 10 } + + + sctpAssocMaxRetr OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The maximum number of data retransmissions in the association + context. This value is specific for each association and the + upper layer can change it by calling the appropriate + primitives. This value has to be smaller than the addition of + all the maximum number for all the paths + (sctpAssocRemAddrMaxPathRtx). + + + +Pastor & Belinchon Standards Track [Page 23] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + A value of zero value means no retransmissions." + DEFVAL {10} -- number of attempts + + ::= { sctpAssocEntry 11 } + + sctpAssocPrimProcess OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "This object identifies the system level process which holds + primary responsibility for the SCTP association. + Wherever possible, this should be the system's native unique + identification number. The special value 0 can be used to + indicate that no primary process is known. + + Note that the value of this object can be used as a pointer + into the swRunTable of the HOST-RESOURCES-MIB(if the value is + smaller than 2147483647) or into the sysApplElmtRunTable of + the SYSAPPL-MIB." + + ::= { sctpAssocEntry 12 } + + + -- Association Statistics + + sctpAssocT1expireds OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The T1 timer determines how long to wait for an + acknowledgement after sending an INIT or COOKIE-ECHO chunk. + This object reflects the number of times the T1 timer expires + without having received the acknowledgement. + + Discontinuities in the value of this counter can occur at re- + initialization of the management system, and at other times as + indicated by the value of sctpAssocDiscontinuityTime." + REFERENCE + "Section 5 in RFC2960." + + + ::= { sctpAssocEntry 13 } + + sctpAssocT2expireds OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + + + +Pastor & Belinchon Standards Track [Page 24] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + STATUS current + DESCRIPTION + "The T2 timer determines how long to wait for an + acknowledgement after sending a SHUTDOWN or SHUTDOWN-ACK + chunk. This object reflects the number of times that T2- timer + expired. + + Discontinuities in the value of this counter can occur at re- + initialization of the management system, and at other times as + indicated by the value of sctpAssocDiscontinuityTime." + REFERENCE + "Section 9.2 in RFC2960." + ::= { sctpAssocEntry 14 } + + + sctpAssocRtxChunks OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "When T3-rtx expires, the DATA chunks that triggered the T3 + timer will be re-sent according with the retransmissions + rules. Every DATA chunk that was included in the SCTP packet + that triggered the T3-rtx timer must be added to the value of + this counter. + + Discontinuities in the value of this counter can occur at re- + initialization of the management system, and at other times as + indicated by the value of sctpAssocDiscontinuityTime." + REFERENCE + "Section 6 in RFC2960 covers the retransmission process and + rules." + + ::= { sctpAssocEntry 15 } + + + sctpAssocStartTime OBJECT-TYPE + SYNTAX TimeStamp + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of sysUpTime at the time that the association + represented by this row enters the ESTABLISHED state, i.e., + the sctpAssocState object is set to established(4). The + value of this object will be zero: + - before the association enters the established(4) + state, or + + + + +Pastor & Belinchon Standards Track [Page 25] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + - if the established(4) state was entered prior to + the last re-initialization of the local network management + subsystem." + + ::= { sctpAssocEntry 16 } + + sctpAssocDiscontinuityTime OBJECT-TYPE + SYNTAX TimeStamp + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of sysUpTime on the most recent occasion at which + any one or more of this SCTP association counters suffered a + discontinuity. The relevant counters are the specific + instances associated with this interface of any Counter32 or + Counter64 object contained in the sctpAssocTable or + sctpLocalAddrTable or sctpRemAddrTable. If no such + discontinuities have occurred since the last re-initialization + of the local management subsystem, then this object contains a + zero value. " + REFERENCE + "The inclusion of this object is recommended by RFC2578." + + ::= { sctpAssocEntry 17 } + + -- Expanded tables: Including Multi-home feature + + -- Local Address TABLE + -- ******************* + + sctpAssocLocalAddrTable OBJECT-TYPE + SYNTAX SEQUENCE OF SctpAssocLocalAddrEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Expanded table of sctpAssocTable based on the AssocId index. + This table shows data related to each local IP address which + is used by this association." + + ::= { sctpObjects 4 } + + sctpAssocLocalAddrEntry OBJECT-TYPE + SYNTAX SctpAssocLocalAddrEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Local information about the available addresses. There will + be an entry for every local IP address defined for this + + + +Pastor & Belinchon Standards Track [Page 26] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + association. + Implementors need to be aware that if the size of + sctpAssocLocalAddr exceeds 114 octets then OIDs of column + instances in this table will have more than 128 sub- + identifiers and cannot be accessed using SNMPv1, SNMPv2c, or + SNMPv3." + INDEX { sctpAssocId, -- shared index + sctpAssocLocalAddrType, + sctpAssocLocalAddr } + + ::= { sctpAssocLocalAddrTable 1 } + + + SctpAssocLocalAddrEntry ::= SEQUENCE { + sctpAssocLocalAddrType InetAddressType, + sctpAssocLocalAddr InetAddress, + sctpAssocLocalAddrStartTime TimeStamp + } + + + sctpAssocLocalAddrType OBJECT-TYPE + SYNTAX InetAddressType + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Internet type of local IP address used for this association." + + + ::= { sctpAssocLocalAddrEntry 1 } + + sctpAssocLocalAddr OBJECT-TYPE + SYNTAX InetAddress + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "The value of a local IP address available for this + association. The type of this address is determined by the + value of sctpAssocLocalAddrType." + + ::= { sctpAssocLocalAddrEntry 2 } + + + + + + + + + + + +Pastor & Belinchon Standards Track [Page 27] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + sctpAssocLocalAddrStartTime OBJECT-TYPE + SYNTAX TimeStamp + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of sysUpTime at the time that this row was + created." + + ::= { sctpAssocLocalAddrEntry 3 } + + -- Remote Addresses TABLE + -- ********************** + + sctpAssocRemAddrTable OBJECT-TYPE + SYNTAX SEQUENCE OF SctpAssocRemAddrEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Expanded table of sctpAssocTable based on the AssocId index. + This table shows data related to each remote peer IP address + which is used by this association." + + ::= { sctpObjects 5 } + + + sctpAssocRemAddrEntry OBJECT-TYPE + SYNTAX SctpAssocRemAddrEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Information about the most important variables for every + remote IP address. There will be an entry for every remote IP + address defined for this association. + + Implementors need to be aware that if the size of + sctpAssocRemAddr exceeds 114 octets then OIDs of column + instances in this table will have more than 128 sub- + identifiers and cannot be accessed using SNMPv1, SNMPv2c, or + SNMPv3." + INDEX { sctpAssocId, -- shared index + sctpAssocRemAddrType, + sctpAssocRemAddr } + + ::= { sctpAssocRemAddrTable 1 } + + + + + + + +Pastor & Belinchon Standards Track [Page 28] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + SctpAssocRemAddrEntry ::= SEQUENCE { + sctpAssocRemAddrType InetAddressType, + sctpAssocRemAddr InetAddress, + sctpAssocRemAddrActive TruthValue, + sctpAssocRemAddrHBActive TruthValue, + sctpAssocRemAddrRTO Unsigned32, + sctpAssocRemAddrMaxPathRtx Unsigned32, + sctpAssocRemAddrRtx Counter32, -- Statistic + sctpAssocRemAddrStartTime TimeStamp + } + + + sctpAssocRemAddrType OBJECT-TYPE + SYNTAX InetAddressType + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Internet type of a remote IP address available for this + association." + ::= { sctpAssocRemAddrEntry 1 } + + + sctpAssocRemAddr OBJECT-TYPE + SYNTAX InetAddress + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "The value of a remote IP address available for this + association. The type of this address is determined by the + value of sctpAssocLocalAddrType." + + ::= { sctpAssocRemAddrEntry 2 } + + + sctpAssocRemAddrActive OBJECT-TYPE + SYNTAX TruthValue + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "This object gives information about the reachability of this + specific remote IP address. + + When the object is set to 'true' (1), the remote IP address is + understood as Active. Active means that the threshold of no + answers received from this IP address has not been reached. + + + + + + +Pastor & Belinchon Standards Track [Page 29] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + When the object is set to 'false' (2), the remote IP address + is understood as Inactive. Inactive means that either no + heartbeat or any other message was received from this address, + reaching the threshold defined by the protocol." + + REFERENCE + "The remote transport states are defined as Active and + Inactive in the SCTP, RFC2960." + + ::= { sctpAssocRemAddrEntry 3 } + + + sctpAssocRemAddrHBActive OBJECT-TYPE + SYNTAX TruthValue + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "This object indicates whether the optional Heartbeat check + associated to one destination transport address is activated + or not (value equal to true or false, respectively). " + + ::= { sctpAssocRemAddrEntry 4 } + + + sctpAssocRemAddrRTO OBJECT-TYPE -- T3-rtx- Timer + SYNTAX Unsigned32 + UNITS "milliseconds" + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The current Retransmission Timeout. T3-rtx timer as defined + in the protocol SCTP." + REFERENCE + "Section 6.3 in RFC2960 deals with the Retransmission Timer + Management." + + ::= { sctpAssocRemAddrEntry 5 } + + + sctpAssocRemAddrMaxPathRtx OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Maximum number of DATA chunks retransmissions allowed to a + remote IP address before it is considered inactive, as defined + in RFC2960." + + + + +Pastor & Belinchon Standards Track [Page 30] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + REFERENCE + "Section 8.2, 8.3 and 14 in RFC2960." + DEFVAL {5} -- number of attempts + + ::= { sctpAssocRemAddrEntry 6 } + + + -- Remote Address Statistic + + sctpAssocRemAddrRtx OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of DATA chunks retransmissions to this specific IP + address. When T3-rtx expires, the DATA chunk that triggered + the T3 timer will be re-sent according to the retransmissions + rules. Every DATA chunk that is included in a SCTP packet and + was transmitted to this specific IP address before, will be + included in this counter. + + Discontinuities in the value of this counter can occur at re- + initialization of the management system, and at other times as + indicated by the value of sctpAssocDiscontinuityTime." + + ::= { sctpAssocRemAddrEntry 7 } + + sctpAssocRemAddrStartTime OBJECT-TYPE + SYNTAX TimeStamp + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of sysUpTime at the time that this row was + created." + + ::= { sctpAssocRemAddrEntry 8 } + + -- ASSOCIATION INVERSE TABLE + -- ************************* + + -- BY LOCAL PORT + + sctpLookupLocalPortTable OBJECT-TYPE + SYNTAX SEQUENCE OF SctpLookupLocalPortEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "With the use of this table, a list of associations which are + + + +Pastor & Belinchon Standards Track [Page 31] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + using the specified local port can be retrieved." + + ::= { sctpObjects 6 } + + + sctpLookupLocalPortEntry OBJECT-TYPE + SYNTAX SctpLookupLocalPortEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This table is indexed by local port and association ID. + Specifying a local port, we would get a list of the + associations whose local port is the one specified." + + INDEX { sctpAssocLocalPort, + sctpAssocId } + + ::= { sctpLookupLocalPortTable 1 } + + + SctpLookupLocalPortEntry::= SEQUENCE { + sctpLookupLocalPortStartTime TimeStamp + } + + + sctpLookupLocalPortStartTime OBJECT-TYPE + SYNTAX TimeStamp + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of sysUpTime at the time that this row was created. + + As the table will be created after the sctpAssocTable + creation, this value could be equal to the sctpAssocStartTime + object from the main table." + + ::= { sctpLookupLocalPortEntry 1 } + + -- BY REMOTE PORT + + sctpLookupRemPortTable OBJECT-TYPE + SYNTAX SEQUENCE OF SctpLookupRemPortEntry + MAX-ACCESS not-accessible + STATUS current + + + + + + + +Pastor & Belinchon Standards Track [Page 32] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + DESCRIPTION + "With the use of this table, a list of associations which are + using the specified remote port can be got" + + ::= { sctpObjects 7 } + + sctpLookupRemPortEntry OBJECT-TYPE + SYNTAX SctpLookupRemPortEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This table is indexed by remote port and association ID. + Specifying a remote port we would get a list of the + associations whose local port is the one specified " + + INDEX { sctpAssocRemPort, + sctpAssocId } + + ::= { sctpLookupRemPortTable 1 } + + SctpLookupRemPortEntry::= SEQUENCE { + sctpLookupRemPortStartTime TimeStamp + } + + + sctpLookupRemPortStartTime OBJECT-TYPE + SYNTAX TimeStamp + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of sysUpTime at the time that this row was created. + + As the table will be created after the sctpAssocTable + creation, this value could be equal to the sctpAssocStartTime + object from the main table." + + ::= { sctpLookupRemPortEntry 1 } + + -- BY REMOTE HOST NAME + + sctpLookupRemHostNameTable OBJECT-TYPE + SYNTAX SEQUENCE OF SctpLookupRemHostNameEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "With the use of this table, a list of associations with that + particular host can be retrieved." + + + + +Pastor & Belinchon Standards Track [Page 33] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + ::= { sctpObjects 8 } + + + sctpLookupRemHostNameEntry OBJECT-TYPE + SYNTAX SctpLookupRemHostNameEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This table is indexed by remote host name and association ID. + Specifying a host name we would get a list of the associations + specifying that host name as the remote one. + + Implementors need to be aware that if the size of + sctpAssocRemHostName exceeds 115 octets then OIDs of column + instances in this table will have more than 128 sub- + identifiers and cannot be accessed using SNMPv1, SNMPv2c, or + SNMPv3." + + INDEX { sctpAssocRemHostName, + sctpAssocId } + + ::= { sctpLookupRemHostNameTable 1 } + + + SctpLookupRemHostNameEntry::= SEQUENCE { + sctpLookupRemHostNameStartTime TimeStamp + } + + sctpLookupRemHostNameStartTime OBJECT-TYPE + SYNTAX TimeStamp + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of sysUpTime at the time that this row was created. + + As the table will be created after the sctpAssocTable + creation, this value could be equal to the sctpAssocStartTime + object from the main table." + + ::= { sctpLookupRemHostNameEntry 1 } + + + + + + + + + + + +Pastor & Belinchon Standards Track [Page 34] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + -- BY REMOTE PRIMARY IP ADDRESS + + sctpLookupRemPrimIPAddrTable OBJECT-TYPE + SYNTAX SEQUENCE OF SctpLookupRemPrimIPAddrEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "With the use of this table, a list of associations that have + the specified IP address as primary within the remote set of + active addresses can be retrieved." + + ::= { sctpObjects 9 } + + + sctpLookupRemPrimIPAddrEntry OBJECT-TYPE + SYNTAX SctpLookupRemPrimIPAddrEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This table is indexed by primary address and association ID. + Specifying a primary address, we would get a list of the + associations that have the specified remote IP address marked + as primary. + Implementors need to be aware that if the size of + sctpAssocRemPrimAddr exceeds 114 octets then OIDs of column + instances in this table will have more than 128 sub- + identifiers and cannot be accessed using SNMPv1, SNMPv2c, or + SNMPv3." + + INDEX { sctpAssocRemPrimAddrType, + sctpAssocRemPrimAddr, + sctpAssocId } + + ::= { sctpLookupRemPrimIPAddrTable 1 } + + SctpLookupRemPrimIPAddrEntry::= SEQUENCE { + sctpLookupRemPrimIPAddrStartTime TimeStamp + } + + + sctpLookupRemPrimIPAddrStartTime OBJECT-TYPE + SYNTAX TimeStamp + MAX-ACCESS read-only + STATUS current + + + + + + + +Pastor & Belinchon Standards Track [Page 35] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + DESCRIPTION + "The value of SysUpTime at the time that this row was created. + + As the table will be created after the sctpAssocTable + creation, this value could be equal to the sctpAssocStartTime + object from the main table." + + ::= { sctpLookupRemPrimIPAddrEntry 1 } + + + -- BY REMOTE IP ADDRESS + + sctpLookupRemIPAddrTable OBJECT-TYPE + SYNTAX SEQUENCE OF SctpLookupRemIPAddrEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "With the use of this table, a list of associations that have + the specified IP address as one of the remote ones can be + retrieved. " + + ::= { sctpObjects 10 } + + + sctpLookupRemIPAddrEntry OBJECT-TYPE + SYNTAX SctpLookupRemIPAddrEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This table is indexed by a remote IP address and association + ID. Specifying an IP address we would get a list of the + associations that have the specified IP address included + within the set of remote IP addresses." + + INDEX { sctpAssocRemAddrType, + sctpAssocRemAddr, + sctpAssocId } + + ::= { sctpLookupRemIPAddrTable 1 } + + + SctpLookupRemIPAddrEntry::= SEQUENCE { + + sctpLookupRemIPAddrStartTime TimeStamp + } + + + + + + +Pastor & Belinchon Standards Track [Page 36] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + sctpLookupRemIPAddrStartTime OBJECT-TYPE + SYNTAX TimeStamp + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of SysUpTime at the time that this row was created. + + As the table will be created after the sctpAssocTable + creation, this value could be equal to the sctpAssocStartTime + object from the main table." + + ::= { sctpLookupRemIPAddrEntry 1 } + + + -- 4.1 Conformance Information + + sctpMibConformance OBJECT IDENTIFIER ::= { sctpMIB 2 } + sctpMibCompliances OBJECT IDENTIFIER ::= { sctpMibConformance 1 } + sctpMibGroups OBJECT IDENTIFIER ::= { sctpMibConformance 2 } + + + -- 4.1.1 Units of conformance + + -- + -- MODULE GROUPS + -- + + sctpLayerParamsGroup OBJECT-GROUP + OBJECTS { sctpRtoAlgorithm, + sctpRtoMin, + sctpRtoMax, + sctpRtoInitial, + sctpMaxAssocs, + sctpValCookieLife, + sctpMaxInitRetr + } + + STATUS current + DESCRIPTION + "Common parameters for the SCTP layer, i.e., for all the + associations. They can usually be referred to as configuration + parameters." + + ::= { sctpMibGroups 1 } + + + + + + + +Pastor & Belinchon Standards Track [Page 37] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + sctpStatsGroup OBJECT-GROUP + OBJECTS { sctpCurrEstab, + sctpActiveEstabs, + sctpPassiveEstabs, + sctpAborteds, + sctpShutdowns, + sctpOutOfBlues, + sctpChecksumErrors, + sctpOutCtrlChunks, + sctpOutOrderChunks, + sctpOutUnorderChunks, + sctpInCtrlChunks, + sctpInOrderChunks, + sctpInUnorderChunks, + sctpFragUsrMsgs, + sctpReasmUsrMsgs, + sctpOutSCTPPacks, + sctpInSCTPPacks, + sctpDiscontinuityTime, + sctpAssocT1expireds, + sctpAssocT2expireds, + sctpAssocRtxChunks, + sctpAssocRemAddrRtx + } + + STATUS current + DESCRIPTION + "Statistics group. It includes the objects to collect state + changes in the SCTP protocol local layer and flow control + statistics." + + ::= { sctpMibGroups 2 } + + + sctpPerAssocParamsGroup OBJECT-GROUP + OBJECTS { sctpAssocRemHostName, + sctpAssocLocalPort, + sctpAssocRemPort, + sctpAssocRemPrimAddrType, + sctpAssocRemPrimAddr, + sctpAssocHeartBeatInterval, + sctpAssocState, + sctpAssocInStreams, + sctpAssocOutStreams, + sctpAssocMaxRetr, + sctpAssocPrimProcess, + sctpAssocStartTime, + sctpAssocDiscontinuityTime, + + + +Pastor & Belinchon Standards Track [Page 38] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + sctpAssocLocalAddrStartTime, + sctpAssocRemAddrActive, + sctpAssocRemAddrHBActive, + sctpAssocRemAddrRTO, + sctpAssocRemAddrMaxPathRtx, + sctpAssocRemAddrStartTime + } + + STATUS current + DESCRIPTION + "The SCTP group of objects to manage per-association + parameters. These variables include all the SCTP basic + features." + + ::= { sctpMibGroups 3 } + + sctpPerAssocStatsGroup OBJECT-GROUP + OBJECTS + { sctpAssocT1expireds, + sctpAssocT2expireds, + sctpAssocRtxChunks, + sctpAssocRemAddrRtx + } + + STATUS current + DESCRIPTION + "Per Association Statistics group. It includes the objects to + collect flow control statistics per association." + + ::= { sctpMibGroups 4 } + + sctpInverseGroup OBJECT-GROUP + OBJECTS { sctpLookupLocalPortStartTime, + sctpLookupRemPortStartTime, + sctpLookupRemHostNameStartTime, + sctpLookupRemPrimIPAddrStartTime, + sctpLookupRemIPAddrStartTime + } + + STATUS current + DESCRIPTION + "Objects used in the inverse lookup tables." + + ::= { sctpMibGroups 5 } + + + + + + + +Pastor & Belinchon Standards Track [Page 39] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + -- 4.1.2 Compliance Statements + + -- + -- MODULE COMPLIANCES + -- + + sctpMibCompliance MODULE-COMPLIANCE + STATUS current + DESCRIPTION + "The compliance statement for SNMP entities which implement + this SCTP MIB Module. + + There are a number of INDEX objects that cannot be represented + in the form of OBJECT clauses in SMIv2, but for which we have + the following compliance requirements, expressed in OBJECT + clause form in this description clause: + + -- OBJECT sctpAssocLocalAddrType + -- SYNTAX InetAddressType {ipv4(1), ipv6(2)} + -- DESCRIPTION + -- It is only required to have IPv4 and IPv6 addresses without + -- zone indices. + -- The address with zone indices is required if an + -- implementation can connect multiple zones. + -- + -- OBJECT sctpAssocLocalAddr + -- SYNTAX InetAddress (SIZE(4|16)) + -- DESCRIPTION + -- An implementation is only required to support globally + -- unique IPv4 and IPv6 addresses. + -- + -- OBJECT sctpAssocRemAddrType + -- SYNTAX InetAddressType {ipv4(1), ipv6(2)} + -- DESCRIPTION + -- It is only required to have IPv4 and IPv6 addresses without + -- zone indices. + -- The address with zone indices is required if an + -- implementation can connect multiple zones. + -- + -- OBJECT sctpAssocRemAddr + -- SYNTAX InetAddress (SIZE(4|16)) + -- DESCRIPTION + -- An implementation is only required to support globally + -- unique IPv4 and IPv6 addresses. + -- + " -- closes DESCRIPTION clause of MODULE-COMPLIANCE + + MODULE -- this module + + + +Pastor & Belinchon Standards Track [Page 40] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + MANDATORY-GROUPS { sctpLayerParamsGroup, + sctpPerAssocParamsGroup, + sctpStatsGroup, + sctpPerAssocStatsGroup + } + + OBJECT sctpAssocRemPrimAddrType + SYNTAX InetAddressType { ipv4(1), + ipv6(2) + } + DESCRIPTION + "It is only required to have IPv4 and IPv6 addresses + without zone indices. + + The address with zone indices is required if an + implementation can connect multiple zones." + + OBJECT sctpAssocRemPrimAddr + SYNTAX InetAddress (SIZE(4|16)) + DESCRIPTION + "An implementation is only required to support globally + unique IPv4 and globally unique IPv6 addresses." + + + OBJECT sctpAssocState + WRITE-SYNTAX INTEGER { deleteTCB(9) } + MIN-ACCESS read-only + DESCRIPTION + "Only the deleteTCB(9) value MAY be set by a management + station at most. A read-only option is also considered to + be compliant with this MIB module description." + + GROUP sctpInverseGroup + DESCRIPTION + "Objects used in inverse lookup tables. This should be + implemented, at the discretion of the implementers, for + easier lookups in the association tables" + + ::= { sctpMibCompliances 1 } + + END + + + + + + + + + + +Pastor & Belinchon Standards Track [Page 41] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + +5. Compiling Notes + + When compiling the MIB module warnings similar to the following may + occur: + + - warning: index of row `sctpAssocLocalAddrEntry' can exceed OID + size limit by 141 subidentifier(s) + - warning: index of row `sctpAssocRemAddrEntry' can exceed OID + size limit by 141 subidentifier(s) + - warning: index of row `sctpLookupRemHostNameEntry' can exceed + OID size limit by 140 subidentifier(s) + - warning: index of row `sctpLookupRemPrimIPAddrEntry' can exceed + OID size limit by 141 subidentifier(s) + - warning: index of row `sctpLookupRemIPAddrEntry' can exceed OID + size limit by 141 subidentifier(s) + + These warnings are due to the fact that the row objects have index + objects of type InetAddress or OCTET STRING whose size limit is 255 + octets, and if that size limit were reached the names of column + instances in those rows would exceed the 128 sub-identifier limit + imposed by current versions of the SNMP. Actual limitations for the + index object sizes are noted in the conceptual row DESCRIPTION + clauses. For the InetAddress index objects these size limits will + not be reached with any of the address types in current use. + +6. References + +6.1. Normative References + + [RFC2578] McCloghrie, K., Perkins, D., and J. Schoenwaelder, + "Structure of Management Information Version 2 (SMIv2)", + STD 58, RFC 2578, April 1999. + + [RFC2579] McCloghrie, K., Perkins, D., and J. Schoenwaelder, + "Textual Conventions for SMIv2", STD 58, RFC 2579, April + 1999. + + [RFC2580] McCloghrie, K., Perkins, D., and J. Schoenwaelder, + "Conformance Statements for SMIv2", STD 58, RFC 2580, + April 1999. + + [RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C., + Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M., + Zhang, L., and V. Paxson, "Stream Control Transmission + Protocol", RFC 2960, October 2000. + + + + + + +Pastor & Belinchon Standards Track [Page 42] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + [RFC3291] Daniele, M., Haberman, B., Routhier, S., and J. + Schoenwaelder, "Textual Conventions for Internet Network + Addresses", RFC 3291, May 2002. + + [RFC3309] Stone, J., Stewart, R., and D. Otis, "Stream Control + Transmission Protocol (SCTP) Checksum Change", RFC 3309, + September 2002. + +6.2. Informative References + + [RFC1213] McCloghrie, K. and M. Rose, "Management Information Base + for Network Management of TCP/IP-based internets:MIB- + II", STD 17, RFC 1213, March 1991. + + [RFC2012] McCloghrie, K., "SNMPv2 Management Information Base for + the Transmission Control Protocol using SMIv2", RFC + 2012, November 1996. + + [RFC3410] Case, J., Mundy, R., Partain, D., and B. Stewart, + "Introduction and Applicability Statements for + Internet-Standard Management Framework", RFC 3410, + December 2002. + + [VANJ] Jacobson, V., "Congestion Avoidance and Control", + SIGCOMM 1988, Stanford, California. + + [IPv6ARCH] Deering, S., Haberman, B., Jinmei, T., Nordmark, E., + Onoe, A., and B. Zill, "IPv6 Scoped Address + Architecture", Work in Progress, December 2002. + + [sctpImplem] Stewart, R., Ong, L., Arias-Rodriguez, I., Caro, A., and + M. Tuexen, "Stream Control Transmission Protocol (SCTP) + Implementers Guide", Work in Progress, January 2002. + + [TCPMIB] Fenner, B., McCloghrie, K., Raghunarayan, R., and J. + Schoenwalder, "Management Information Base for the + Transmission Control Protocol (TCP)", Work in Progress, + November 2002. + + [UDPMIB] Fenner, B., "Management Information Base for User + Datagram Protocol (UDP)", Work in Progress, June 2002. + + [MIBGUIDE] Heard, C.M., "Guidelines for MIB Authors and Reviewers", + Work in Progress, February 2003. + + + + + + + +Pastor & Belinchon Standards Track [Page 43] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + +7. Security Considerations + + There are management objects defined in this MIB that have a MAX- + ACCESS clause of read-write and/or read-create. Such objects may be + considered sensitive or vulnerable in some network environments. The + support for SET operations in a non-secure environment without proper + protection can have a negative effect on network operations. These + are the tables and objects and their sensitivity/vulnerability: + + o The sctpAssocState object has a MAX-ACCESS clause of read-write, + which allows termination of an arbitrary connection. Unauthorized + access could cause a denial of service. + + Some of the readable objects in this MIB module (i.e., objects with a + MAX-ACCESS other than not-accessible) may be considered sensitive or + vulnerable in some network environments. Thus, it is important to + control even GET and/or NOTIFY access to these objects and possibly + to even encrypt the values of these objects when sending them over + the network via SNMP. These are the tables and objects and their + sensitivity/vulnerability: + + o The sctpAssocTable, sctpAssocLocalAddressTable, + sctpAssocRemAddressTable and the lookup tables contain objects + providing information on the active associations on the device, + local and peer's IP addresses, the status of these associations + and the associated processes. This information may be used by an + attacker to launch attacks against known/unknown weakness in + certain protocols/applications. + + o The sctpAssocTable contains objects providing information on local + and remote ports objects, that can be used to identify what ports + are open on the machine and can thus suggest what attacks are + likely to succeed, without the attacker having to run a port + scanner. + + SNMP versions prior to SNMPv3 did not include adequate security. + Even if the network itself is secure (for example by using IPSec), + even then, there is no control as to who on the secure network is + allowed to access and GET/SET (read/change/create/delete) the objects + in this MIB module. + + It is RECOMMENDED that implementers consider the security features as + provided by the SNMPv3 framework (see [RFC3410], section 8), + including full support for the SNMPv3 cryptographic mechanisms (for + authentication and privacy). + + + + + + +Pastor & Belinchon Standards Track [Page 44] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + + Further, deployment of SNMP versions prior to SNMPv3 is NOT + RECOMMENDED. Instead, it is RECOMMENDED to deploy SNMPv3 and to + enable cryptographic security. It is then a customer/operator + responsibility to ensure that the SNMP entity giving access to an + instance of this MIB module is properly configured to give access to + the objects only to those principals (users) that have legitimate + rights to indeed GET or SET (change/create/delete) them. + + The above objects also have privacy implications, i.e., they disclose + who is connecting to what hosts. These are sensitive from a + perspective of preventing traffic analysis, and also to protect + individual privacy. + +8. Acknowledgments + + The authors wish to thank Juergen Schoenwaelder, David Partain, Shawn + A. Routhier, Ed Yarwood, John Linton, Shyamal Prasad, Juan-Francisco + Martin, Dave Thaler, and Bert Wijnen for their invaluable comments. + +9. Authors' Addresses + + Javier Pastor-Balbas + Ericsson Espana S.A. + Network Signaling System Management + Via de los Poblados 13 + Madrid, 28033 + Spain + + Phone: +34-91-339-1397 + EMail: J.Javier.Pastor@ericsson.com + + + Maria-Carmen Belinchon + Ericsson Espana S.A. + Network Signaling System Management + Via de los Poblados 13 + Madrid, 28033 + Spain + + Phone: +34-91-339-3535 + EMail: maria.carmen.belinchon@ericsson.com + + + + + + + + + + +Pastor & Belinchon Standards Track [Page 45] + +RFC 3873 SCTP MIB using SMIv2 September 2004 + + +10. Full Copyright Statement + + Copyright (C) The Internet Society (2004). + + This document is subject to the rights, licenses and restrictions + contained in BCP 78, and except as set forth therein, the authors + retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/S HE + REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE + INTERNET ENGINEERING TASK FORCE DISCLAIM 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. + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the IETF's procedures with respect to rights in IETF Documents can + be found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at ietf- + ipr@ietf.org. + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + + + + +Pastor & Belinchon Standards Track [Page 46] + diff --git a/doc/rfc4460.txt b/doc/rfc4460.txt new file mode 100644 index 0000000..1345b19 --- /dev/null +++ b/doc/rfc4460.txt @@ -0,0 +1,6107 @@ + + + + + + +Network Working Group R. Stewart +Request for Comments: 4460 Cisco Systems, Inc. +Category: Informational I. Arias-Rodriguez + Nokia Research Center + K. Poon + Sun Microsystems, Inc. + A. Caro + BBN Technologies + M. Tuexen + Muenster Univ. of Applied Sciences + April 2006 + + + Stream Control Transmission Protocol (SCTP) Specification + Errata and Issues + + +Status of This Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2006). + +Abstract + + This document is a compilation of issues found during six + interoperability events and 5 years of experience with implementing, + testing, and using Stream Control Transmission Protocol (SCTP) along + with the suggested fixes. This document provides deltas to RFC 2960 + and is organized in a time-based way. The issues are listed in the + order they were brought up. Because some text is changed several + times, the last delta in the text is the one that should be applied. + In addition to the delta, a description of the problem and the + details of the solution are also provided. + +Table of Contents + + 1. Introduction ....................................................6 + 1.1. Conventions ................................................7 + 2. Corrections to RFC 2960 .........................................7 + 2.1. Incorrect Error Type During Chunk Processing. ..............7 + 2.1.1. Description of the Problem ..........................7 + 2.1.2. Text changes to the document ........................7 + 2.1.3. Solution Description ................................7 + + + +Stewart, et al. Informational [Page 1] + +RFC 4460 SCTP Errata April 2006 + + + 2.2. Parameter Processing Issue .................................7 + 2.2.1. Description of the Problem ..........................7 + 2.2.2. Text Changes to the Document ........................8 + 2.2.3. Solution Description ................................8 + 2.3. Padding Issues .............................................8 + 2.3.1. Description of the Problem ..........................8 + 2.3.2. Text Changes to the Document ........................9 + 2.3.3. Solution Description ...............................10 + 2.4. Parameter Types across All Chunk Types ....................10 + 2.4.1. Description of the Problem .........................10 + 2.4.2. Text Changes to the Document .......................10 + 2.4.3. Solution Description ...............................12 + 2.5. Stream Parameter Clarification ............................12 + 2.5.1. Description of the problem .........................12 + 2.5.2. Text Changes to the Document .......................12 + 2.5.3. Solution Description ...............................13 + 2.6. Restarting Association Security Issue .....................13 + 2.6.1. Description of the Problem .........................13 + 2.6.2. Text Changes to the Document .......................14 + 2.6.3. Solution Description ...............................18 + 2.7. Implicit Ability to Exceed cwnd by PMTU-1 Bytes ...........19 + 2.7.1. Description of the Problem .........................19 + 2.7.2. Text Changes to the Document .......................19 + 2.7.3. Solution Description ...............................19 + 2.8. Issues with Fast Retransmit ...............................19 + 2.8.1. Description of the Problem .........................19 + 2.8.2. Text Changes to the Document .......................20 + 2.8.3. Solution Description ...............................23 + 2.9. Missing Statement about partial_bytes_acked Update ........24 + 2.9.1. Description of the Problem .........................24 + 2.9.2. Text Changes to the Document .......................24 + 2.9.3. Solution Description ...............................25 + 2.10. Issues with Heartbeating and Failure Detection ...........25 + 2.10.1. Description of the Problem ........................25 + 2.10.2. Text Changes to the Document ......................26 + 2.10.3. Solution Description ..............................28 + 2.11. Security interactions with firewalls .....................29 + 2.11.1. Description of the Problem ........................29 + 2.11.2. Text Changes to the Document ......................29 + 2.11.3. Solution Description ..............................31 + 2.12. Shutdown Ambiguity .......................................31 + 2.12.1. Description of the Problem ........................31 + 2.12.2. Text Changes to the Document ......................31 + 2.12.3. Solution Description ..............................32 + 2.13. Inconsistency in ABORT Processing ........................32 + 2.13.1. Description of the Problem ........................32 + 2.13.2. Text changes to the document ......................33 + 2.13.3. Solution Description ..............................33 + + + +Stewart, et al. Informational [Page 2] + +RFC 4460 SCTP Errata April 2006 + + + 2.14. Cwnd Gated by Its Full Use ...............................34 + 2.14.1. Description of the Problem ........................34 + 2.14.2. Text Changes to the Document ......................34 + 2.14.3. Solution Description ..............................36 + 2.15. Window Probes in SCTP ....................................36 + 2.15.1. Description of the Problem ........................36 + 2.15.2. Text Changes to the Document ......................36 + 2.15.3. Solution Description ..............................38 + 2.16. Fragmentation and Path MTU Issues ........................39 + 2.16.1. Description of the Problem ........................39 + 2.16.2. Text Changes to the Document ......................39 + 2.16.3. Solution Description ..............................40 + 2.17. Initial Value of the Cumulative TSN Ack ..................40 + 2.17.1. Description of the Problem ........................40 + 2.17.2. Text Changes to the Document ......................40 + 2.17.3. Solution Description ..............................41 + 2.18. Handling of Address Parameters within the INIT or + INIT-ACK .................................................41 + 2.18.1. Description of the Problem ........................41 + 2.18.2. Text Changes to the Document ......................41 + 2.18.3. Solution description ..............................42 + 2.19. Handling of Stream Shortages .............................42 + 2.19.1. Description of the Problem ........................42 + 2.19.2. Text Changes to the Document ......................42 + 2.19.3. Solution Description ..............................43 + 2.20. Indefinite Postponement ..................................43 + 2.20.1. Description of the Problem ........................43 + 2.20.2. Text Changes to the Document ......................43 + 2.20.3. Solution Description ..............................44 + 2.21. User-Initiated Abort of an Association ...................44 + 2.21.1. Description of the Problem ........................44 + 2.21.2. Text changes to the document ......................44 + 2.21.3. Solution Description ..............................50 + 2.22. Handling of Invalid Initiate Tag of INIT-ACK .............50 + 2.22.1. Description of the Problem ........................50 + 2.22.2. Text Changes to the Document ......................50 + 2.22.3. Solution Description ..............................51 + 2.23. Sending an ABORT in Response to an INIT ..................51 + 2.23.1. Description of the Problem ........................51 + 2.23.2. Text Changes to the Document ......................51 + 2.23.3. Solution Description ..............................52 + 2.24. Stream Sequence Number (SSN) Initialization ..............52 + 2.24.1. Description of the Problem ........................52 + 2.24.2. Text Changes to the Document ......................52 + 2.24.3. Solution Description ..............................53 + 2.25. SACK Packet Format .......................................53 + 2.25.1. Description of the Problem ........................53 + 2.25.2. Text Changes to the Document ......................53 + + + +Stewart, et al. Informational [Page 3] + +RFC 4460 SCTP Errata April 2006 + + + 2.25.3. Solution Description ..............................53 + 2.26. Protocol Violation Error Cause ...........................53 + 2.26.1. Description of the Problem ........................53 + 2.26.2. Text Changes to the Document ......................54 + 2.26.3. Solution Description ..............................56 + 2.27. Reporting of Unrecognized Parameters .....................56 + 2.27.1. Description of the Problem ........................56 + 2.27.2. Text Changes to the Document ......................56 + 2.27.3. Solution Description ..............................57 + 2.28. Handling of IP Address Parameters ........................58 + 2.28.1. Description of the Problem ........................58 + 2.28.2. Text Changes to the Document ......................58 + 2.28.3. Solution Description ..............................58 + 2.29. Handling of COOKIE ECHO Chunks When a TCB Exists .........59 + 2.29.1. Description of the Problem ........................59 + 2.29.2. Text Changes to the Document ......................59 + 2.29.3. Solution Description ..............................59 + 2.30. The Initial Congestion Window Size .......................59 + 2.30.1. Description of the Problem ........................59 + 2.30.2. Text Changes to the Document ......................60 + 2.30.3. Solution Description ..............................61 + 2.31. Stream Sequence Numbers in Figures .......................62 + 2.31.1. Description of the Problem ........................62 + 2.31.2. Text Changes to the Document ......................63 + 2.31.3. Solution description ..............................67 + 2.32. Unrecognized Parameters ..................................67 + 2.32.1. Description of the Problem ........................67 + 2.32.2. Text Changes to the Document ......................67 + 2.32.3. Solution Description ..............................68 + 2.33. Handling of Unrecognized Parameters ......................68 + 2.33.1. Description of the Problem ........................68 + 2.33.2. Text Changes to the Document ......................68 + 2.33.3. Solution Description ..............................70 + 2.34. Tie Tags .................................................70 + 2.34.1. Description of the Problem ........................70 + 2.34.2. Text Changes to the Document ......................70 + 2.34.3. Solution Description ..............................72 + 2.35. Port Number Verification in the COOKIE-ECHO ..............72 + 2.35.1. Description of the Problem ........................72 + 2.35.2. Text Changes to the Document ......................72 + 2.35.3. Solution Description ..............................73 + 2.36. Path Initialization ......................................74 + 2.36.1. Description of the Problem ........................74 + 2.36.2. Text Changes to the Document ......................74 + 2.36.3. Solution Description ..............................76 + 2.37. ICMP Handling Procedures .................................76 + 2.37.1. Description of the Problem ........................76 + 2.37.2. Text Changes to the Document ......................77 + + + +Stewart, et al. Informational [Page 4] + +RFC 4460 SCTP Errata April 2006 + + + 2.37.3. Solution Description ..............................79 + 2.38. Checksum .................................................79 + 2.38.1. Description of the problem ........................79 + 2.38.2. Text Changes to the Document ......................79 + 2.38.3. Solution Description ..............................86 + 2.39. Retransmission Policy ....................................86 + 2.39.1. Description of the Problem ........................86 + 2.39.2. Text Changes to the Document ......................87 + 2.39.3. Solution Description ..............................87 + 2.40. Port Number 0 ............................................88 + 2.40.1. Description of the Problem ........................88 + 2.40.2. Text Changes to the Document ......................88 + 2.40.3. Solution Description ..............................89 + 2.41. T Bit ....................................................89 + 2.41.1. Description of the Problem ........................89 + 2.41.2. Text Changes to the Document ......................89 + 2.41.3. Solution Description ..............................93 + 2.42. Unknown Parameter Handling ...............................93 + 2.42.1. Description of the Problem ........................93 + 2.42.2. Text Changes to the Document ......................93 + 2.42.3. Solution Description ..............................95 + 2.43. Cookie Echo Chunk ........................................95 + 2.43.1. Description of the Problem ........................95 + 2.43.2. Text Changes to the Document ......................95 + 2.43.3. Solution Description ..............................96 + 2.44. Partial Chunks ...........................................96 + 2.44.1. Description of the Problem ........................96 + 2.44.2. Text Changes to the Document ......................96 + 2.44.3. Solution Description ..............................97 + 2.45. Non-unicast Addresses ....................................97 + 2.45.1. Description of the Problem ........................97 + 2.45.2. Text Changes to the Document ......................97 + 2.45.3. Solution Description ..............................98 + 2.46. Processing of ABORT Chunks ...............................98 + 2.46.1. Description of the Problem ........................98 + 2.46.2. Text Changes to the Document ......................98 + 2.46.3. Solution Description ..............................98 + 2.47. Sending of ABORT Chunks ..................................99 + 2.47.1. Description of the Problem ........................99 + 2.47.2. Text Changes to the Document ......................99 + 2.47.3. Solution Description ..............................99 + 2.48. Handling of Supported Address Types Parameter ............99 + 2.48.1. Description of the Problem ........................99 + 2.48.2. Text Changes to the Document .....................100 + 2.48.3. Solution Description .............................100 + 2.49. Handling of Unexpected Parameters .......................101 + 2.49.1. Description of the Problem .......................101 + 2.49.2. Text Changes to the Document .....................101 + + + +Stewart, et al. Informational [Page 5] + +RFC 4460 SCTP Errata April 2006 + + + 2.49.3. Solution Description .............................102 + 2.50. Payload Protocol Identifier .............................102 + 2.50.1. Description of the Problem .......................102 + 2.50.2. Text Changes to the Document .....................103 + 2.50.3. Solution Description .............................103 + 2.51. Karn's Algorithm ........................................104 + 2.51.1. Description of the Problem .......................104 + 2.51.2. Text Changes to the Document .....................104 + 2.51.3. Solution Description .............................104 + 2.52. Fast Retransmit Algorithm ...............................104 + 2.52.1. Description of the Problem .......................104 + 2.52.2. Text Changes to the Document .....................105 + 2.52.3. Solution Description .............................105 + 3. Security Considerations .......................................105 + 4. Acknowledgements ..............................................106 + 5. IANA Considerations ...........................................106 + 6. Normative References ..........................................106 + +1. Introduction + + This document contains a compilation of all defects found up until + the publishing of this document for the Stream Control Transmission + Protocol (SCTP), RFC 2960 [5]. These defects may be of an editorial + or technical nature. This document may be thought of as a companion + document to be used in the implementation of SCTP to clarify errors + in the original SCTP document. + + This document provides a history of the changes that will be compiled + into RFC 2960's [5] BIS document. Each error will be detailed within + this document in the form of + + o the problem description, + + o the text quoted from RFC 2960 [5], + + o the replacement text that should be placed into the BIS document, + and + + o a description of the solution. + + This document is a historical record of sequential changes what have + been found necessary at various interop events and through discussion + on this list. + + Note that because some text is changed several times, the last delta + for a text in the document is the erratum for that text in RFC 2960. + + + + + +Stewart, et al. Informational [Page 6] + +RFC 4460 SCTP Errata April 2006 + + +1.1. Conventions + + The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, + SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when + they appear in this document, are to be interpreted as described in + RFC 2119 [2]. + +2. Corrections to RFC 2960 + +2.1. Incorrect Error Type During Chunk Processing. + +2.1.1. Description of the Problem + + A typo was discovered in RFC 2960 [5] that incorrectly specifies an + action to be taken when processing chunks of unknown identity. + +2.1.2. Text changes to the document + + --------- + Old text: (Section 3.2) + --------- + + 01 - Stop processing this SCTP packet and discard it, do not process + any further chunks within it, and report the unrecognized + parameter in an 'Unrecognized Parameter Type' (in either an + ERROR or in the INIT ACK). + + --------- + New text: (Section 3.2) + --------- + + 01 - Stop processing this SCTP packet and discard it, do not process + any further chunks within it, and report the unrecognized + chunk in an 'Unrecognized Chunk Type'. + +2.1.3. Solution Description + + The receiver of an unrecognized chunk should not send a 'parameter' + error but instead should send the appropriate chunk error as + described above. + +2.2. Parameter Processing Issue + +2.2.1. Description of the Problem + + A typographical error was introduced through an improper cut and + paste in the use of the upper two bits to describe proper handling of + unknown parameters. + + + +Stewart, et al. Informational [Page 7] + +RFC 4460 SCTP Errata April 2006 + + +2.2.2. Text Changes to the Document + + --------- + Old text: (Section 3.2.1) + --------- + + 00 - Stop processing this SCTP packet and discard it; do not process + any further chunks within it. + + 01 - Stop processing this SCTP packet and discard it, do not process + any further chunks within it, and report the unrecognized + parameter in an 'Unrecognized Parameter Type' (in either an + ERROR or in the INIT ACK). + + --------- + New text: (Section 3.2.1) + --------- + + 00 - Stop processing this SCTP chunk and discard it, do not process + any further parameters within this chunk. + + 01 - Stop processing this SCTP chunk and discard it, do not process + any further parameters within this chunk, and report the + unrecognized parameter in an 'Unrecognized Parameter Type' (in + either an ERROR or in the INIT ACK). + +2.2.3. Solution Description + + It was always the intent to stop processing at the level one was at + in an unknown chunk or parameter with the upper bit set to 0. Thus, + if you are processing a chunk, you should drop the packet. If you + are processing a parameter, you should drop the chunk. + +2.3. Padding Issues + +2.3.1. Description of the Problem + + A problem was found when a Chunk terminated in a TLV parameter. If + this last TLV was not on a 32-bit boundary (as required), there was + confusion as to whether the last padding was included in the chunk + length. + + + + + + + + + + +Stewart, et al. Informational [Page 8] + +RFC 4460 SCTP Errata April 2006 + + +2.3.2. Text Changes to the Document + + --------- + Old text: (Section 3.2) + --------- + + Chunk Length: 16 bits (unsigned integer) + + This value represents the size of the chunk in bytes including the + Chunk Type, Chunk Flags, Chunk Length, and Chunk Value fields. + Therefore, if the Chunk Value field is zero-length, the Length + field will be set to 4. The Chunk Length field does not count any + padding. + + Chunk Value: variable length + + The Chunk Value field contains the actual information to be + transferred in the chunk. The usage and format of this field is + dependent on the Chunk Type. + + The total length of a chunk (including Type, Length and Value fields) + MUST be a multiple of 4 bytes. If the length of the chunk is not a + multiple of 4 bytes, the sender MUST pad the chunk with all zero + bytes and this padding is not included in the chunk length field. + The sender should never pad with more than 3 bytes. The receiver + MUST ignore the padding bytes. + + --------- + New text: (Section 3.2) + --------- + + Chunk Length: 16 bits (unsigned integer) + + This value represents the size of the chunk in bytes, including + the Chunk Type, Chunk Flags, Chunk Length, and Chunk Value fields. + Therefore, if the Chunk Value field is zero-length, the Length + field will be set to 4. The Chunk Length field does not count any + chunk padding. + + Chunks (including Type, Length, and Value fields) are padded out + by the sender with all zero bytes to be a multiple of 4 bytes + long. This padding MUST NOT be more than 3 bytes in total. The + Chunk Length value does not include terminating padding of the + chunk. However, it does include padding of any variable-length + parameter except the last parameter in the chunk. The receiver + MUST ignore the padding. + + + + + +Stewart, et al. Informational [Page 9] + +RFC 4460 SCTP Errata April 2006 + + + Note: A robust implementation should accept the Chunk whether or + not the final padding has been included in the Chunk Length. + + Chunk Value: variable length + + The Chunk Value field contains the actual information to be + transferred in the chunk. The usage and format of this field is + dependent on the Chunk Type. + + The total length of a chunk (including Type, Length, and Value + fields) MUST be a multiple of 4 bytes. If the length of the chunk is + not a multiple of 4 bytes, the sender MUST pad the chunk with all + zero bytes, and this padding is not included in the chunk length + field. The sender should never pad with more than 3 bytes. The + receiver MUST ignore the padding bytes. + +2.3.3. Solution Description + + The above text makes clear that the padding of the last parameter is + not included in the Chunk Length field. It also clarifies that the + padding of parameters that are not the last one must be counted in + the Chunk Length field. + +2.4. Parameter Types across All Chunk Types + +2.4.1. Description of the Problem + + A problem was noted when multiple errors are needed to be sent + regarding unknown or unrecognized parameters. Since often the error + type does not hold the chunk type field, it may become difficult to + tell which error was associated with which chunk. + +2.4.2. Text Changes to the Document + + --------- + Old text: (Section 3.2.1) + --------- + + The actual SCTP parameters are defined in the specific SCTP chunk + sections. The rules for IETF-defined parameter extensions are + defined in Section 13.2. + + --------- + New text: (Section 3.2.1) + --------- + + The actual SCTP parameters are defined in the specific SCTP chunk + sections. The rules for IETF-defined parameter extensions are + + + +Stewart, et al. Informational [Page 10] + +RFC 4460 SCTP Errata April 2006 + + + defined in Section 13.2. Note that a parameter type MUST be unique + across all chunks. For example, the parameter type '5' is used to + represent an IPv4 address (see Section 3.3.2). The value '5' then is + reserved across all chunks to represent an IPv4 address and MUST NOT + be reused with a different meaning in any other chunk. + + --------- + Old text: (Section 13.2) + --------- + + 13.2 IETF-defined Chunk Parameter Extension + + The assignment of new chunk parameter type codes is done through an + IETF Consensus action as defined in [RFC2434]. Documentation of the + chunk parameter MUST contain the following information: + + a) Name of the parameter type. + + b) Detailed description of the structure of the parameter field. + This structure MUST conform to the general type-length-value + format described in Section 3.2.1. + + c) Detailed definition of each component of the parameter type. + + d) Detailed description of the intended use of this parameter type, + and an indication of whether and under what circumstances multiple + instances of this parameter type may be found within the same + chunk. + + --------- + New text: (Section 13.2) + --------- + + 13.2. IETF-defined Chunk Parameter Extension + + The assignment of new chunk parameter type codes is done through an + IETF Consensus action, as defined in [RFC2434]. Documentation of the + chunk parameter MUST contain the following information: + + a) Name of the parameter type. + + b) Detailed description of the structure of the parameter field. + This structure MUST conform to the general type-length-value + format described in Section 3.2.1. + + c) Detailed definition of each component of the parameter type. + + + + + +Stewart, et al. Informational [Page 11] + +RFC 4460 SCTP Errata April 2006 + + + d) Detailed description of the intended use of this parameter type, + and an indication of whether and under what circumstances multiple + instances of this parameter type may be found within the same + chunk. + + e) Each parameter type MUST be unique across all chunks. + +2.4.3. Solution Description + + By having all parameters unique across all chunk assignments (the + current assignment policy), no ambiguity exists as to what a + parameter means in different contexts. The trade-off for this is a + smaller parameter space, i.e., 65,536 parameters versus 65,536 * + Number-of- chunks. + +2.5. Stream Parameter Clarification + +2.5.1. Description of the problem + + A problem was found where the specification is unclear on the + legality of an endpoint asking for more stream resources than were + allowed in the MIS value of the INIT. In particular, the value in + the INIT ACK requested in its OS value was larger than the MIS value + received in the INIT chunk. This behavior is illegal, yet it was + unspecified in RFC 2960 [5] + +2.5.2. Text Changes to the Document + + --------- + Old text: (Section 3.3.3) + --------- + + Number of Outbound Streams (OS): 16 bits (unsigned integer) + + Defines the number of outbound streams the sender of this INIT ACK + chunk wishes to create in this association. The value of 0 MUST + NOT be used. + + Note: A receiver of an INIT ACK with the OS value set to 0 SHOULD + destroy the association discarding its TCB. + + + + + + + + + + + +Stewart, et al. Informational [Page 12] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 3.3.3) + --------- + + Number of Outbound Streams (OS): 16 bits (unsigned integer) + + Defines the number of outbound streams the sender of this INIT ACK + chunk wishes to create in this association. The value of 0 MUST + NOT be used, and the value MUST NOT be greater than the MIS value + sent in the INIT chunk. + + Note: A receiver of an INIT ACK with the OS value set to 0 SHOULD + destroy the association, discarding its TCB. + +2.5.3. Solution Description + + The change in wording, above, changes it so that a responder to an + INIT chunk does not specify more streams in its OS value than were + represented to it in the MIS value, i.e., its maximum. + +2.6. Restarting Association Security Issue + +2.6.1. Description of the Problem + + A security problem was found when a restart occurs. It is possible + for an intruder to send an INIT to an endpoint of an existing + association. In the INIT the intruder would list one or more of the + current addresses of an association and its own. The normal restart + procedures would then occur, and the intruder would have hijacked an + association. + + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Informational [Page 13] + +RFC 4460 SCTP Errata April 2006 + + +2.6.2. Text Changes to the Document + + --------- + Old text: (Section 3.3.10) + --------- + + Cause Code + Value Cause Code + --------- ---------------- + 1 Invalid Stream Identifier + 2 Missing Mandatory Parameter + 3 Stale Cookie Error + 4 Out of Resource + 5 Unresolvable Address + 6 Unrecognized Chunk Type + 7 Invalid Mandatory Parameter + 8 Unrecognized Parameters + 9 No User Data + 10 Cookie Received While Shutting Down + + Cause Length: 16 bits (unsigned integer) + + Set to the size of the parameter in bytes, including the Cause + Code, Cause Length, and Cause-Specific Information fields + + Cause-specific Information: variable length + + This field carries the details of the error condition. + + Sections 3.3.10.1 - 3.3.10.10 define error causes for SCTP. + + Guidelines for the IETF to define new error cause values are + discussed in Section 13.3. + + + + + + + + + + + + + + + + + + +Stewart, et al. Informational [Page 14] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 3.3.10) + --------- + + Cause Code + Value Cause Code + --------- ---------------- + 1 Invalid Stream Identifier + 2 Missing Mandatory Parameter + 3 Stale Cookie Error + 4 Out of Resource + 5 Unresolvable Address + 6 Unrecognized Chunk Type + 7 Invalid Mandatory Parameter + 8 Unrecognized Parameters + 9 No User Data + 10 Cookie Received While Shutting Down + 11 Restart of an Association with New Addresses + + Cause Length: 16 bits (unsigned integer) + + Set to the size of the parameter in bytes, including the Cause + Code, Cause Length, and Cause-Specific Information fields. + + Cause-specific Information: variable length + + This field carries the details of the error condition. + + Sections 3.3.10.1 - 3.3.10.11 define error causes for SCTP. + Guidelines for the IETF to define new error cause values are + discussed in Section 13.3. + + --------- + New text: (Note no old text, new error cause added in section 3.3.10) + --------- + + 3.3.10.11. Restart of an Association with New Addresses (11) + + Cause of error + -------------- + Restart of an association with new addresses: An INIT was received + on an existing association. But the INIT added addresses to the + association that were previously NOT part of the association. The + new addresses are listed in the error code. This ERROR is normally + sent as part of an ABORT refusing the INIT (see Section 5.2). + + + + + + +Stewart, et al. Informational [Page 15] + +RFC 4460 SCTP Errata April 2006 + + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=11 | Cause Length=Variable | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / New Address TLVs / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Note: Each New Address TLV is an exact copy of the TLV + that was found in the INIT chunk that was new, including the + Parameter Type and the Parameter length. + + --------- + Old text: (Section 5.2.1) + --------- + + Upon receipt of an INIT in the COOKIE-WAIT or COOKIE-ECHOED state, an + endpoint MUST respond with an INIT ACK using the same parameters it + sent in its original INIT chunk (including its Initiation Tag, + unchanged). These original parameters are combined with those from + the newly received INIT chunk. The endpoint shall also generate a + State Cookie with the INIT ACK. The endpoint uses the parameters + sent in its INIT to calculate the State Cookie. + + --------- + New text: (Section 5.2.1) + --------- + + Upon receipt of an INIT in the COOKIE-WAIT state, an endpoint MUST + respond with an INIT ACK using the same parameters it sent in its + original INIT chunk (including its Initiation Tag, unchanged). When + responding, the endpoint MUST send the INIT ACK back to the same + address that the original INIT (sent by this endpoint) was sent to. + + Upon receipt of an INIT in the COOKIE-ECHOED state, an endpoint MUST + respond with an INIT ACK using the same parameters it sent in its + original INIT chunk (including its Initiation Tag, unchanged), + provided that no NEW address has been added to the forming + association. If the INIT message indicates that a new address has + been added to the association, then the entire INIT MUST be + discarded, and NO changes should be made to the existing association. + An ABORT SHOULD be sent in response that MAY include the error + 'Restart of an association with new addresses'. The error SHOULD + list the addresses that were added to the restarting association. + + + + + + + + +Stewart, et al. Informational [Page 16] + +RFC 4460 SCTP Errata April 2006 + + + When responding in either state (COOKIE-WAIT or COOKIE-ECHOED) with + an INIT ACK, the original parameters are combined with those from the + newly received INIT chunk. The endpoint shall also generate a State + Cookie with the INIT ACK. The endpoint uses the parameters sent in + its INIT to calculate the State Cookie. + + --------- + Old text: (Section 5.2.2) + --------- + + 5.2.2 Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED, + COOKIE-WAIT and SHUTDOWN-ACK-SENT + + Unless otherwise stated, upon reception of an unexpected INIT for + this association, the endpoint shall generate an INIT ACK with a + State Cookie. In the outbound INIT ACK the endpoint MUST copy its + current Verification Tag and peer's Verification Tag into a reserved + place within the state cookie. We shall refer to these locations as + the Peer's-Tie-Tag and the Local-Tie-Tag. The outbound SCTP packet + containing this INIT ACK MUST carry a Verification Tag value equal to + the Initiation Tag found in the unexpected INIT. And the INIT ACK + MUST contain a new Initiation Tag (randomly generated see Section + 5.3.1). Other parameters for the endpoint SHOULD be copied from the + existing parameters of the association (e.g., number of outbound + streams) into the INIT ACK and cookie. + + After sending out the INIT ACK, the endpoint shall take no further + actions, i.e., the existing association, including its current state, + and the corresponding TCB MUST NOT be changed. + + Note: Only when a TCB exists and the association is not in a COOKIE- + WAIT state are the Tie-Tags populated. For a normal association INIT + (i.e., the endpoint is in a COOKIE-WAIT state), the Tie-Tags MUST be + set to 0 (indicating that no previous TCB existed). The INIT ACK and + State Cookie are populated as specified in section 5.2.1. + + --------- + New text: (Section 5.2.2) + --------- + + 5.2.2. Unexpected INIT in States Other Than CLOSED, COOKIE-ECHOED, + COOKIE-WAIT, and SHUTDOWN-ACK-SENT + + Unless otherwise stated, upon receipt of an unexpected INIT for this + association, the endpoint shall generate an INIT ACK with a State + Cookie. Before responding, the endpoint MUST check to see if the + unexpected INIT adds new addresses to the association. If new + addresses are added to the association, the endpoint MUST respond + + + +Stewart, et al. Informational [Page 17] + +RFC 4460 SCTP Errata April 2006 + + + with an ABORT, copying the 'Initiation Tag' of the unexpected INIT + into the 'Verification Tag' of the outbound packet carrying the + ABORT. In the ABORT response, the cause of error MAY be set to + 'restart of an association with new addresses'. The error SHOULD + list the addresses that were added to the restarting association. + + If no new addresses are added, when responding to the INIT in the + outbound INIT ACK, the endpoint MUST copy its current Verification + Tag and peer's Verification Tag into a reserved place within the + state cookie. We shall refer to these locations as the Peer's-Tie- + Tag and the Local-Tie-Tag. The outbound SCTP packet containing this + INIT ACK MUST carry a Verification Tag value equal to the Initiation + Tag found in the unexpected INIT. And the INIT ACK MUST contain a + new Initiation Tag (randomly generated; see Section 5.3.1). Other + parameters for the endpoint SHOULD be copied from the existing + parameters of the association (e.g., number of outbound streams) into + the INIT ACK and cookie. + + After sending out the INIT ACK or ABORT, the endpoint shall take no + further actions; i.e., the existing association, including its + current state, and the corresponding TCB MUST NOT be changed. + + Note: Only when a TCB exists and the association is not in a COOKIE- + WAIT or SHUTDOWN-ACK-SENT state are the Tie-Tags populated with a + value other than 0. For a normal association INIT (i.e., the + endpoint is in the CLOSED state), the Tie-Tags MUST be set to 0 + (indicating that no previous TCB existed). + +2.6.3. Solution Description + + A new error code is being added, along with specific instructions to + send back an ABORT to a new association in a restart case or + collision case, where new addresses have been added. The error code + can be used by a legitimate restart to inform the endpoint that it + has made a software error in adding a new address. The endpoint then + can choose to wait until the OOTB ABORT tears down the old + association, or to restart without the new address. + + Also, the note at the end of Section 5.2.2 explaining the use of the + Tie-Tags was modified to properly explain the states in which the + Tie-Tags should be set to a value different than 0. + + + + + + + + + + +Stewart, et al. Informational [Page 18] + +RFC 4460 SCTP Errata April 2006 + + +2.7. Implicit Ability to Exceed cwnd by PMTU-1 Bytes + +2.7.1. Description of the Problem + + Some implementations were having difficulty growing their cwnd. This + was due to an improper enforcement of the congestion control rules. + The rules, as written, provided for a slop over of the cwnd value. + Without this slop over, the sender would appear NOT to be using its + full cwnd value and thus would never increase it. + +2.7.2. Text Changes to the Document + + --------- + Old text: (Section 6.1) + --------- + + B) At any given time, the sender MUST NOT transmit new data to a + given transport address if it has cwnd or more bytes of data + outstanding to that transport address. + + --------- + New text: (Section 6.1) + --------- + + B) At any given time, the sender MUST NOT transmit new data to a + given transport address if it has cwnd or more bytes of data + outstanding to that transport address. The sender may exceed cwnd + by up to (PMTU-1) bytes on a new transmission if the cwnd is not + currently exceeded. + +2.7.3. Solution Description + + The text changes make clear the ability to go over the cwnd value by + no more than (PMTU-1) bytes. + +2.8. Issues with Fast Retransmit + +2.8.1. Description of the Problem + + Several problems were found in the current specification of fast + retransmit. The current wording did not require GAP ACK blocks to be + sent, even though they are essential to the workings of SCTP's + congestion control. The specification left unclear how to handle the + fast retransmit cycle, having the implementation wait on the cwnd to + retransmit a TSN that was marked for fast retransmit. No limit was + placed on how many times a TSN could be fast retransmitted. Fast + Recovery was not specified, causing the congestion window to be + reduced drastically when there are multiple losses in a single RTT. + + + +Stewart, et al. Informational [Page 19] + +RFC 4460 SCTP Errata April 2006 + + +2.8.2. Text Changes to the Document + + --------- + Old text: (Section 6.2) + --------- + + Acknowledgements MUST be sent in SACK chunks unless shutdown was + requested by the ULP in which case an endpoint MAY send an + acknowledgement in the SHUTDOWN chunk. A SACK chunk can acknowledge + the reception of multiple DATA chunks. See Section 3.3.4 for SACK + chunk format. In particular, the SCTP endpoint MUST fill in the + Cumulative TSN Ack field to indicate the latest sequential TSN (of a + valid DATA chunk) it has received. Any received DATA chunks with TSN + greater than the value in the Cumulative TSN Ack field SHOULD also be + reported in the Gap Ack Block fields. + + --------- + New text: (Section 6.2) + --------- + + Acknowledegments MUST be sent in SACK chunks unless shutdown was + requested by the ULP, in which case an endpoint MAY send an + acknowledgement in the SHUTDOWN chunk. A SACK chunk can acknowledge + the reception of multiple DATA chunks. See Section 3.3.4 for SACK + chunk format. In particular, the SCTP endpoint MUST fill in the + Cumulative TSN Ack field to indicate the latest sequential TSN (of a + valid DATA chunk) it has received. Any received DATA chunks with + TSN greater than the value in the Cumulative TSN Ack field are + reported in the Gap Ack Block fields. The SCTP endpoint MUST + report as many Gap Ack Blocks as can fit in a single SACK + chunk limited by the current path MTU. + + --------- + Old text: (Section 6.2.1) + --------- + + D) Any time a SACK arrives, the endpoint performs the following: + + i) If Cumulative TSN Ack is less than the Cumulative TSN Ack + Point, then drop the SACK. Since Cumulative TSN Ack is + monotonically increasing, a SACK whose Cumulative TSN Ack is + less than the Cumulative TSN Ack Point indicates an out-of- + order SACK. + + ii) Set rwnd equal to the newly received a_rwnd minus the + number of bytes still outstanding after processing the + Cumulative TSN Ack and the Gap Ack Blocks. + + + + +Stewart, et al. Informational [Page 20] + +RFC 4460 SCTP Errata April 2006 + + + iii) If the SACK is missing a TSN that was previously + acknowledged via a Gap Ack Block (e.g., the data receiver + reneged on the data), then mark the corresponding DATA chunk + as available for retransmit: Mark it as missing for fast + retransmit as described in Section 7.2.4 and if no + retransmit timer is running for the destination address + to which the DATA chunk was originally transmitted, then + T3-rtx is started for that destination address. + + --------- + New text: (Section 6.2.1) + --------- + + D) Any time a SACK arrives, the endpoint performs the following: + + i) If Cumulative TSN Ack is less than the Cumulative TSN Ack + Point, then drop the SACK. Since Cumulative TSN Ack is + monotonically increasing, a SACK whose Cumulative TSN Ack is + less than the Cumulative TSN Ack Point indicates an out-of- + order SACK. + + ii) Set rwnd equal to the newly received a_rwnd minus the + number of bytes still outstanding after processing the + Cumulative TSN Ack and the Gap Ack Blocks. + + iii) If the SACK is missing a TSN that was previously + acknowledged via a Gap Ack Block (e.g., the data receiver + reneged on the data), then consider the corresponding DATA + that might be possibly missing: Count one miss indication + towards fast retransmit as described in Section 7.2.4, and + if no retransmit timer is running for the destination + address to which the DATA chunk was originally transmitted, + then T3-rtx is started for that destination address. + + iv) If the Cumulative TSN Ack matches or exceeds the Fast + Recovery exitpoint (Section 7.2.4), Fast Recovery is exited. + + --------- + Old text: (Section 7.2.4) + --------- + + Whenever an endpoint receives a SACK that indicates some TSN(s) + missing, it SHOULD wait for 3 further miss indications (via + subsequent SACK's) on the same TSN(s) before taking action with + regard to Fast Retransmit. + + When the TSN(s) is reported as missing in the fourth consecutive + SACK, the data sender shall: + + + +Stewart, et al. Informational [Page 21] + +RFC 4460 SCTP Errata April 2006 + + + 1) Mark the missing DATA chunk(s) for retransmission, + + 2) Adjust the ssthresh and cwnd of the destination address(es) to + which the missing DATA chunks were last sent, according to the + formula described in Section 7.2.3. + + 3) Determine how many of the earliest (i.e., lowest TSN) DATA chunks + marked for retransmission will fit into a single packet, subject + to constraint of the path MTU of the destination transport address + to which the packet is being sent. Call this value K. Retransmit + those K DATA chunks in a single packet. + + 4) Restart T3-rtx timer only if the last SACK acknowledged the lowest + outstanding TSN number sent to that address, or the endpoint is + retransmitting the first outstanding DATA chunk sent to that + address. + + Note: Before the above adjustments, if the received SACK also + acknowledges new DATA chunks and advances the Cumulative TSN Ack + Point, the cwnd adjustment rules defined in Sections 7.2.1 and 7.2.2 + must be applied first. + + A straightforward implementation of the above keeps a counter for + each TSN hole reported by a SACK. The counter increments for each + consecutive SACK reporting the TSN hole. After reaching 4 and + starting the fast retransmit procedure, the counter resets to 0. + Because cwnd in SCTP indirectly bounds the number of outstanding + TSN's, the effect of TCP fast-recovery is achieved automatically with + no adjustment to the congestion control window size. + + --------- + New text: (Section 7.2.4) + --------- + + Whenever an endpoint receives a SACK that indicates that some TSNs + are missing, it SHOULD wait for 3 further miss indications (via + subsequent SACKs) on the same TSN(s) before taking action with + regard to Fast Retransmit. + + Miss indications SHOULD follow the HTNA (Highest TSN Newly + Acknowledged) algorithm. For each incoming SACK, miss + indications are incremented only for missing TSNs prior to + the highest TSN newly acknowledged in the SACK. A newly + acknowledged DATA chunk is one not previously acknowledged + in a SACK. If an endpoint is in Fast Recovery and a SACK + arrives that advances the Cumulative TSN Ack Point, the + miss indications are incremented for all TSNs reported + missing in the SACK. + + + +Stewart, et al. Informational [Page 22] + +RFC 4460 SCTP Errata April 2006 + + + When the fourth consecutive miss indication is received for a TSN(s), + the data sender shall do the following: + + 1) Mark the DATA chunk(s) with four miss indications for + retransmission. + + 2) If not in Fast Recovery, adjust the ssthresh and cwnd of the + destination address(es) to which the missing DATA chunks were + last sent, according to the formula described in Section 7.2.3. + + 3) Determine how many of the earliest (i.e., lowest TSN) DATA chunks + marked for retransmission will fit into a single packet, subject + to constraint of the path MTU of the destination transport address + to which the packet is being sent. Call this value K. Retransmit + those K DATA chunks in a single packet. When a Fast Retransmit is + being performed, the sender SHOULD ignore the value of cwnd and + SHOULD NOT delay retransmission for this single packet. + + 4) Restart T3-rtx timer only if the last SACK acknowledged the lowest + outstanding TSN number sent to that address, or the endpoint is + retransmitting the first outstanding DATA chunk sent to that + address. + + 5) Mark the DATA chunk(s) as being fast retransmitted and thus + ineligible for a subsequent fast retransmit. Those TSNs marked + for retransmission due to the Fast Retransmit algorithm that + did not fit in the sent datagram carrying K other TSNs are also + marked as ineligible for a subsequent fast retransmit. However, + as they are marked for retransmission they will be retransmitted + later on as soon as cwnd allows. + + 6) If not in Fast Recovery, enter Fast Recovery and mark the highest + outstanding TSN as the Fast Recovery exit point. When a SACK + acknowledges all TSNs up to and including this exit point, Fast + Recovery is exited. While in Fast Recovery, the ssthresh and cwnd + SHOULD NOT change for any destinations due to a subsequent Fast + Recovery event (i.e., one SHOULD NOT reduce the cwnd further due + to a subsequent fast retransmit). + + Note: Before the above adjustments, if the received SACK also + acknowledges new DATA chunks and advances the Cumulative TSN Ack + Point, the cwnd adjustment rules defined in Sections 7.2.1 and 7.2.2 + must be applied first. + +2.8.3. Solution Description + + The effect of the above wording changes are as follows: + + + + +Stewart, et al. Informational [Page 23] + +RFC 4460 SCTP Errata April 2006 + + + o It requires with a MUST the sending of GAP Ack blocks instead of + the current RFC 2960 [5] SHOULD. + + o It allows a TSN being Fast Retransmitted (FR) to be sent only once + via FR. + + o It ends the delay in waiting for the flight size to drop when a + TSN is identified as being ready to FR. + + o It changes the way chunks are marked during fast retransmit, so + that only new reports are counted. + + o It introduces a Fast Recovery period to avoid multiple congestion + window reductions when there are multiple losses in a single RTT + (as shown by Caro et al. [3]). + + These changes will effectively allow SCTP to follow a similar model + as TCP+SACK in the handling of Fast Retransmit. + +2.9. Missing Statement about partial_bytes_acked Update + +2.9.1. Description of the Problem + + SCTP uses four control variables to regulate its transmission rate: + rwnd, cwnd, ssthresh, and partial_bytes_acked. Upon detection of + packet losses from SACK, or when the T3-rtx timer expires on an + address, cwnd and ssthresh should be updated as stated in Section + 7.2.3. However, that section should also clarify that + partial_bytes_acked must be updated as well; it has to be reset to 0. + +2.9.2. Text Changes to the Document + + --------- + Old text: (Section 7.2.3) + --------- + + 7.2.3 Congestion Control + + Upon detection of packet losses from SACK (see Section 7.2.4), An + endpoint should do the following: + + ssthresh = max(cwnd/2, 2*MTU) + cwnd = ssthresh + + Basically, a packet loss causes cwnd to be cut in half. + + When the T3-rtx timer expires on an address, SCTP should perform slow + start by: + + + +Stewart, et al. Informational [Page 24] + +RFC 4460 SCTP Errata April 2006 + + + ssthresh = max(cwnd/2, 2*MTU) + cwnd = 1*MTU + + --------- + New text: (Section 7.2.3) + --------- + + 7.2.3. Congestion Control + + Upon detection of packet losses from SACK (see Section 7.2.4), an + endpoint should do the following if not in Fast Recovery: + + ssthresh = max(cwnd/2, 2*MTU) + cwnd = ssthresh + partial_bytes_acked = 0 + + Basically, a packet loss causes cwnd to be cut in half. + + When the T3-rtx timer expires on an address, SCTP should perform slow + start by + + ssthresh = max(cwnd/2, 2*MTU) + cwnd = 1*MTU + partial_bytes_acked = 0 + +2.9.3. Solution Description + + The missing text added solves the doubts about what to do with + partial_bytes_acked in the situations stated in Section 7.2.3, making + clear that, along with ssthresh and cwnd, partial_bytes_acked should + also be updated by being reset to 0. + +2.10. Issues with Heartbeating and Failure Detection + +2.10.1. Description of the Problem + + Five basic problems have been discovered with the current heartbeat + procedures: + + o The current specification does not specify that you should count a + failed heartbeat as an error against the overall association. + + o The current specification is not specific as to when you start + sending heartbeats and when you should stop. + + o The current specification is not specific as to when you should + respond to heartbeats. + + + + +Stewart, et al. Informational [Page 25] + +RFC 4460 SCTP Errata April 2006 + + + o When responding to a Heartbeat, it is unclear what to do if more + than a single TLV is present. + + o The jitter applied to a heartbeat was meant to be a small variance + of the RTO and is currently a wide variance, due to the default + delay time and incorrect wording within the RFC. + +2.10.2. Text Changes to the Document + + --------- + Old text: (Section 8.1) + --------- + + 8.1 Endpoint Failure Detection + + An endpoint shall keep a counter on the total number of consecutive + retransmissions to its peer (including retransmissions to all the + destination transport addresses of the peer if it is multi-homed). + If the value of this counter exceeds the limit indicated in the + protocol parameter 'Association.Max.Retrans', the endpoint shall + consider the peer endpoint unreachable and shall stop transmitting + any more data to it (and thus the association enters the CLOSED + state). In addition, the endpoint shall report the failure to the + upper layer, and optionally report back all outstanding user data + remaining in its outbound queue. The association is automatically + closed when the peer endpoint becomes unreachable. + + The counter shall be reset each time a DATA chunk sent to that peer + endpoint is acknowledged (by the reception of a SACK), or a + HEARTBEAT-ACK is received from the peer endpoint. + + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Informational [Page 26] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 8.1) + --------- + + 8.1. Endpoint Failure Detection + + An endpoint shall keep a counter on the total number of consecutive + retransmissions to its peer (this includes retransmissions to all the + destination transport addresses of the peer if it is multi-homed), + including unacknowledged HEARTBEAT Chunks. If the value of this + counter exceeds the limit indicated in the protocol parameter + 'Association.Max.Retrans', the endpoint shall consider the peer + endpoint unreachable and shall stop transmitting any more data to it + (and thus the association enters the CLOSED state). In addition, the + endpoint MAY report the failure to the upper layer and optionally + report back all outstanding user data remaining in its outbound + queue. The association is automatically closed when the peer + endpoint becomes unreachable. + + The counter shall be reset each time a DATA chunk sent to that peer + endpoint is acknowledged (by the reception of a SACK), or a + HEARTBEAT-ACK is received from the peer endpoint. + + + --------- + Old text: (Section 8.3) + --------- + + 8.3 Path Heartbeat + + By default, an SCTP endpoint shall monitor the reachability of the + idle destination transport address(es) of its peer by sending a + HEARTBEAT chunk periodically to the destination transport + address(es). + + --------- + New text: (Section 8.3) + --------- + + 8.3 Path Heartbeat + + By default, an SCTP endpoint SHOULD monitor the reachability of the + idle destination transport address(es) of its peer by sending a + HEARTBEAT chunk periodically to the destination transport + address(es). HEARTBEAT sending MAY begin upon reaching the + ESTABLISHED state and is discontinued after sending either SHUTDOWN + or SHUTDOWN-ACK. A receiver of a HEARTBEAT MUST respond to a + HEARTBEAT with a HEARTBEAT-ACK after entering the COOKIE-ECHOED state + + + +Stewart, et al. Informational [Page 27] + +RFC 4460 SCTP Errata April 2006 + + + (INIT sender) or the ESTABLISHED state (INIT receiver), up until + reaching the SHUTDOWN-SENT state (SHUTDOWN sender) or the SHUTDOWN- + ACK-SENT state (SHUTDOWN receiver). + + + --------- + Old text: (Section 8.3) + --------- + + The receiver of the HEARTBEAT should immediately respond with a + HEARTBEAT ACK that contains the Heartbeat Information field copied + from the received HEARTBEAT chunk. + + --------- + New text: (Section 8.3) + --------- + + The receiver of the HEARTBEAT should immediately respond with a + HEARTBEAT ACK that contains the Heartbeat Information TLV, together + with any other received TLVs, copied unchanged from the received + HEARTBEAT chunk. + + + --------- + Old text: (Section 8.3) + --------- + + On an idle destination address that is allowed to heartbeat, a + HEARTBEAT chunk is RECOMMENDED to be sent once per RTO of that + destination address plus the protocol parameter 'HB.interval' , with + jittering of +/- 50%, and exponential back-off of the RTO if the + previous HEARTBEAT is unanswered. + + --------- + New text: (Section 8.3) + --------- + + On an idle destination address that is allowed to heartbeat, it is + recommended that a HEARTBEAT chunk is sent once per RTO of that + destination address plus the protocol parameter 'HB.interval', with + jittering of +/- 50% of the RTO value, and exponential back-off of + the RTO if the previous HEARTBEAT is unanswered. + +2.10.3. Solution Description + + The above text provides guidance as to how to respond to the five + issues mentioned in Section 2.10.1. In particular, the wording + changes provide guidance as to when to start and stop heartbeating, + + + +Stewart, et al. Informational [Page 28] + +RFC 4460 SCTP Errata April 2006 + + + how to respond to a heartbeat with extra parameters, and it clarifies + the error counting procedures for the association. + +2.11. Security interactions with firewalls + +2.11.1. Description of the Problem + + When dealing with firewalls, it is advantageous for the firewall to + be able to properly determine the initial startup sequence of a + reliable transport protocol. With this in mind, the following text + is to be added to SCTP's security section. + +2.11.2. Text Changes to the Document + + --------- + New text: (no old text, new section added) + --------- + + 11.4 SCTP Interactions with Firewalls + + It is helpful for some firewalls if they can inspect + just the first fragment of a fragmented SCTP packet and unambiguously + determine whether it corresponds to an INIT chunk (for further + information, please refer to RFC1858). Accordingly, we + stress the requirements, stated in 3.1, that (1) an INIT chunk MUST + NOT be bundled with any other chunk in a packet, and (2) a packet + containing an INIT chunk MUST have a zero Verification Tag. + Furthermore, we require that the receiver of an INIT chunk MUST + enforce these rules by silently discarding an arriving packet with an + INIT chunk that is bundled with other chunks. + + --------- + Old text: (Section 18) + --------- + + 18. Bibliography + + [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End + Network Path Properties", Proc. SIGCOMM'99, 1999. + + [FALL96] Fall, K. and Floyd, S., Simulation-based Comparisons of + Tahoe, Reno, and SACK TCP, Computer Communications Review, + V. 26 N. 3, July 1996, pp. 5-21. + + [RFC1750] Eastlake, D. (ed.), "Randomness Recommendations for + Security", RFC 1750, December 1994. + + + + + +Stewart, et al. Informational [Page 29] + +RFC 4460 SCTP Errata April 2006 + + + [RFC1950] Deutsch P. and J. Gailly, "ZLIB Compressed Data Format + Specification version 3.3", RFC 1950, May 1996. + + [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed- + Hashing for Message Authentication", RFC 2104, March 1997. + + [RFC2196] Fraser, B., "Site Security Handbook", FYI 8, RFC 2196, + September 1997. + + [RFC2522] Karn, P. and W. Simpson, "Photuris: Session-Key Management + Protocol", RFC 2522, March 1999. + + [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T., + "TCP Congestion Control with a Misbehaving Receiver", ACM + Computer Communication Review, 29(5), October 1999. + + --------- + New text: (Section 18) + --------- + + 18. Bibliography + + [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End + Network Path Properties", Proc. SIGCOMM'99, 1999. + + [FALL96] Fall, K. and Floyd, S., Simulation-based Comparisons of + Tahoe, Reno, and SACK TCP, Computer Communications Review, + V. 26 N. 3, July 1996, pp. 5-21. + + [RFC1750] Eastlake, D. (ed.), "Randomness Recommendations for + Security", RFC 1750, December 1994. + + [RFC1858] Ziemba, G., Reed, D. and Traina P., "Security + Considerations for IP Fragment Filtering", RFC 1858, + October 1995. + + [RFC1950] Deutsch P. and J. Gailly, "ZLIB Compressed Data Format + Specification version 3.3", RFC 1950, May 1996. + + [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed- + Hashing for Message Authentication", RFC 2104, March 1997. + + [RFC2196] Fraser, B., "Site Security Handbook", FYI 8, RFC 2196, + September 1997. + + [RFC2522] Karn, P. and W. Simpson, "Photuris: Session-Key Management + Protocol", RFC 2522, March 1999. + + + + +Stewart, et al. Informational [Page 30] + +RFC 4460 SCTP Errata April 2006 + + + [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T., + "TCP Congestion Control with a Misbehaving Receiver", ACM + Computer Communication Review, 29(5), October 1999. + +2.11.3. Solution Description + + The above text, which adds a new subsection to the Security + Considerations section of RFC 2960 [5] makes clear that, to make + easier the interaction with firewalls, an INIT chunk must not be + bundled in any case with any other chunk that will silently discard + the packets that do not follow this rule (this rule is enforced by + the packet receiver). + +2.12. Shutdown Ambiguity + +2.12.1. Description of the Problem + + Currently, there is an ambiguity between the statements in Sections + 6.2 and 9.2. Section 6.2 allows the sending of a SHUTDOWN chunk in + place of a SACK when the sender is in the process of shutting down, + while section 9.2 requires that both a SHUTDOWN chunk and a SACK + chunk be sent. + + Along with this ambiguity there is a problem wherein an errant + SHUTDOWN receiver may fail to stop accepting user data. + +2.12.2. Text Changes to the Document + + --------- + Old text: (Section 9.2) + --------- + + If there are still outstanding DATA chunks left, the SHUTDOWN + receiver shall continue to follow normal data transmission procedures + defined in Section 6 until all outstanding DATA chunks are + acknowledged; however, the SHUTDOWN receiver MUST NOT accept new data + from its SCTP user. + + While in SHUTDOWN-SENT state, the SHUTDOWN sender MUST immediately + respond to each received packet containing one or more DATA chunk(s) + with a SACK, a SHUTDOWN chunk, and restart the T2-shutdown timer. If + it has no more outstanding DATA chunks, the SHUTDOWN receiver shall + send a SHUTDOWN ACK and start a T2-shutdown timer of its own, + entering the SHUTDOWN-ACK-SENT state. If the timer expires, the + endpoint must re-send the SHUTDOWN ACK. + + + + + + +Stewart, et al. Informational [Page 31] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 9.2) + --------- + + If there are still outstanding DATA chunks left, the SHUTDOWN + receiver MUST continue to follow normal data transmission procedures + defined in Section 6, until all outstanding DATA chunks are + acknowledged; however, the SHUTDOWN receiver MUST NOT accept new data + from its SCTP user. + + While in SHUTDOWN-SENT state, the SHUTDOWN sender MUST immediately + respond to each received packet containing one or more DATA chunks + with a SHUTDOWN chunk and restart the T2-shutdown timer. If a + SHUTDOWN chunk by itself cannot acknowledge all of the received DATA + chunks (i.e., there are TSNs that can be acknowledged that are larger + than the cumulative TSN, and thus gaps exist in the TSN sequence), or + if duplicate TSNs have been received, then a SACK chunk MUST also be + sent. + + The sender of the SHUTDOWN MAY also start an overall guard timer + 'T5-shutdown-guard' to bound the overall time for shutdown sequence. + At the expiration of this timer, the sender SHOULD abort the + association by sending an ABORT chunk. If the 'T5-shutdown-guard' + timer is used, it SHOULD be set to the recommended value of 5 times + 'RTO.Max'. + + If the receiver of the SHUTDOWN has no more outstanding DATA chunks, + the SHUTDOWN receiver MUST send a SHUTDOWN ACK and start a + T2-shutdown timer of its own, entering the SHUTDOWN-ACK-SENT state. + If the timer expires, the endpoint must re-send the SHUTDOWN ACK. + +2.12.3. Solution Description + + The above text clarifies the use of a SACK in conjunction with a + SHUTDOWN chunk. It also adds a guard timer to the SCTP shutdown + sequence to protect against errant receivers of SHUTDOWN chunks. + +2.13. Inconsistency in ABORT Processing + +2.13.1. Description of the Problem + + It was noted that the wording in Section 8.5.1 did not give proper + directions in the use of the 'T bit' with the Verification Tags. + + + + + + + + +Stewart, et al. Informational [Page 32] + +RFC 4460 SCTP Errata April 2006 + + +2.13.2. Text changes to the document + + --------- + Old text: (Section 8.5.1) + --------- + + B) Rules for packet carrying ABORT: + + - The endpoint shall always fill in the Verification Tag field + of the outbound packet with the destination endpoint's tag + value if it is known. + + - If the ABORT is sent in response to an OOTB packet, the + endpoint MUST follow the procedure described in Section 8.4. + + - The receiver MUST accept the packet if the Verification Tag + matches either its own tag, OR the tag of its peer. Otherwise, + the receiver MUST silently discard the packet and take no + further action. + + --------- + New text: (Section 8.5.1) + --------- + + B) Rules for packet carrying ABORT: + + - The endpoint MUST always fill in the Verification Tag field of + the outbound packet with the destination endpoint's tag value, + if it is known. + + - If the ABORT is sent in response to an OOTB packet, the + endpoint MUST follow the procedure described in Section 8.4. + + - The receiver of a ABORT MUST accept the packet if the + Verification Tag field of the packet matches its own tag OR if + it is set to its peer's tag and the T bit is set in the Chunk + Flags. Otherwise, the receiver MUST silently discard the + packet and take no further action. + +2.13.3. Solution Description + + The above text change clarifies that the T bit must be set before an + implementation looks for the peer's tag. + + + + + + + + +Stewart, et al. Informational [Page 33] + +RFC 4460 SCTP Errata April 2006 + + +2.14. Cwnd Gated by Its Full Use + +2.14.1. Description of the Problem + + A problem was found with the current specification of the growth and + decay of cwnd. The cwnd should only be increased if it is being + fully utilized, and after periods of underutilization, the cwnd + should be decreased. In some sections, the current wording is weak + and is not clearly defined. Also, the current specification + unnecessarily introduces the need for special case code to ensure + cwnd degradation. Plus, the cwnd should not be increased during Fast + Recovery, since a full cwnd during Fast Recovery does not qualify the + cwnd as being fully utilized. Additionally, multiple loss scenarios + in a single window may cause the cwnd to grow more rapidly as the + number of losses in a window increases [3]. + +2.14.2. Text Changes to the Document + + --------- + Old text: (Section 6.1) + --------- + + D) Then, the sender can send out as many new DATA chunks as Rule A + and Rule B above allow. + + --------- + New text: (Section 6.1) + --------- + + D) When the time comes for the sender to transmit new DATA chunks, + the protocol parameter Max.Burst SHOULD be used to limit the + number of packets sent. The limit MAY be applied by adjusting + cwnd as follows: + + if((flightsize + Max.Burst*MTU) < cwnd) + cwnd = flightsize + Max.Burst*MTU + + Or it MAY be applied by strictly limiting the number of packets + emitted by the output routine. + + E) Then, the sender can send out as many new DATA chunks as Rule A + and Rule B allow. + + + + + + + + + +Stewart, et al. Informational [Page 34] + +RFC 4460 SCTP Errata April 2006 + + + --------- + Old text: (Section 7.2.1) + --------- + + o When cwnd is less than or equal to ssthresh an SCTP endpoint MUST + use the slow start algorithm to increase cwnd (assuming the + current congestion window is being fully utilized). If an + incoming SACK advances the Cumulative TSN Ack Point, cwnd MUST be + increased by at most the lesser of 1) the total size of the + previously outstanding DATA chunk(s) acknowledged, and 2) the + destination's path MTU. This protects against the ACK-Splitting + attack outlined in [SAVAGE99]. + + --------- + New text: (Section 7.2.1) + --------- + + o When cwnd is less than or equal to ssthresh, an SCTP endpoint MUST + use the slow start algorithm to increase cwnd only if the current + congestion window is being fully utilized, an incoming SACK + advances the Cumulative TSN Ack Point, and the data sender is not + in Fast Recovery. Only when these three conditions are met can + the cwnd be increased; otherwise, the cwnd MUST not be increased. + If these conditions are met, then cwnd MUST be increased by, at + most, the lesser of 1) the total size of the previously + outstanding DATA chunk(s) acknowledged, and 2) the destination's + path MTU. This upper bound protects against the ACK-Splitting + attack outlined in [SAVAGE99]. + + + --------- + Old text: (Section 14) + --------- + + 14. Suggested SCTP Protocol Parameter Values + + The following protocol parameters are RECOMMENDED: + + RTO.Initial - 3 seconds + RTO.Min - 1 second + RTO.Max - 60 seconds + RTO.Alpha - 1/8 + RTO.Beta - 1/4 + Valid.Cookie.Life - 60 seconds + Association.Max.Retrans - 10 attempts + Path.Max.Retrans - 5 attempts (per destination address) + Max.Init.Retransmits - 8 attempts + HB.interval - 30 seconds + + + +Stewart, et al. Informational [Page 35] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 14) + --------- + + 14. Suggested SCTP Protocol Parameter Values + + The following protocol parameters are RECOMMENDED: + + RTO.Initial - 3 seconds + RTO.Min - 1 second + RTO.Max - 60 seconds + Max.Burst - 4 + RTO.Alpha - 1/8 + RTO.Beta - 1/4 + Valid.Cookie.Life - 60 seconds + Association.Max.Retrans - 10 attempts + Path.Max.Retrans - 5 attempts (per destination address) + Max.Init.Retransmits - 8 attempts + HB.Interval - 30 seconds + +2.14.3. Solution Description + + The above changes strengthen the rules and make it much more apparent + as to the need to block cwnd growth when the full cwnd is not being + utilized. The changes also apply cwnd degradation without + introducing the need for complex special case code. + +2.15. Window Probes in SCTP + +2.15.1. Description of the Problem + + When a receiver clamps its rwnd to 0 to flow control the peer, the + specification implies that one must continue to accept data from the + remote peer. This is incorrect and needs clarification. + +2.15.2. Text Changes to the Document + + --------- + Old text: (Section 6.2) + --------- + + The SCTP endpoint MUST always acknowledge the receipt of each valid + DATA chunk. + + + + + + + + +Stewart, et al. Informational [Page 36] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 6.2) + --------- + + The SCTP endpoint MUST always acknowledge the reception of each valid + DATA chunk when the DATA chunk received is inside its receive window. + + When the receiver's advertised window is 0, the receiver MUST drop + any new incoming DATA chunk with a TSN larger than the largest TSN + received so far. If the new incoming DATA chunk holds a TSN value + less than the largest TSN received so far, then the receiver SHOULD + drop the largest TSN held for reordering and accept the new incoming + DATA chunk. In either case, if such a DATA chunk is dropped, the + receiver MUST immediately send back a SACK with the current receive + window showing only DATA chunks received and accepted so far. The + dropped DATA chunk(s) MUST NOT be included in the SACK, as they were + not accepted. The receiver MUST also have an algorithm for + advertising its receive window to avoid receiver silly window + syndrome (SWS), as described in RFC 813. The algorithm can be + similar to the one described in Section 4.2.3.3 of RFC 1122. + + + --------- + Old text: (Section 6.1) + --------- + + A) At any given time, the data sender MUST NOT transmit new data to + any destination transport address if its peer's rwnd indicates + that the peer has no buffer space (i.e., rwnd is 0, see Section + 6.2.1). However, regardless of the value of rwnd (including if it + is 0), the data sender can always have one DATA chunk in flight to + the receiver if allowed by cwnd (see rule B below). This rule + allows the sender to probe for a change in rwnd that the sender + missed due to the SACK having been lost in transit from the data + receiver to the data sender. + + + + + + + + + + + + + + + + +Stewart, et al. Informational [Page 37] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 6.1) + --------- + + A) At any given time, the data sender MUST NOT transmit new data to + any destination transport address if its peer's rwnd indicates + that the peer has no buffer space (i.e., rwnd is 0; see Section + 6.2.1). However, regardless of the value of rwnd (including if it + is 0), the data sender can always have one DATA chunk in flight to + the receiver if allowed by cwnd (see rule B, below). This rule + allows the sender to probe for a change in rwnd that the sender + missed due to the SACK's having been lost in transit from the data + receiver to the data sender. + + When the receiver's advertised window is zero, this probe is + called a zero window probe. Note that a zero window probe + SHOULD only be sent when all outstanding DATA chunks have + been cumulatively acknowledged and no DATA chunks are in + flight. Zero window probing MUST be supported. + + If the sender continues to receive new packets from the receiver + while doing zero window probing, the unacknowledged window probes + should not increment the error counter for the association or any + destination transport address.This is because the receiver MAY + keep its window closed for an indefinite time. Refer to + Section 6.2 on the receiver behavior when it advertises a zero + window. The sender SHOULD send the first zero window probe after + 1 RTO when it detects that the receiver has closed its window + and SHOULD increase the probe interval exponentially afterwards. + Also note that the cwnd SHOULD be adjusted according to + Section 7.2.1. Zero window probing does not affect the + calculation of cwnd. + + The sender MUST also have an algorithm for sending new DATA chunks + to avoid silly window syndrome (SWS) as described in RFC 813. The + algorithm can be similar to the one described in Section 4.2.3.4 + of RFC 1122. + +2.15.3. Solution Description + + The above allows a receiver to drop new data that arrives and yet + still requires the receiver to send a SACK showing the conditions + unchanged (with the possible exception of a new a_rwnd) and the + dropped chunk as missing. This will allow the association to + continue until the rwnd condition clears. + + + + + + +Stewart, et al. Informational [Page 38] + +RFC 4460 SCTP Errata April 2006 + + +2.16. Fragmentation and Path MTU Issues + +2.16.1. Description of the Problem + + The current wording of the Fragmentation and Reassembly forces an + implementation that supports fragmentation to always fragment. This + prohibits an implementation from offering its users an option to + disable sends that exceed the SCTP fragmentation point. + + The restriction in RFC 2960 [5], Section 6.9, was never meant to + restrict an implementations API from this behavior. + +2.16.2. Text Changes to the Document + + --------- + Old text: (Section 6.1) + --------- + + 6.9 Fragmentation and Reassembly + + An endpoint MAY support fragmentation when sending DATA chunks, but + MUST support reassembly when receiving DATA chunks. If an endpoint + supports fragmentation, it MUST fragment a user message if the size + of the user message to be sent causes the outbound SCTP packet size + to exceed the current MTU. If an implementation does not support + fragmentation of outbound user messages, the endpoint must return an + error to its upper layer and not attempt to send the user message. + + IMPLEMENTATION NOTE: In this error case, the Send primitive + discussed in Section 10.1 would need to return an error to the upper + layer. + + --------- + New text: (Section 6.1) + --------- + + 6.9. Fragmentation and Reassembly + + An endpoint MAY support fragmentation when sending DATA chunks, but + it MUST support reassembly when receiving DATA chunks. If an + endpoint supports fragmentation, it MUST fragment a user message if + the size of the user message to be sent causes the outbound SCTP + packet size to exceed the current MTU. If an implementation does not + support fragmentation of outbound user messages, the endpoint MUST + return an error to its upper layer and not attempt to send the user + message. + + + + + +Stewart, et al. Informational [Page 39] + +RFC 4460 SCTP Errata April 2006 + + + Note: If an implementation that supports fragmentation makes + available to its upper layer a mechanism to turn off fragmentation it + may do so. However, in so doing, it MUST react just like an + implementation that does NOT support fragmentation, i.e., it MUST + reject sends that exceed the current P-MTU. + + IMPLEMENTATION NOTE: In this error case, the Send primitive + discussed in Section 10.1 would need to return an error to the upper + layer. + +2.16.3. Solution Description + + The above wording will allow an implementation to offer the option of + rejecting sends that exceed the P-MTU size even when the + implementation supports fragmentation. + +2.17. Initial Value of the Cumulative TSN Ack + +2.17.1. Description of the Problem + + The current description of the SACK chunk within the RFC does not + clearly state the value that would be put within a SACK when no DATA + chunk has been received. + +2.17.2. Text Changes to the Document + + --------- + Old text: (Section 3.3.4) + --------- + + Cumulative TSN Ack: 32 bits (unsigned integer) + + This parameter contains the TSN of the last DATA chunk received in + sequence before a gap. + + --------- + New text: (Section 3.3.4) + --------- + + Cumulative TSN Ack: 32 bits (unsigned integer) + + This parameter contains the TSN of the last DATA chunk received in + sequence before a gap. In the case where no DATA chunk has + been received, this value is set to the peer's Initial TSN minus + one. + + + + + + +Stewart, et al. Informational [Page 40] + +RFC 4460 SCTP Errata April 2006 + + +2.17.3. Solution Description + + This change clearly states what the initial value will be for a SACK + sender. + +2.18. Handling of Address Parameters within the INIT or INIT-ACK + +2.18.1. Description of the Problem + + The current description on handling address parameters contained + within the INIT and INIT-ACK does not fully describe a requirement + for their handling. + +2.18.2. Text Changes to the Document + + --------- + Old text: (Section 5.1.2) + --------- + + C) If there are only IPv4/IPv6 addresses present in the received INIT + or INIT ACK chunk, the receiver shall derive and record all the + transport address(es) from the received chunk AND the source IP + address that sent the INIT or INIT ACK. The transport address(es) + are derived by the combination of SCTP source port (from the + common header) and the IP address parameter(s) carried in the INIT + or INIT ACK chunk and the source IP address of the IP datagram. + The receiver should use only these transport addresses as + destination transport addresses when sending subsequent packets to + its peer. + + --------- + New text: (Section 5.1.2) + --------- + + C) If there are only IPv4/IPv6 addresses present in the received INIT + or INIT ACK chunk, the receiver MUST derive and record all the + transport addresses from the received chunk AND the source IP + address that sent the INIT or INIT ACK. The transport addresses + are derived by the combination of SCTP source port (from the + common header) and the IP address parameter(s) carried in the INIT + or INIT ACK chunk and the source IP address of the IP datagram. + The receiver should use only these transport addresses as + destination transport addresses when sending subsequent packets to + its peer. + + + + + + + +Stewart, et al. Informational [Page 41] + +RFC 4460 SCTP Errata April 2006 + + + D) An INIT or INIT ACK chunk MUST be treated as belonging + to an already established association (or one in the + process of being established) if the use of any of the + valid address parameters contained within the chunk + would identify an existing TCB. + +2.18.3. Solution description + + This new text clearly specifies to an implementor the need to look + within the INIT or INIT ACK. Any implementation that does not do + this may (for example) not be able to recognize an INIT chunk coming + from an already established association that adds new addresses (see + Section 2.6) or an incoming INIT ACK chunk sent from a source address + different from the destination address used to send the INIT chunk. + +2.19. Handling of Stream Shortages + +2.19.1. Description of the Problem + + The current wording in the RFC places the choice of sending an ABORT + upon the SCTP stack when a stream shortage occurs. This decision + should really be made by the upper layer, not the SCTP stack. + +2.19.2. Text Changes to the Document + + --------- + Old text: + --------- + + 5.1.1 Handle Stream Parameters + + In the INIT and INIT ACK chunks, the sender of the chunk shall + indicate the number of outbound streams (OS) it wishes to have in + the association, as well as the maximum inbound streams (MIS) it + will accept from the other endpoint. + + After receiving the stream configuration information from the other + side, each endpoint shall perform the following check: If the peer's + MIS is less than the endpoint's OS, meaning that the peer is + incapable of supporting all the outbound streams the endpoint wants + to configure, the endpoint MUST either use MIS outbound streams, or + abort the association and report to its upper layer the resources + shortage at its peer. + + + + + + + + +Stewart, et al. Informational [Page 42] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 5.1.2) + --------- + + 5.1.1. Handle Stream Parameters + + In the INIT and INIT ACK chunks, the sender of the chunk MUST + indicate the number of outbound streams (OS) it wishes to have in + the association, as well as the maximum inbound streams (MIS) it will + accept from the other endpoint. + + After receiving the stream configuration information from the other + side, each endpoint MUST perform the following check: If the peer's + MIS is less than the endpoint's OS, meaning that the peer is + incapable of supporting all the outbound streams the endpoint wants + to configure, the endpoint MUST use MIS outbound streams and MAY + report any shortage to the upper layer. The upper layer can then + choose to abort the association if the resource shortage + is unacceptable. + +2.19.3. Solution Description + + The above changes take the decision to ABORT out of the realm of the + SCTP stack and place it into the user's hands. + +2.20. Indefinite Postponement + +2.20.1. Description of the Problem + + The current RFC does not provide any guidance on the assignment of + TSN sequence numbers to outbound messages nor reception of these + messages. This could lead to a possible indefinite postponement. + +2.20.2. Text Changes to the Document + + --------- + Old text: (Section 6.1) + --------- + + Note: The data sender SHOULD NOT use a TSN that is more than 2**31 - + 1 above the beginning TSN of the current send window. + + 6.2 Acknowledgement on Reception of DATA Chunks + + + + + + + + +Stewart, et al. Informational [Page 43] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 6.1) + --------- + + Note: The data sender SHOULD NOT use a TSN that is more than 2**31 - + 1 above the beginning TSN of the current send window. + + The algorithm by which an implementation assigns sequential TSNs to + messages on a particular association MUST ensure that no user + message that has been accepted by SCTP is indefinitely postponed + from being assigned a TSN. Acceptable algorithms for assigning TSNs + include + + (a) assigning TSNs in round-robin order over all streams with + pending data; and + + (b) preserving the linear order in which the user messages were + submitted to the SCTP association. + + When an upper layer requests to read data on an SCTP association, + the SCTP receiver SHOULD choose the message with the lowest TSN from + among all deliverable messages. In SCTP implementations that allow a + user to request data on a specific stream, this operation SHOULD NOT + block if data is not available, since this can lead to a deadlock + under certain conditions. + + 6.2. Acknowledgement on Receipt of DATA Chunks + +2.20.3. Solution Description + + The above wording clarifies how TSNs SHOULD be assigned by the + sender. + +2.21. User-Initiated Abort of an Association + +2.21.1. Description of the Problem + + It is not possible for an upper layer to abort the association and + provide the peer with an indication of why the association is + aborted. + +2.21.2. Text changes to the document + + Some of the changes given here already include changes suggested in + Section 2.6 of this document. + + + + + + +Stewart, et al. Informational [Page 44] + +RFC 4460 SCTP Errata April 2006 + + + --------- + Old text: (Section 3.3.10) + --------- + + Cause Code + Value Cause Code + --------- ---------------- + 1 Invalid Stream Identifier + 2 Missing Mandatory Parameter + 3 Stale Cookie Error + 4 Out of Resource + 5 Unresolvable Address + 6 Unrecognized Chunk Type + 7 Invalid Mandatory Parameter + 8 Unrecognized Parameters + 9 No User Data + 10 Cookie Received While Shutting Down + + Cause Length: 16 bits (unsigned integer) + + Set to the size of the parameter in bytes, including the Cause + Code, Cause Length, and Cause-Specific Information fields + + Cause-specific Information: variable length + + This field carries the details of the error condition. + + Sections 3.3.10.1 - 3.3.10.10 define error causes for SCTP. + Guidelines for the IETF to define new error cause values are + discussed in Section 13.3. + + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Informational [Page 45] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 3.3.10) + --------- + + Cause Code + Value Cause Code + --------- ---------------- + 1 Invalid Stream Identifier + 2 Missing Mandatory Parameter + 3 Stale Cookie Error + 4 Out of Resource + 5 Unresolvable Address + 6 Unrecognized Chunk Type + 7 Invalid Mandatory Parameter + 8 Unrecognized Parameters + 9 No User Data + 10 Cookie Received While Shutting Down + 11 Restart of an Association with New Addresses + 12 User-Initiated Abort + + Cause Length: 16 bits (unsigned integer) + + Set to the size of the parameter in bytes, including the Cause + Code, Cause Length, and Cause-Specific Information fields + + Cause-specific Information: variable length + + This field carries the details of the error condition. + + Sections 3.3.10.1 - 3.3.10.12 define error causes for SCTP. + Guidelines for the IETF to define new error cause values are + discussed in Section 13.3. + + --------- + New text: (Note: no old text, new error added in Section 3.3.10) + --------- + + 3.3.10.12. User-Initiated Abort (12) + + Cause of error + -------------- + + This error cause MAY be included in ABORT chunks that are sent + because of an upper layer request. The upper layer can specify + an Upper Layer Abort Reason that is transported by SCTP + transparently and MAY be delivered to the upper layer protocol + at the peer. + + + + +Stewart, et al. Informational [Page 46] + +RFC 4460 SCTP Errata April 2006 + + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=12 | Cause Length=Variable | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / Upper Layer Abort Reason / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + --------- + Old text: (Section 9.1) + --------- + + 9.1 Abort of an Association + + When an endpoint decides to abort an existing association, it + shall send an ABORT chunk to its peer endpoint. The sender MUST + fill in the peer's Verification Tag in the outbound packet and + MUST NOT bundle any DATA chunk with the ABORT. + + An endpoint MUST NOT respond to any received packet that contains + an ABORT chunk (also see Section 8.4). + + An endpoint receiving an ABORT shall apply the special + Verification Tag check rules described in Section 8.5.1. + + After checking the Verification Tag, the receiving endpoint shall + remove the association from its record and shall report the + termination to its upper layer. + + --------- + New text: (Section 9.1) + --------- + + 9.1. Abort of an Association + + When an endpoint decides to abort an existing association, it MUST + send an ABORT chunk to its peer endpoint. The sender MUST fill in + the peer's Verification Tag in the outbound packet and MUST NOT + bundle any DATA chunk with the ABORT. If the association is + aborted on request of the upper layer, a User-Initiated Abort + error cause (see 3.3.10.12) SHOULD be present in the ABORT chunk. + + An endpoint MUST NOT respond to any received packet that contains + an ABORT chunk (also see Section 8.4). + + An endpoint receiving an ABORT MUST apply the special Verification + Tag check rules described in Section 8.5.1. + + After checking the Verification Tag, the receiving endpoint MUST + + + +Stewart, et al. Informational [Page 47] + +RFC 4460 SCTP Errata April 2006 + + + remove the association from its record and SHOULD report the + termination to its upper layer. If a User-Initiated Abort error + cause is present in the ABORT chunk, the Upper Layer Abort Reason + SHOULD be made available to the upper layer. + + --------- + Old text: (Section 10.1) + --------- + + D) Abort + + Format: ABORT(association id [, cause code]) + -> result + + Ungracefully closes an association. Any locally queued user + data will be discarded and an ABORT chunk is sent to the peer. + A success code will be returned on successful abortion of the + association. If attempting to abort the association results + in a failure, an error code shall be returned. + + Mandatory attributes: + + o association id - local handle to the SCTP association + + Optional attributes: + + o cause code - reason of the abort to be passed to the peer. + + + --------- + New text: (Section 10.1) + --------- + + D) Abort + + Format: ABORT(association id [, Upper Layer Abort Reason]) + -> result + + Ungracefully closes an association. Any locally queued user + data will be discarded, and an ABORT chunk is sent to the peer. + A success code will be returned on successful abortion of the + association. If attempting to abort the association results + in a failure, an error code shall be returned. + + Mandatory attributes: + + o association id - Local handle to the SCTP association. + + + + +Stewart, et al. Informational [Page 48] + +RFC 4460 SCTP Errata April 2006 + + + Optional attributes: + + o Upper Layer Abort Reason - Reason of the abort to be passed + to the peer. + + None. + + --------- + Old text: (Section 10.2) + --------- + + E) COMMUNICATION LOST notification + + When SCTP loses communication to an endpoint completely (e.g., via + Heartbeats) or detects that the endpoint has performed an abort + operation, it shall invoke this notification on the ULP. + + The following shall be passed with the notification: + + o association id - local handle to the SCTP association + + o status - This indicates what type of event has occurred; The + status may indicate a failure OR a normal termination + event occurred in response to a shutdown or abort + request. + + The following may be passed with the notification: + + o data retrieval id - an identification used to retrieve + unsent and unacknowledged data. + + o last-acked - the TSN last acked by that peer endpoint; + + o last-sent - the TSN last sent to that peer endpoint; + + --------- + New text: (Section 10.2) + --------- + + E) COMMUNICATION LOST notification + + When SCTP loses communication to an endpoint completely (e.g., via + Heartbeats) or detects that the endpoint has performed an abort + operation, it shall invoke this notification on the ULP. + + The following shall be passed with the notification: + + o association id - Local handle to the SCTP association. + + + +Stewart, et al. Informational [Page 49] + +RFC 4460 SCTP Errata April 2006 + + + o status - This indicates what type of event has occurred; The + status may indicate that a failure OR a normal + termination event occurred in response to a shutdown + or abort request. + + The following may be passed with the notification: + + o data retrieval id - An identification used to retrieve unsent + and unacknowledged data. + + o last-acked - The TSN last acked by that peer endpoint. + + o last-sent - The TSN last sent to that peer endpoint. + + o Upper Layer Abort Reason - The abort reason specified in + case of a user-initiated abort. + +2.21.3. Solution Description + + The above allows an upper layer to provide its peer with an + indication of why the association was aborted. Therefore, an + addition error cause was introduced. + +2.22. Handling of Invalid Initiate Tag of INIT-ACK + +2.22.1. Description of the Problem + + RFC 2960 requires that the receiver of an INIT-ACK with the Initiate + Tag set to zero handles this as an error and sends back an ABORT. + But the sender of the INIT-ACK normally has no TCB, and thus the + ABORT is useless. + +2.22.2. Text Changes to the Document + + --------- + Old text: (Section 3.3.3) + --------- + + Initiate Tag: 32 bits (unsigned integer) + + The receiver of the INIT ACK records the value of the + Initiate Tag parameter. This value MUST be placed into + the Verification Tag field of every SCTP packet that the + INIT ACK receiver transmits within this association. + + The Initiate Tag MUST NOT take the value 0. See Section 5.3.1 + for more on the selection of the Initiate Tag value. + + + + +Stewart, et al. Informational [Page 50] + +RFC 4460 SCTP Errata April 2006 + + + If the value of the Initiate Tag in a received INIT ACK chunk + is found to be 0, the receiver MUST treat it as an error and + close the association by transmitting an ABORT. + + --------- + New text: (Section 3.3.3) + --------- + + Initiate Tag: 32 bits (unsigned integer) + + The receiver of the INIT ACK records the value of the + Initiate Tag parameter. This value MUST be placed into + the Verification Tag field of every SCTP packet that the + INIT ACK receiver transmits within this association. + + The Initiate Tag MUST NOT take the value 0. See Section 5.3.1 + for more on the selection of the Initiate Tag value. + + If the value of the Initiate Tag in a received INIT ACK + chunk is found to be 0, the receiver MUST destroy the + association discarding its TCB. The receiver MAY send an + ABORT for debugging purpose. + +2.22.3. Solution Description + + The new text does not require that the receiver of the invalid INIT- + ACK send the ABORT. This behavior is in tune with the error case of + invalid stream numbers in the INIT-ACK. However, sending an ABORT + for debugging purposes is allowed. + +2.23. Sending an ABORT in Response to an INIT + +2.23.1. Description of the Problem + + Whenever the receiver of an INIT chunk has to send an ABORT chunk in + response, for whatever reason, it is not stated clearly which + Verification Tag and value of the T-bit should be used. + +2.23.2. Text Changes to the Document + + --------- + Old text: (Section 8.4) + --------- + + 3) If the packet contains an INIT chunk with a Verification Tag + set to '0', process it as described in Section 5.1. + Otherwise, + + + + +Stewart, et al. Informational [Page 51] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 8.4) + --------- + + 3) If the packet contains an INIT chunk with a Verification Tag + set to '0', process it as described in Section 5.1. If, for + whatever reason, the INIT cannot be processed normally and + an ABORT has to be sent in response, the Verification Tag + of the packet containing the ABORT chunk MUST be the + Initiate tag of the received INIT chunk, and the T-Bit of + the ABORT chunk has to be set to 0, indicating that + a TCB was destroyed. Otherwise, + +2.23.3. Solution Description + + The new text stated clearly which value of the Verification Tag and + T-bit have to be used. + +2.24. Stream Sequence Number (SSN) Initialization + +2.24.1. Description of the Problem + + RFC 2960 does not describe the fact that the SSN has to be + initialized to 0, as required by RFC 2119. + +2.24.2. Text Changes to the Document + + --------- + Old text: (Section 6.5) + --------- + + The stream sequence number in all the streams shall start from 0 + when the association is established. Also, when the stream + sequence number reaches the value 65535 the next stream sequence + number shall be set to 0. + + --------- + New text: (Section 6.5) + --------- + + The stream sequence number in all the streams MUST start from 0 + when the association is established. Also, when the stream + sequence number reaches the value 65535 the next stream sequence + number MUST be set to 0. + + + + + + + +Stewart, et al. Informational [Page 52] + +RFC 4460 SCTP Errata April 2006 + + +2.24.3. Solution Description + + The 'shall' in the text is replaced by a 'MUST' to clearly state the + required behavior. + +2.25. SACK Packet Format + +2.25.1. Description of the Problem + + It is not clear in RFC 2960 whether a SACK must contain the fields + Number of Gap Ack Blocks and Number of Duplicate TSNs. + +2.25.2. Text Changes to the Document + + --------- + Old text: (Section 3.3.4) + --------- + + The SACK MUST contain the Cumulative TSN Ack and + Advertised Receiver Window Credit (a_rwnd) parameters. + + --------- + New text: (Section 3.3.4) + --------- + + The SACK MUST contain the Cumulative TSN Ack, + Advertised Receiver Window Credit (a_rwnd), Number + of Gap Ack Blocks, and Number of Duplicate TSNs fields. + +2.25.3. Solution Description + + The text has been modified. It is now clear that a SACK always + contains the fields Number of Gap Ack Blocks and Number of Duplicate + TSNs. + +2.26. Protocol Violation Error Cause + +2.26.1. Description of the Problem + + There are many situations where an SCTP endpoint may detect that its + peer violates the protocol. The result of such detection often + results in the association being destroyed by the sending of an + ABORT. Currently, there are only some error causes that could be + used to indicate the reason for the abort, but these do not cover all + cases. + + + + + + +Stewart, et al. Informational [Page 53] + +RFC 4460 SCTP Errata April 2006 + + +2.26.2. Text Changes to the Document + + Some of the changes given here already include changes suggested in + Section 2.6 and 2.21 of this document. + + --------- + Old text: (Section 3.3.10) + --------- + + Cause Code + Value Cause Code + --------- ---------------- + 1 Invalid Stream Identifier + 2 Missing Mandatory Parameter + 3 Stale Cookie Error + 4 Out of Resource + 5 Unresolvable Address + 6 Unrecognized Chunk Type + 7 Invalid Mandatory Parameter + 8 Unrecognized Parameters + 9 No User Data + 10 Cookie Received While Shutting Down + + Cause Length: 16 bits (unsigned integer) + + Set to the size of the parameter in bytes, including the Cause + Code, Cause Length, and Cause-Specific Information fields + + Cause-specific Information: variable length + + This field carries the details of the error condition. + + Sections 3.3.10.1 - 3.3.10.10 define error causes for SCTP. + Guidelines for the IETF to define new error cause values are + discussed in Section 13.3. + + + + + + + + + + + + + + + + +Stewart, et al. Informational [Page 54] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 3.3.10) + --------- + + Cause Code + Value Cause Code + --------- ---------------- + 1 Invalid Stream Identifier + 2 Missing Mandatory Parameter + 3 Stale Cookie Error + 4 Out of Resource + 5 Unresolvable Address + 6 Unrecognized Chunk Type + 7 Invalid Mandatory Parameter + 8 Unrecognized Parameters + 9 No User Data + 10 Cookie Received While Shutting Down + 11 Restart of an Association with New Addresses + 12 User Initiated Abort + 13 Protocol Violation + + Cause Length: 16 bits (unsigned integer) + + Set to the size of the parameter in bytes, including the Cause + Code, Cause Length, and Cause-Specific Information fields + + Cause-specific Information: variable length + + This field carries the details of the error condition. + + Sections 3.3.10.1 - 3.3.10.13 define error causes for SCTP. + Guidelines for the IETF to define new error cause values are + discussed in Section 13.3. + + --------- + New text: (Note: no old text; new error added in section 3.3.10) + --------- + + 3.3.10.13. Protocol Violation (13) + + Cause of error + -------------- + + This error cause MAY be included in ABORT chunks that are sent + because an SCTP endpoint detects a protocol violation of the peer + that is not covered by the error causes described in 3.3.10.1 to + 3.3.10.12. An implementation MAY provide additional information + specifying what kind of protocol violation has been detected. + + + +Stewart, et al. Informational [Page 55] + +RFC 4460 SCTP Errata April 2006 + + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cause Code=13 | Cause Length=Variable | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / Additional Information / + \ \ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +2.26.3. Solution Description + + An additional error cause has been defined that can be used by an + endpoint to indicate a protocol violation of the peer. + +2.27. Reporting of Unrecognized Parameters + +2.27.1. Description of the Problem + + It is not stated clearly in RFC 2960 [5] how unrecognized parameters + should be reported. Unrecognized parameters in an INIT chunk could + be reported in the INIT-ACK chunk or in a separate ERROR chunk, which + can get lost. Unrecognized parameters in an INIT-ACK chunk have to + be reported in an ERROR-chunk. This can be bundled with the COOKIE- + ERROR chunk or sent separately. If it is sent separately and + received before the COOKIE-ECHO, it will be handled as an OOTB + packet, resulting in sending out an ABORT chunk. Therefore, the + association would not be established. + +2.27.2. Text Changes to the Document + + Some of the changes given here already include changes suggested in + Section 2.2 of this document. + + --------- + Old text: (Section 3.2.1) + --------- + + 00 - Stop processing this SCTP packet and discard it, do not process + any further chunks within it. + + 01 - Stop processing this SCTP packet and discard it, do not process + any further chunks within it, and report the unrecognized + parameter in an 'Unrecognized Parameter Type' (in either an + ERROR or in the INIT ACK). + + 10 - Skip this parameter and continue processing. + + 11 - Skip this parameter and continue processing but report the + unrecognized parameter in an 'Unrecognized Parameter Type' (in + either an ERROR or in the INIT ACK). + + + +Stewart, et al. Informational [Page 56] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 3.2.1) + --------- + + 00 - Stop processing this SCTP chunk and discard it; do not process + any further parameters within this chunk. + + 01 - Stop processing this SCTP chunk and discard it, do not process + any further parameters within this chunk, and report the + unrecognized parameter in an 'Unrecognized Parameter Type', as + described in 3.2.2. + + 10 - Skip this parameter and continue processing. + + 11 - Skip this parameter and continue processing but report the + unrecognized parameter in an 'Unrecognized Parameter Type', as + described in 3.2.2. + + --------- + New text: (Note: no old text; clarification added in Section 3.2) + --------- + + 3.2.2. Reporting of Unrecognized Parameters + + If the receiver of an INIT chunk detects unrecognized parameters + and has to report them according to Section 3.2.1, it MUST put + the 'Unrecognized Parameter' parameter(s) in the INIT-ACK chunk + sent in response to the INIT-chunk. Note that if the receiver + of the INIT chunk is NOT going to establish an association (e.g., + due to lack of resources), then no report would be sent back. + + If the receiver of an INIT-ACK chunk detects unrecognized + parameters and has to report them according to Section 3.2.1, + it SHOULD bundle the ERROR chunk containing the + 'Unrecognized Parameter' error cause with the COOKIE-ECHO + chunk sent in response to the INIT-ACK chunk. If the + receiver of the INIT-ACK cannot bundle the COOKIE-ECHO chunk + with the ERROR chunk, the ERROR chunk MAY be sent separately + but not before the COOKIE-ACK has been received. + + Note: Any time a COOKIE-ECHO is sent in a packet, it MUST be the + first chunk. + +2.27.3. Solution Description + + The procedure of reporting unrecognized parameters has been described + clearly. + + + + +Stewart, et al. Informational [Page 57] + +RFC 4460 SCTP Errata April 2006 + + +2.28. Handling of IP Address Parameters + +2.28.1. Description of the Problem + + It is not stated clearly in RFC 2960 [5] how an SCTP endpoint that + supports either IPv4 addresses or IPv6 addresses should respond if + IPv4 and IPv6 addresses are presented by the peer in the INIT or + INIT-ACK chunk. + +2.28.2. Text Changes to the Document + + --------- + Old text: (Section 5.1.2) + --------- + + IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK + fails to resolve the address parameter due to an unsupported type, + it can abort the initiation process and then attempt a + re-initiation by using a 'Supported Address Types' parameter in + the new INIT to indicate what types of address it prefers. + + --------- + New text: (Section 5.1.2) + --------- + + IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK + fails to resolve the address parameter due to an unsupported type, + it can abort the initiation process and then attempt a re- + initiation by using a 'Supported Address Types' parameter in the + new INIT to indicate what types of address it prefers. + + IMPLEMENTATION NOTE: If an SCTP endpoint that only supports either + IPv4 or IPv6 receives IPv4 and IPv6 addresses in an INIT or INIT- + ACK chunk from its peer, it MUST use all the addresses belonging + to the supported address family. The other addresses MAY be + ignored. The endpoint SHOULD NOT respond with any kind of error + indication. + +2.28.3. Solution Description + + The procedure of handling IP address parameters has been described + clearly. + + + + + + + + + +Stewart, et al. Informational [Page 58] + +RFC 4460 SCTP Errata April 2006 + + +2.29. Handling of COOKIE ECHO Chunks When a TCB Exists + +2.29.1. Description of the Problem + + The description of the behavior in RFC 2960 [5] when a COOKIE ECHO + chunk and a TCB exist could be misunderstood. When a COOKIE ECHO is + received, a TCB exists and the local tag and peer's tag match, it is + stated that the endpoint should enter the ESTABLISHED state if it has + not already done so and send a COOKIE ACK. It was not clear that, in + the case the endpoint has already left the ESTABLISHED state again, + then it should not go back to established. In case D, the endpoint + can only enter state ESTABLISHED from COOKIE-ECHOED because in state + CLOSED it has no TCB and in state COOKIE-WAIT it has a TCB but knows + nothing about the peer's tag, which is requested to match in this + case. + +2.29.2. Text Changes to the Document + + --------- + Old text: (Section 5.2.4) + --------- + D) When both local and remote tags match the endpoint should + always enter the ESTABLISHED state, if it has not already + done so. It should stop any init or cookie timers that may + be running and send a COOKIE ACK. + + --------- + New text: (Section 5.2.4) + --------- + D) When both local and remote tags match, the endpoint should + enter the ESTABLISHED state, if it is in the COOKIE-ECHOED + state. It should stop any cookie timer that may + be running and send a COOKIE ACK. + +2.29.3. Solution Description + + The procedure of handling of COOKIE-ECHO chunks when a TCB exists has + been described clearly. + +2.30. The Initial Congestion Window Size + +2.30.1. Description of the Problem + + RFC 2960 was published with the intention of having the same + congestion control properties as TCP. Since the publication of RFC + 2960, TCP's initial congestion window size has been increased via RFC + 3390. This same update will be needed for SCTP to keep SCTP's + congestion control properties equivalent to that of TCP. + + + +Stewart, et al. Informational [Page 59] + +RFC 4460 SCTP Errata April 2006 + + +2.30.2. Text Changes to the Document + + --------- + Old text: (Section 7.2.1) + --------- + o The initial cwnd before DATA transmission or after a + sufficiently long idle period MUST be <= 2*MTU. + + --------- + New text: (Section 7.2.1) + --------- + o The initial cwnd before DATA transmission or after a + sufficiently long idle period MUST be set to + min(4*MTU, max (2*MTU, 4380 bytes)). + + --------- + Old text: (Section 7.2.1) + --------- + o When the endpoint does not transmit data on a given transport + address, the cwnd of the transport address should be adjusted + to max(cwnd/2, 2*MTU) per RTO. + + --------- + New text: (Section 7.2.1) + --------- + o When the endpoint does not transmit data on a given transport + address, the cwnd of the transport address should be adjusted + to max(cwnd/2, 4*MTU) per RTO. + + --------- + Old text: (Section 7.2.2) + --------- + o Same as in the slow start, when the sender does not transmit + DATA on a given transport address, the cwnd of the transport + address should be adjusted to max(cwnd / 2, 2*MTU) per RTO. + + --------- + New text: (Section 7.2.2) + --------- + o Same as in the slow start, when the sender does not transmit + DATA on a given transport address, the cwnd of the transport + address should be adjusted to max(cwnd / 2, 4*MTU) per RTO. + + + + + + + + + +Stewart, et al. Informational [Page 60] + +RFC 4460 SCTP Errata April 2006 + + + --------- + Old text: (Section 7.2.3) + --------- + + 7.2.3. Congestion Control + + Upon detection of packet losses from SACK (see Section 7.2.4), an + endpoint should do the following: + + ssthresh = max(cwnd/2, 2*MTU) + cwnd = ssthresh + + Basically, a packet loss causes cwnd to be cut in half. + + When the T3-rtx timer expires on an address, SCTP should perform + slow start by + + ssthresh = max(cwnd/2, 2*MTU) + cwnd = 1*MTU + + --------- + New text: (Section 7.2.3) + --------- + + 7.2.3 Congestion Control + + Upon detection of packet losses from SACK (see Section 7.2.4), An + endpoint should do the following: + + ssthresh = max(cwnd/2, 4*MTU) + cwnd = ssthresh + + Basically, a packet loss causes cwnd to be cut in half. + + When the T3-rtx timer expires on an address, SCTP should perform + slow start by: + + ssthresh = max(cwnd/2, 4*MTU) + cwnd = 1*MTU + +2.30.3. Solution Description + + The change to SCTP's initial congestion window will allow it to + continue to maintain the same congestion control properties as TCP. + + + + + + + +Stewart, et al. Informational [Page 61] + +RFC 4460 SCTP Errata April 2006 + + +2.31. Stream Sequence Numbers in Figures + +2.31.1. Description of the Problem + + In Section 2.24 of this document, it is clarified that the SSN are + initialized with 0. Two figures in RFC 2960 [5] illustrate that they + start with 1. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Informational [Page 62] + +RFC 4460 SCTP Errata April 2006 + + +2.31.2. Text Changes to the Document + + --------- + Old text: (Section 7.2.1) + --------- + + Endpoint A Endpoint Z + {app sets association with Z} + (build TCB) + INIT [I-Tag=Tag_A + & other info] ------\ + (Start T1-init timer) \ + (Enter COOKIE-WAIT state) \---> (compose temp TCB and Cookie_Z) + /-- INIT ACK [Veri Tag=Tag_A, + / I-Tag=Tag_Z, + (Cancel T1-init timer) <-----/ Cookie_Z, & other info] + (destroy temp TCB) + COOKIE ECHO [Cookie_Z] ------\ + (Start T1-init timer) \ + (Enter COOKIE-ECHOED state) \---> (build TCB enter ESTABLISHED + state) + /---- COOKIE-ACK + / + (Cancel T1-init timer, <-----/ + Enter ESTABLISHED state) + {app sends 1st user data; strm 0} + DATA [TSN=initial TSN_A + Strm=0,Seq=1 & user data]--\ + (Start T3-rtx timer) \ + \-> + /----- SACK [TSN Ack=init + / TSN_A,Block=0] + (Cancel T3-rtx timer) <------/ + ... + {app sends 2 messages;strm 0} + /---- DATA + / [TSN=init TSN_Z + <--/ Strm=0,Seq=1 & user data 1] + SACK [TSN Ack=init TSN_Z, / ---- DATA + Block=0] --------\ / [TSN=init TSN_Z +1, + \/ Strm=0,Seq=2 & user data 2] + <------/\ + \ + \------> + + Figure 4: INITiation Example + + + + + +Stewart, et al. Informational [Page 63] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 7.2.1) + --------- + + + Endpoint A Endpoint Z + {app sets association with Z} + (build TCB) + INIT [I-Tag=Tag_A + & other info] ------\ + (Start T1-init timer) \ + (Enter COOKIE-WAIT state) \---> (compose temp TCB and Cookie_Z) + /-- INIT ACK [Veri Tag=Tag_A, + / I-Tag=Tag_Z, + (Cancel T1-init timer) <------/ Cookie_Z, & other info] + (destroy temp TCB) + COOKIE ECHO [Cookie_Z] ------\ + (Start T1-init timer) \ + (Enter COOKIE-ECHOED state) \---> (build TCB enter ESTABLISHED + state) + /---- COOKIE-ACK + / + (Cancel T1-init timer, <-----/ + Enter ESTABLISHED state) + {app sends 1st user data; strm 0} + DATA [TSN=initial TSN_A + Strm=0,Seq=0 & user data]--\ + (Start T3-rtx timer) \ + \-> + /----- SACK [TSN Ack=init + / TSN_A,Block=0] + (Cancel T3-rtx timer) <------/ + ... + {app sends 2 messages;strm 0} + /---- DATA + / [TSN=init TSN_Z + <--/ Strm=0,Seq=0 & user data 1] + SACK [TSN Ack=init TSN_Z, /---- DATA + Block=0] --------\ / [TSN=init TSN_Z +1, + \/ Strm=0,Seq=1 & user data 2] + <------/\ + \ + \------> + + Figure 4: INITiation Example + + + + + + +Stewart, et al. Informational [Page 64] + +RFC 4460 SCTP Errata April 2006 + + + --------- + Old text: (Section 5.2.4.1) + --------- + + Endpoint A Endpoint Z + <------------ Association is established----------------------> + Tag=Tag_A Tag=Tag_Z + <-------------------------------------------------------------> + {A crashes and restarts} + {app sets up a association with Z} + (build TCB) + INIT [I-Tag=Tag_A' + & other info] --------\ + (Start T1-init timer) \ + (Enter COOKIE-WAIT state) \---> (find a existing TCB + compose temp TCB and Cookie_Z + with Tie-Tags to previous + association) + /--- INIT ACK [Veri Tag=Tag_A', + / I-Tag=Tag_Z', + (Cancel T1-init timer) <------/ Cookie_Z[TieTags= + Tag_A,Tag_Z + & other info] + (destroy temp TCB,leave original + in place) + COOKIE ECHO [Veri=Tag_Z', + Cookie_Z + Tie=Tag_A, + Tag_Z]----------\ + (Start T1-init timer) \ + (Enter COOKIE-ECHOED state) \---> (Find existing association, + Tie-Tags match old tags, + Tags do not match i.e., + case X X M M above, + Announce Restart to ULP + and reset association). + /---- COOKIE-ACK + (Cancel T1-init timer, <------/ + Enter ESTABLISHED state) + {app sends 1st user data; strm 0} + DATA [TSN=initial TSN_A + Strm=0,Seq=1 & user data]--\ + (Start T3-rtx timer) \ + \-> + /--- SACK [TSN Ack=init TSN_A,Block=0] + (Cancel T3-rtx timer) <------/ + + Figure 5: A Restart Example + + + +Stewart, et al. Informational [Page 65] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 5.2.4.1) + --------- + + Endpoint A Endpoint Z + <-------------- Association is established----------------------> + Tag=Tag_A Tag=Tag_Z + <---------------------------------------------------------------> + {A crashes and restarts} + {app sets up a association with Z} + (build TCB) + INIT [I-Tag=Tag_A' + & other info] --------\ + (Start T1-init timer) \ + (Enter COOKIE-WAIT state) \---> (find a existing TCB + compose temp TCB and Cookie_Z + with Tie-Tags to previous + association) + /--- INIT ACK [Veri Tag=Tag_A', + / I-Tag=Tag_Z', + (Cancel T1-init timer) <------/ Cookie_Z[TieTags= + Tag_A,Tag_Z + & other info] + (destroy temp TCB,leave original + in place) + COOKIE ECHO [Veri=Tag_Z', + Cookie_Z + Tie=Tag_A, + Tag_Z]----------\ + (Start T1-init timer) \ + (Enter COOKIE-ECHOED state) \---> (Find existing association, + Tie-Tags match old tags, + Tags do not match i.e., + case X X M M above, + Announce Restart to ULP + and reset association). + /---- COOKIE-ACK + (Cancel T1-init timer, <------/ + Enter ESTABLISHED state) + {app sends 1st user data; strm 0} + DATA [TSN=initial TSN_A + Strm=0,Seq=0 & user data]--\ + (Start T3-rtx timer) \ + \-> + /--- SACK [TSN Ack=init TSN_A,Block=0] + (Cancel T3-rtx timer) <------/ + + Figure 5: A Restart Example + + + +Stewart, et al. Informational [Page 66] + +RFC 4460 SCTP Errata April 2006 + + +2.31.3. Solution description + + Figure 4 and 5 were changed so that the SSN starts with 0 instead of + 1. + +2.32. Unrecognized Parameters + +2.32.1. Description of the Problem + + The RFC does not state clearly in Section 3.3.3.1 whether one or + multiple unrecognized parameters are included in the 'Unrecognized + Parameter' parameter. + +2.32.2. Text Changes to the Document + + --------- + Old text: (Section 3.3.3) + --------- + Variable Parameters Status Type Value + ------------------------------------------------------------- + State Cookie Mandatory 7 + IPv4 Address (Note 1) Optional 5 + IPv6 Address (Note 1) Optional 6 + Unrecognized Parameters Optional 8 + Reserved for ECN Capable (Note 2) Optional 32768 (0x8000) + Host Name Address (Note 3) Optional 11 + + --------- + New text: (Section 3.3.3) + --------- + Variable Parameters Status Type Value + ------------------------------------------------------------- + State Cookie Mandatory 7 + IPv4 Address (Note 1) Optional 5 + IPv6 Address (Note 1) Optional 6 + Unrecognized Parameter Optional 8 + Reserved for ECN Capable (Note 2) Optional 32768 (0x8000) + Host Name Address (Note 3) Optional 11 + + + --------- + Old text: (Section 3.3.3.1) + --------- + Unrecognized Parameters: + + Parameter Type Value: 8 + + Parameter Length: Variable Size. + + + +Stewart, et al. Informational [Page 67] + +RFC 4460 SCTP Errata April 2006 + + + Parameter Value: + This parameter is returned to the originator of the INIT + chunk when the INIT contains an unrecognized parameter + which has a value that indicates that it should be reported + to the sender. This parameter value field will contain + unrecognized parameters copied from the INIT chunk complete + with Parameter Type, Length and Value fields. + + --------- + New text: (Section 3.3.3.1) + --------- + Unrecognized Parameter: + + Parameter Type Value: 8 + + Parameter Length: Variable Size. + + Parameter Value: + + This parameter is returned to the originator of the INIT + chunk when the INIT contains an unrecognized parameter + that has a value that indicates that it should be reported + to the sender. This parameter value field will contain the + unrecognized parameter copied from the INIT chunk complete + with Parameter Type, Length, and Value fields. + +2.32.3. Solution Description + + The new text states clearly that only one unrecognized parameter is + reported per parameter. + +2.33. Handling of Unrecognized Parameters + +2.33.1. Description of the Problem + + It is not stated clearly in RFC 2960 [5] how unrecognized parameters + should be handled. The problem comes up when an INIT contains an + unrecognized parameter with highest bits 00. It was not clear + whether an INIT-ACK should be sent. + +2.33.2. Text Changes to the Document + + Some of the changes given here already include changes suggested in + Section 2.27 of this document. + + + + + + + +Stewart, et al. Informational [Page 68] + +RFC 4460 SCTP Errata April 2006 + + + --------- + Old text: (Section 3.2.1) + --------- + + 00 - Stop processing this SCTP packet and discard it, do not process + any further chunks within it. + + 01 - Stop processing this SCTP packet and discard it, do not process + any further chunks within it, and report the unrecognized + parameter in an 'Unrecognized Parameter Type' (in either an + ERROR or in the INIT ACK). + + 10 - Skip this parameter and continue processing. + + 11 - Skip this parameter and continue processing but report the + unrecognized parameter in an 'Unrecognized Parameter Type' (in + either an ERROR or in the INIT ACK). + + --------- + New text: (Section 3.2.1) + --------- + + 00 - Stop processing this parameter; do not process + any further parameters within this chunk. + + 01 - Stop processing this parameter, do not process + any further parameters within this chunk, and report the + unrecognized parameter in an 'Unrecognized Parameter Type', as + described in 3.2.2. + + 10 - Skip this parameter and continue processing. + + 11 - Skip this parameter and continue processing but report the + unrecognized parameter in an 'Unrecognized Parameter Type', as + described in 3.2.2. + + + --------- + New text: (Note: no old text; clarification added in section 3.2) + --------- + + 3.2.2. Reporting of Unrecognized Parameters + + If the receiver of an INIT chunk detects unrecognized parameters and + has to report them according to Section 3.2.1, it MUST put the + 'Unrecognized Parameter' parameter(s) in the INIT-ACK chunk sent in + response to the INIT-chunk. Note that if the receiver of the INIT + chunk is NOT going to establish an association (e.g., due to lack of + + + +Stewart, et al. Informational [Page 69] + +RFC 4460 SCTP Errata April 2006 + + + resources), an 'Unrecognized Parameter' would NOT be included with + any ABORT being sent to the sender of the INIT. + + If the receiver of an INIT-ACK chunk detects unrecognized parameters + and has to report them according to Section 3.2.1, it SHOULD bundle + the ERROR chunk containing the 'Unrecognized Parameter' error cause + with the COOKIE-ECHO chunk sent in response to the INIT-ACK chunk. + If the receiver of the INIT-ACK cannot bundle the COOKIE-ECHO chunk + with the ERROR chunk, the ERROR chunk MAY be sent separately but not + before the COOKIE-ACK has been received. + + Note: Any time a COOKIE-ECHO is sent in a packet, it MUST be the + first chunk. + +2.33.3. Solution Description + + The procedure of handling unrecognized parameters has been described + clearly. + +2.34. Tie Tags + +2.34.1. Description of the Problem + + RFC 2960 requires that Tie-Tags be included in the COOKIE. The + cookie may not be encrypted. An attacker could discover the value of + the Verification Tags by analyzing cookies received after sending an + INIT. + +2.34.2. Text Changes to the Document + + --------- + Old text: (Section 1.4) + --------- + o Tie-Tags: Verification Tags from a previous association. These + Tags are used within a State Cookie so that the newly + restarting association can be linked to the original + association within the endpoint that did not restart. + + --------- + New text: (Section 1.4) + --------- + + o Tie-Tags: Two 32-bit random numbers that together make a 64- + bit nonce. These Tags are used within a State Cookie and TCB + so that a newly restarting association can be linked to the + original association within the endpoint that did not restart + and yet not reveal the true Verification Tags of an existing + association. + + + +Stewart, et al. Informational [Page 70] + +RFC 4460 SCTP Errata April 2006 + + + --------- + Old text: (Section 5.2.1) + --------- + + For an endpoint that is in the COOKIE-ECHOED state it MUST + populate its Tie-Tags with the Tag information of itself and + its peer (see Section 5.2.2 for a description of the Tie-Tags). + + --------- + New text: (Section 5.2.1) + --------- + For an endpoint that is in the COOKIE-ECHOED state it MUST + populate its Tie-Tags within both the association TCB and + inside the State Cookie (see section 5.2.2 for a description + of the Tie-Tags). + + + --------- + Old text: (Section 5.2.2) + --------- + Unless otherwise stated, upon reception of an unexpected INIT for + this association, the endpoint shall generate an INIT ACK with a + State Cookie. In the outbound INIT ACK the endpoint MUST copy its + current Verification Tag and peer's Verification Tag into a + reserved place within the state cookie. We shall refer to these + locations as the Peer's-Tie-Tag and the Local-Tie-Tag. The + outbound SCTP packet containing this INIT ACK MUST carry a + Verification Tag value equal to the Initiation Tag found in the + unexpected INIT. And the INIT ACK MUST contain a new Initiation + Tag (randomly generated see Section 5.3.1). Other parameters + for the endpoint SHOULD be copied from the existing parameters + of the association (e.g., number of outbound streams) into the + INIT ACK and cookie. + + --------- + New text: (Section 5.2.2) + --------- + + Unless otherwise stated, upon receipt of an unexpected INIT for + this association, the endpoint MUST generate an INIT ACK with a + State Cookie. In the outbound INIT ACK, the endpoint MUST copy + its current Tie-Tags to a reserved place within the State Cookie + and the association's TCB. We shall refer to these locations + inside the cookie as the Peer's-Tie-Tag and the Local-Tie-Tag. We + will refer to the copy within an association's TCB as the Local + Tag and Peer's Tag. The outbound SCTP packet containing this INIT + ACK MUST carry a Verification Tag value equal to the Initiation + Tag found in the unexpected INIT. And the INIT ACK MUST contain a + + + +Stewart, et al. Informational [Page 71] + +RFC 4460 SCTP Errata April 2006 + + + new Initiation Tag (randomly generated; see Section 5.3.1). Other + parameters for the endpoint SHOULD be copied from the existing + parameters of the association (e.g., number of outbound streams) + into the INIT ACK and cookie. + +2.34.3. Solution Description + + The solution to this problem is not to use the real Verification Tags + within the State Cookie as tie-tags. Instead, two 32-bit random + numbers are created to form one 64-bit nonce and stored both in the + State Cookie and the existing association TCB. This prevents + exposing the Verification Tags inadvertently. + +2.35. Port Number Verification in the COOKIE-ECHO + +2.35.1. Description of the Problem + + The State Cookie sent by a listening SCTP endpoint may not contain + the original port numbers or the local Verification Tag. It is then + possible that the endpoint, on receipt of the COOKIE-ECHO, will not + be able to verify that these values match the original values found + in the INIT and INIT-ACK that began the association setup. + +2.35.2. Text Changes to the Document + + --------- + Old text: (Section 5.1.5) + --------- + 3) Compare the creation timestamp in the State Cookie to the + current local time. If the elapsed time is longer than the + lifespan carried in the State Cookie, then the packet, + including the COOKIE ECHO and any attached DATA chunks, + SHOULD be discarded and the endpoint MUST transmit an ERROR + chunk with a "Stale Cookie" error cause to the peer endpoint, + + 4) If the State Cookie is valid, create an association to the + sender of the COOKIE ECHO chunk with the information in the + TCB data carried in the COOKIE ECHO, and enter the + ESTABLISHED state, + + 5) Send a COOKIE ACK chunk to the peer acknowledging reception + of the COOKIE ECHO. The COOKIE ACK MAY be bundled with an + outbound DATA chunk or SACK chunk; however, the COOKIE ACK + MUST be the first chunk in the SCTP packet. + + 6) Immediately acknowledge any DATA chunk bundled with the COOKIE + ECHO with a SACK (subsequent DATA chunk acknowledgement should + follow the rules defined in Section 6.2). As mentioned in step + + + +Stewart, et al. Informational [Page 72] + +RFC 4460 SCTP Errata April 2006 + + + 5), if the SACK is bundled with the COOKIE ACK, the COOKIE ACK + MUST appear first in the SCTP packet. + + --------- + New text: (Section 5.1.5) + --------- + + 3) Compare the port numbers and the Verification Tag contained + within the COOKIE ECHO chunk to the actual port numbers and the + Verification Tag within the SCTP common header of the received + packet. If these values do not match, the packet MUST be + silently discarded. + + 4) Compare the creation timestamp in the State Cookie to the + current local time. If the elapsed time is longer than the + lifespan carried in the State Cookie, then the packet, + including the COOKIE ECHO and any attached DATA chunks, + SHOULD be discarded, and the endpoint MUST transmit an + ERROR chunk with a "Stale Cookie" error cause to the peer + endpoint. + + 5) If the State Cookie is valid, create an association to the + sender of the COOKIE ECHO chunk with the information in the + TCB data carried in the COOKIE ECHO and enter the + ESTABLISHED state. + + 6) Send a COOKIE ACK chunk to the peer acknowledging receipt of + the COOKIE ECHO. The COOKIE ACK MAY be bundled with an + outbound DATA chunk or SACK chunk; however, the COOKIE ACK + MUST be the first chunk in the SCTP packet. + + 7) Immediately acknowledge any DATA chunk bundled with the COOKIE + ECHO with a SACK (subsequent DATA chunk acknowledgement should + follow the rules defined in Section 6.2). As mentioned in step + 5, if the SACK is bundled with the COOKIE ACK, the COOKIE ACK + MUST appear first in the SCTP packet. + +2.35.3. Solution Description + + By including both port numbers and the local Verification Tag within + the State Cookie and verifying these during COOKIE-ECHO processing, + this issue is resolved. + + + + + + + + + +Stewart, et al. Informational [Page 73] + +RFC 4460 SCTP Errata April 2006 + + +2.36. Path Initialization + +2.36.1. Description of the Problem + + When an association enters the ESTABLISHED state, the endpoint has no + verification that all of the addresses presented by the peer do in + fact belong to the peer. This could cause various forms of denial of + service attacks. + +2.36.2. Text Changes to the Document + + --------- + Old text: None + --------- + + --------- + New text: (Section 5.4) + --------- + 5.4. Path Verification + + During association establishment, the two peers exchange a list of + addresses. In the predominant case, these lists accurately represent + the addresses owned by each peer. However, it is possible that a + misbehaving peer may supply addresses that it does not own. To + prevent this, the following rules are applied to all addresses of the + new association: + + 1) Any address passed to the sender of the INIT by its upper layer is + automatically considered to be CONFIRMED. + + 2) For the receiver of the COOKIE-ECHO the only CONFIRMED address is + the one that the INIT-ACK was sent to. + + 3) All other addresses not covered by rules 1 and 2 are considered + UNCONFIRMED and are subject to probing for verification. + + To probe an address for verification, an endpoint will send + HEARTBEATs including a 64-bit random nonce and a path indicator (to + identify the address that the HEARTBEAT is sent to) within the + HEARTBEAT parameter. + + Upon receipt of the HEARTBEAT-ACK, a verification is made that the + nonce included in the HEARTBEAT parameter is the one sent to the + address indicated inside the HEARTBEAT parameter. When this match + occurs, the address that the original HEARTBEAT was sent to is now + considered CONFIRMED and available for normal data transfer. + + + + + +Stewart, et al. Informational [Page 74] + +RFC 4460 SCTP Errata April 2006 + + + These probing procedures are started when an association moves to the + ESTABLISHED state and are ended when all paths are confirmed. + + Each RTO a probe may be sent on an active UNCONFIRMED path in an + attempt to move it to the CONFIRMED state. If during this probing + the path becomes inactive, this rate is lowered to the normal + HEARTBEAT rate. At the expiration of the RTO timer, the error + counter of any path that was probed but not CONFIRMED is incremented + by one and subjected to path failure detection, as defined in section + 8.2. When probing UNCONFIRMED addresses, however, the association + overall error count is NOT incremented. + + The number of HEARTBEATS sent at each RTO SHOULD be limited by the + HB.Max.Burst parameter. It is an implementation decision as to how + to distribute HEARTBEATS to the peer's addresses for path + verification. + + Whenever a path is confirmed, an indication MAY be given to the upper + layer. + + An endpoint MUST NOT send any chunks to an UNCONFIRMED address, with + the following exceptions: + + - A HEARTBEAT including a nonce MAY be sent to an UNCONFIRMED + address. + + - A HEARTBEAT-ACK MAY be sent to an UNCONFIRMED address. + + - A COOKIE-ACK MAY be sent to an UNCONFIRMED address, but it MUST be + bundled with a HEARTBEAT including a nonce. An implementation that + does NOT support bundling MUST NOT send a COOKIE-ACK to an + UNCONFIRMED address. + + - A COOKE-ECHO MAY be sent to an UNCONFIRMED address, but it MUST be + bundled with a HEARTBEAT including a nonce, and the packet MUST NOT + exceed the path MTU. If the implementation does NOT support + bundling or if the bundled COOKIE-ECHO plus HEARTBEAT (including + nonce) would exceed the path MTU, then the implementation MUST NOT + send a COOKIE-ECHO to an UNCONFIRMED address. + + --------- + Old text: (Section 14) + --------- + + 14. Suggested SCTP Protocol Parameter Values + + The following protocol parameters are RECOMMENDED: + + + + +Stewart, et al. Informational [Page 75] + +RFC 4460 SCTP Errata April 2006 + + + RTO.Initial - 3 seconds + RTO.Min - 1 second + RTO.Max - 60 seconds + RTO.Alpha - 1/8 + RTO.Beta - 1/4 + Valid.Cookie.Life - 60 seconds + Association.Max.Retrans - 10 attempts + Path.Max.Retrans - 5 attempts (per destination address) + Max.Init.Retransmits - 8 attempts + HB.interval - 30 seconds + + --------- + New text: (Section 14) + --------- + + 14. Suggested SCTP Protocol Parameter Values + + The following protocol parameters are RECOMMENDED: + + RTO.Initial - 3 seconds + RTO.Min - 1 second + RTO.Max - 60 seconds + Max.Burst - 4 + RTO.Alpha - 1/8 + RTO.Beta - 1/4 + Valid.Cookie.Life - 60 seconds + Association.Max.Retrans - 10 attempts + Path.Max.Retrans - 5 attempts (per destination address) + Max.Init.Retransmits - 8 attempts + HB.Interval - 30 seconds + HB.Max.Burst - 1 + +2.36.3. Solution Description + + By properly setting up initial path state and accelerated probing via + HEARTBEAT's, a new association can verify that all addresses + presented by a peer belong to that peer. + +2.37. ICMP Handling Procedures + +2.37.1. Description of the Problem + + RFC 2960 does not describe how ICMP messages should be processed by + an SCTP endpoint. + + + + + + + +Stewart, et al. Informational [Page 76] + +RFC 4460 SCTP Errata April 2006 + + +2.37.2. Text Changes to the Document + + -------- + Old text: None + -------- + + --------- + New text + --------- + + 11.5. Protection of Non-SCTP Capable Hosts. + + To provide a non-SCTP capable host with the same level of protection + against attacks as for SCTP-capable ones, all SCTP stacks MUST + implement the ICMP handling described in Appendix C. + + When an SCTP stack receives a packet containing multiple control or + DATA chunks and the processing of the packet requires the sending of + multiple chunks in response, the sender of the response chunk(s) MUST + NOT send more than one packet. If bundling is supported, multiple + response chunks that fit into a single packet MAY be bundled together + into one single response packet. If bundling is not supported, then + the sender MUST NOT send more than one response chunk and MUST + discard all other responses. Note that this rule does NOT apply to a + SACK chunk, since a SACK chunk is, in itself, a response to DATA and + a SACK does not require a response of more DATA. + + An SCTP implementation SHOULD abort the association if it receives a + SACK acknowledging a TSN that has not been sent. + + An SCTP implementation that receives an INIT that would require a + large packet in response, due to the inclusion of multiple ERROR + parameters, MAY (at its discretion) elect to omit some or all of the + ERROR parameters to reduce the size of the INIT-ACK. Due to a + combination of the size of the COOKIE parameter and the number of + addresses a receiver of an INIT may be indicating to a peer, it is + always possible that the INIT-ACK will be larger than the original + INIT. An SCTP implementation SHOULD attempt to make the INIT-ACK as + small as possible to reduce the possibility of byte amplification + attacks. + + --------- + Old text: None + --------- + + + + + + + +Stewart, et al. Informational [Page 77] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Appendix C) + --------- + + Appendix C ICMP Handling + + Whenever an ICMP message is received by an SCTP endpoint the + following procedures MUST be followed to ensure proper utilization of + the information being provided by layer 3. + + ICMP1) An implementation MAY ignore all ICMPv4 messages where the + type field is not set to "Destination Unreachable". + + ICMP2) An implementation MAY ignore all ICMPv6 messages where the + type field is not "Destination Unreachable, "Parameter + Problem" or "Packet Too Big". + + ICMP3) An implementation MAY ignore any ICMPv4 messages where the + code does not indicate "Protocol Unreachable" or + "Fragmentation Needed". + + ICMP4) An implementation MAY ignore all ICMPv6 messages of type + "Parameter Problem" if the code is not "Unrecognized next + header type encountered". + + ICMP5) An implementation MUST use the payload of the ICMP message (V4 + or V6) to locate the association that sent the message that + ICMP is responding to. If the association cannot be found, an + implementation SHOULD ignore the ICMP message. + + ICMP6) An implementation MUST validate that the Verification Tag + contained in the ICMP message matches the verification tag of + the peer. If the Verification Tag is not 0 and does NOT + match, discard the ICMP message. If it is 0 and the ICMP + message contains enough bytes to verify that the chunk type is + an INIT chunk and that the initiate tag matches the tag of the + peer, continue with ICMP7. If the ICMP message is too short + or the chunk type or the initiate tag does not match, silently + discard the packet. + + ICMP7) If the ICMP message is either a V6 "Packet Too Big" or a V4 + "Fragmentation Needed", an implementation MAY process this + information as defined for PATH MTU discovery. + + ICMP8) If the ICMP code is a "Unrecognized next header type + encountered" or a "Protocol Unreachable", an implementation + MUST treat this message as an abort with the T bit set if it + does not contain an INIT chunk. If it does contain an INIT + + + +Stewart, et al. Informational [Page 78] + +RFC 4460 SCTP Errata April 2006 + + + chunk and the association is in COOKIE-WAIT state, handle the + ICMP message like an ABORT. + + ICMP9) If the ICMPv6 code is "Destination Unreachable", the + implementation MAY mark the destination into the unreachable + state or alternatively increment the path error counter. + + Note that these procedures differ from RFC 1122 [1] and from its + requirements for processing of port-unreachable messages and the + requirements that an implementation MUST abort associations in + response to a "protocol unreachable" message. Port unreachable + messages are not processed, since an implementation will send an + ABORT, not a port unreachable. The stricter handling of the + "protocol unreachable" message is due to security concerns for hosts + that do NOT support SCTP. + +2.37.3. Solution Description + + The new appendix now describes proper handling of ICMP messages in + conjunction with SCTP. + +2.38. Checksum + +2.38.1. Description of the problem + + RFC 3309 [6] changes the SCTP checksum due to weaknesses in the + original Adler 32 checksum for small messages. This document, being + used as a guide for a cut and paste replacement to update RFC 2960, + thus also needs to incorporate the checksum changes. The idea is + that one could apply all changes found in this guide to a copy of RFC + 2960 and have a "new" document that has ALL changes (including RFC + 3309). + +2.38.2. Text Changes to the Document + + --------- + Old text: + --------- + + 6.8 Adler-32 Checksum Calculation + + When sending an SCTP packet, the endpoint MUST strengthen the data + integrity of the transmission by including the Adler-32 checksum + value calculated on the packet, as described below. + + After the packet is constructed (containing the SCTP common header + and one or more control or DATA chunks), the transmitter shall: + + + + +Stewart, et al. Informational [Page 79] + +RFC 4460 SCTP Errata April 2006 + + + 1) Fill in the proper Verification Tag in the SCTP common header + and initialize the checksum field to 0's. + + 2) Calculate the Adler-32 checksum of the whole packet, including + the SCTP common header and all the chunks. Refer to + appendix B for details of the Adler-32 algorithm. And, + + 3) Put the resultant value into the checksum field in the common + header, and leave the rest of the bits unchanged. + + When an SCTP packet is received, the receiver MUST first check the + Adler-32 checksum: + + 1) Store the received Adler-32 checksum value aside, + + 2) Replace the 32 bits of the checksum field in the received SCTP + packet with all '0's and calculate an Adler-32 checksum value + of the whole received packet. And, + + 3) Verify that the calculated Adler-32 checksum is the same as the + received Adler-32 checksum. If not, the receiver MUST treat + the packet as an invalid SCTP packet. + + The default procedure for handling invalid SCTP packets is to + silently discard them. + + --------- + New text: + --------- + + 6.8 CRC-32c Checksum Calculation + + When sending an SCTP packet, the endpoint MUST strengthen the data + integrity of the transmission by including the CRC32c checksum + value calculated on the packet, as described below. + + After the packet is constructed (containing the SCTP common header + and one or more control or DATA chunks), the transmitter MUST + + 1) fill in the proper Verification Tag in the SCTP common header + and initialize the checksum field to '0's, + + 2) calculate the CRC32c checksum of the whole packet, including + the SCTP common header and all the chunks (refer to + appendix B for details of the CRC32c algorithm); and + + 3) put the resultant value into the checksum field in the common + header, and leave the rest of the bits unchanged. + + + +Stewart, et al. Informational [Page 80] + +RFC 4460 SCTP Errata April 2006 + + + When an SCTP packet is received, the receiver MUST first check the + CRC32c checksum as follows: + + 1) Store the received CRC32c checksum value aside. + + 2) Replace the 32 bits of the checksum field in the received SCTP + packet with all '0's and calculate a CRC32c checksum value of + the whole received packet. + + 3) Verify that the calculated CRC32c checksum is the same as the + received CRC32c checksum. If it is not, the receiver MUST + treat the packet as an invalid SCTP packet. + + The default procedure for handling invalid SCTP packets is to + silently discard them. + + Any hardware implementation SHOULD be done in a way that is + verifiable by the software. + + + --------- + Old text: + --------- + + Appendix B Alder 32 bit checksum calculation + + The Adler-32 checksum calculation given in this appendix is + copied from [RFC1950]. + + Adler-32 is composed of two sums accumulated per byte: s1 is the + sum of all bytes, s2 is the sum of all s1 values. Both sums are + done modulo 65521. s1 is initialized to 1, s2 to zero. The + Adler-32 checksum is stored as s2*65536 + s1 in network byte + order. + + The following C code computes the Adler-32 checksum of a data + buffer. It is written for clarity, not for speed. The sample + code is in the ANSI C programming language. Non C users may + find it easier to read with these hints: + + & Bitwise AND operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero bit(s) + at the left. + << Bitwise left shift operator. Left shift inserts zero + bit(s) at the right. + ++ "n++" increments the variable n. + % modulo operator: a % b is the remainder of a divided by b. + + + +Stewart, et al. Informational [Page 81] + +RFC 4460 SCTP Errata April 2006 + + + #define BASE 65521 /* largest prime smaller than 65536 */ + /* + Update a running Adler-32 checksum with the bytes buf[0..len-1] + and return the updated checksum. The Adler-32 checksum should + be initialized to 1. + + Usage example: + + unsigned long adler = 1L; + + while (read_buffer(buffer, length) != EOF) { + adler = update_adler32(adler, buffer, length); + } + if (adler != original_adler) error(); + */ + unsigned long update_adler32(unsigned long adler, + unsigned char *buf, int len) + { + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int n; + + for (n = 0; n < len; n++) { + s1 = (s1 + buf[n]) % BASE; + s2 = (s2 + s1) % BASE; + } + return (s2 << 16) + s1; + } + + /* Return the adler32 of the bytes buf[0..len-1] */ + unsigned long adler32(unsigned char *buf, int len) + { + return update_adler32(1L, buf, len); + } + + --------- + New text: + --------- + + Appendix B CRC32c Checksum Calculation + + We define a 'reflected value' as one that is the opposite of the + normal bit order of the machine. The 32-bit CRC is calculated as + described for CRC-32c and uses the polynomial code 0x11EDC6F41 + (Castagnoli93) or x^32+x^28+x^27+x^26+x^25 + +x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+x^8+x^6+x^0. + The CRC is computed using a procedure similar to ETHERNET CRC + [ITU32], modified to reflect transport level usage. + + + +Stewart, et al. Informational [Page 82] + +RFC 4460 SCTP Errata April 2006 + + + CRC computation uses polynomial division. A message + bit-string M is transformed to a polynomial, M(X), and the CRC + is calculated from M(X) using polynomial arithmetic [PETERSON 72]. + + When CRCs are used at the link layer, the polynomial is derived + from on-the-wire bit ordering: the first bit 'on the wire' is the + high-order coefficient. Since SCTP is a transport-level protocol, + it cannot know the actual serial-media bit ordering. Moreover, + different links in the path between SCTP endpoints may use + different link-level bit orders. + + A convention must therefore be established for mapping SCTP + transport messages to polynomials for purposes of CRC computation. + The bit-ordering for mapping SCTP messages to polynomials is that + bytes are taken most-significant first; but within each byte, bits + are taken least-significant first. The first byte of the message + provides the eight highest coefficients. Within each byte, + the least-significant SCTP bit gives the most significant + polynomial coefficient within that byte, and the most-significant + SCTP bit is the least significant polynomial coefficient in that + byte. (This bit ordering is sometimes called 'mirrored' or + 'reflected' [WILLIAMS93].) CRC polynomials are to be transformed + back into SCTP transport-level byte values, using a consistent + mapping. + + The SCTP transport-level CRC value should be calculated as + follows: + + - CRC input data are assigned to a byte stream, numbered from + 0 to N-1. + + - The transport-level byte-stream is mapped to a polynomial + value. An N-byte PDU with j bytes numbered 0 to N-1 is + considered as coefficients of a polynomial M(x) of order + 8N-1, with bit 0 of byte j being coefficient x^(8(N-j)-8), + and bit 7 of byte j being coefficient x^(8(N-j)-1). + + - The CRC remainder register is initialized with all 1s and + the CRC is computed with an algorithm that simultaneously + multiplies by x^32 and divides by the CRC polynomial. + + - The polynomial is multiplied by x^32 and divided by G(x), + the generator polynomial, producing a remainder R(x) of + degree less than or equal to 31. + + - The coefficients of R(x) are considered a 32-bit sequence. + + + + + +Stewart, et al. Informational [Page 83] + +RFC 4460 SCTP Errata April 2006 + + + - The bit sequence is complemented. The result is the CRC + polynomial. + + - The CRC polynomial is mapped back into SCTP transport-level + bytes. The coefficient of x^31 gives the value of bit 7 of + SCTP byte 0, and the coefficient of x^24 gives the value of + bit 0 of byte 0. The coefficient of x^7 gives bit 7 of + byte 3, and the coefficient of x^0 gives bit 0 of byte 3. + The resulting four-byte transport-level sequence is the + 32-bit SCTP checksum value. + + IMPLEMENTATION NOTE: Standards documents, textbooks, and vendor + literature on CRCs often follow an alternative formulation, in + which the register used to hold the remainder of the + long-division algorithm is initialized to zero rather than + all-1s, and instead the first 32 bits of the message are + complemented. The long-division algorithm used in our + formulation is specified such that the initial + multiplication by 2^32 and the long-division are combined into + one simultaneous operation. For such algorithms, and for + messages longer than 64 bits, the two specifications are + precisely equivalent. That equivalence is the intent of + this document. + + Implementors of SCTP are warned that both specifications are to be + found in the literature, sometimes with no restriction on the + long-division algorithm. The choice of formulation in this + document is to permit non-SCTP usage, where the same CRC + algorithm may be used to protect messages shorter than 64 bits. + + There may be a computational advantage in validating the + Association against the Verification Tag, prior to performing a + checksum, as invalid tags will result in the same action as a bad + checksum in most cases. The exceptions for this technique would + be INIT and some SHUTDOWN-COMPLETE exchanges, as well as a stale + COOKIE-ECHO. These special case exchanges must represent small + packets and will minimize the effect of the checksum calculation. + + + --------- + Old text: (Section 18) + --------- + + 18. Bibliography + + [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End + Network Path Properties", Proc. SIGCOMM'99, 1999. + + + + +Stewart, et al. Informational [Page 84] + +RFC 4460 SCTP Errata April 2006 + + + [FALL96] Fall, K. and Floyd, S., Simulation-based Comparisons of + Tahoe, Reno, and SACK TCP, Computer Communications Review, + V. 26 N. 3, July 1996, pp. 5-21. + + [RFC1750] Eastlake, D. (ed.), "Randomness Recommendations for + Security", RFC 1750, December 1994. + + [RFC1950] Deutsch P. and J. Gailly, "ZLIB Compressed Data Format + Specification version 3.3", RFC 1950, May 1996. + + [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed- + Hashing for Message Authentication", RFC 2104, March 1997. + + [RFC2196] Fraser, B., "Site Security Handbook", FYI 8, RFC 2196, + September 1997. + + [RFC2522] Karn, P. and W. Simpson, "Photuris: Session-Key Management + Protocol", RFC 2522, March 1999. + + [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T., + "TCP Congestion Control with a Misbehaving Receiver", ACM + Computer Communication Review, 29(5), October 1999. + + --------- + New text: (Section 18, including changes from 2.11) + --------- + + 18. Bibliography + + [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End + Network Path Properties", Proc. SIGCOMM'99, 1999. + + [FALL96] Fall, K. and Floyd, S., Simulation-based Comparisons of + Tahoe, Reno, and SACK TCP, Computer Communications Review, + V. 26 N. 3, July 1996, pp. 5-21. + + [ITU32] ITU-T Recommendation V.42, "Error-correcting + procedures for DCEs using asynchronous-to-synchronous + conversion", Section 8.1.1.6.2, October 1996. + + [PETERSON 1972] W. W. Peterson and E.J Weldon, Error Correcting + Codes, 2nd Edition, MIT Press, Cambridge, + Massachusetts. + + [RFC1750] Eastlake, D., Ed., "Randomness Recommendations for + Security", RFC 1750, December 1994. + + + + + +Stewart, et al. Informational [Page 85] + +RFC 4460 SCTP Errata April 2006 + + + [RFC1858] Ziemba, G., Reed, D. and Traina P., "Security + Considerations for IP Fragment Filtering", RFC 1858, + October 1995. + + [RFC1950] Deutsch P. and J. Gailly, "ZLIB Compressed Data Format + Specification version 3.3", RFC 1950, May 1996. + + [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed- + Hashing for Message Authentication", RFC 2104, March 1997. + + [RFC2196] Fraser, B., "Site Security Handbook", FYI 8, RFC 2196, + September 1997. + + [RFC2522] Karn, P. and W. Simpson, "Photuris: Session-Key Management + Protocol", RFC 2522, March 1999. + + [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T., + "TCP Congestion Control with a Misbehaving Receiver", ACM + Computer Communication Review, 29(5), October 1999. + + [WILLIAMS93] Williams, R., "A PAINLESS GUIDE TO CRC ERROR + DETECTION ALGORITHMS" - Internet publication, August + 1993, + http://www.geocities.com/SiliconValley/Pines/ + 8659/crc.htm. + +2.38.3. Solution Description + + This change adds to the implementor's guide the complete set of + changes that, when combined with RFC 2960 [5], encompasses the + changes from RFC 3309 [6]. + +2.39. Retransmission Policy + +2.39.1. Description of the Problem + + The current retransmission policy (send all retransmissions an + alternate destination) in the specification has performance issues + under certain loss conditions with multihomed endpoints. Instead, + fast retransmissions should be sent to the same destination, and only + timeout retransmissions should be sent to an alternate destination + [4]. + + + + + + + + + +Stewart, et al. Informational [Page 86] + +RFC 4460 SCTP Errata April 2006 + + +2.39.2. Text Changes to the Document + + --------- + Old text: (Section 6.4) + --------- + + Furthermore, when its peer is multi-homed, an endpoint SHOULD try to + retransmit a chunk to an active destination transport address that is + different from the last destination address to which the DATA chunk + was sent. + + --------- + New text: (Section 6.4) + --------- + + Furthermore, when its peer is multi-homed, an endpoint SHOULD try to + retransmit a chunk that timed out to an active destination transport + address that is different from the last destination address to which + the DATA chunk was sent. + + --------- + Old text: (Section 6.4.1) + --------- + + When retransmitting data, if the endpoint is multi-homed, it should + consider each source-destination address pair in its retransmission + selection policy. When retransmitting the endpoint should attempt to + pick the most divergent source-destination pair from the original + source-destination pair to which the packet was transmitted. + + --------- + New text: (Section 6.4.1) + --------- + + When retransmitting data that timed out, if the endpoint is + multi-homed, it should consider each source-destination address + pair in its retransmission selection policy. When retransmitting + timed out data, the endpoint should attempt to pick the most + divergent source-destination pair from the original + source-destination pair to which the packet was transmitted. + +2.39.3. Solution Description + + The above wording changes clarify that only timeout retransmissions + should be sent to an alternate active destination. + + + + + + +Stewart, et al. Informational [Page 87] + +RFC 4460 SCTP Errata April 2006 + + +2.40. Port Number 0 + +2.40.1. Description of the Problem + + The port number 0 has a special semantic in various APIs. For + example, in the socket API, if the user specifies 0, the SCTP + implementation chooses an appropriate port number for the user. + Therefore, the port number 0 should not be used on the wire. + +2.40.2. Text Changes to the Document + + --------- + Old text: (Section 3.1) + --------- + + Source Port Number: 16 bits (unsigned integer) + + This is the SCTP sender's port number. It can be used by the + receiver in combination with the source IP address, the SCTP + destination port, and possibly the destination IP address to + identify the association to which this packet belongs. + + Destination Port Number: 16 bits (unsigned integer) + + This is the SCTP port number to which this packet is destined. + The receiving host will use this port number to de-multiplex + the SCTP packet to the correct receiving endpoint/application. + + --------- + New text: (Section 3.1) + --------- + + Source Port Number: 16 bits (unsigned integer) + + This is the SCTP sender's port number. It can be used by the + receiver in combination with the source IP address, the SCTP + destination port and possibly the destination IP address to + identify the association to which this packet belongs. + The port number 0 MUST NOT be used. + + Destination Port Number: 16 bits (unsigned integer) + + This is the SCTP port number to which this packet is destined. + The receiving host will use this port number to de-multiplex + the SCTP packet to the correct receiving endpoint/application. + The port number 0 MUST NOT be used. + + + + + +Stewart, et al. Informational [Page 88] + +RFC 4460 SCTP Errata April 2006 + + +2.40.3. Solution Description + + It is clearly stated that the port number 0 is an invalid value on + the wire. + +2.41. T Bit + +2.41.1. Description of the Problem + + The description of the T bit as the bit describing whether a TCB has + been destroyed is misleading. In addition, the procedure described + in Section 2.13 is not as precise as needed. + +2.41.2. Text Changes to the Document + + --------- + Old text: (Section 3.3.7) + --------- + + T bit: 1 bit + The T bit is set to 0 if the sender had a TCB that it + destroyed. If the sender did not have a TCB it should set + this bit to 1. + + --------- + New text: (Section 3.3.7) + --------- + + T bit: 1 bit + The T bit is set to 0 if the sender filled in the + Verification Tag expected by the peer. If the Verification + Tag is reflected, the T bit MUST be set to 1. Reflecting means + that the sent Verification Tag is the same as the received + one. + + + --------- + Old text: (Section 3.3.13) + --------- + + T bit: 1 bit + The T bit is set to 0 if the sender had a TCB that it + destroyed. If the sender did not have a TCB it should set + this bit to 1. + + + + + + + +Stewart, et al. Informational [Page 89] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 3.3.13) + --------- + + T bit: 1 bit + The T bit is set to 0 if the sender filled in the + Verification Tag expected by the peer. If the Verification + Tag is reflected, the T bit MUST be set to 1. Reflecting means + that the sent Verification Tag is the same as the received + one. + + + --------- + Old text: (Section 8.4) + --------- + + 3) If the packet contains an INIT chunk with a Verification Tag + set to '0', process it as described in Section 5.1. + Otherwise, + + --------- + New text: (Section 8.4) + --------- + 3) If the packet contains an INIT chunk with a Verification Tag + set to '0', process it as described in Section 5.1. If, for + whatever reason, the INIT cannot be processed normally and + an ABORT has to be sent in response, the Verification Tag of + the packet containing the ABORT chunk MUST be the Initiate + tag of the received INIT chunk, and the T-Bit of the ABORT + chunk has to be set to 0, indicating that the Verification + Tag is NOT reflected. + + + --------- + Old text: (Section 8.4) + --------- + 5) If the packet contains a SHUTDOWN ACK chunk, the receiver + should respond to the sender of the OOTB packet with a + SHUTDOWN COMPLETE. When sending the SHUTDOWN COMPLETE, the + receiver of the OOTB packet must fill in the Verification + Tag field of the outbound packet with the Verification Tag + received in the SHUTDOWN ACK and set the T-bit in the Chunk + Flags to indicate that no TCB was found. Otherwise, + + + + + + + + +Stewart, et al. Informational [Page 90] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Section 8.4) + --------- + + 5) If the packet contains a SHUTDOWN ACK chunk, the receiver + should respond to the sender of the OOTB packet with a + SHUTDOWN COMPLETE. When sending the SHUTDOWN COMPLETE, the + receiver of the OOTB packet must fill in the Verification + Tag field of the outbound packet with the Verification Tag + received in the SHUTDOWN ACK and set the T-bit in the + Chunk Flags to indicate that the Verification Tag is + reflected. Otherwise, + + + --------- + Old text: (Section 8.4) + --------- + + 8) The receiver should respond to the sender of the OOTB packet + with an ABORT. When sending the ABORT, the receiver of the + OOTB packet MUST fill in the Verification Tag field of the + outbound packet with the value found in the Verification + Tag field of the OOTB packet and set the T-bit in the Chunk + Flags to indicate that no TCB was found. After sending this + ABORT, the receiver of the OOTB packet shall discard the + OOTB packet and take no further action. + + --------- + New text: (Section 8.4) + --------- + + 8) The receiver should respond to the sender of the OOTB packet + with an ABORT. When sending the ABORT, the receiver of the + OOTB packet MUST fill in the Verification Tag field of the + outbound packet with the value found in the Verification Tag + field of the OOTB packet and set the T-bit in the Chunk Flags + to indicate that the Verification Tag is reflected. After + sending this ABORT, the receiver of the OOTB packet shall + discard the OOTB packet and take no further action. + + + --------- + Old text: (Section 8.5.1) + --------- + + B) Rules for packet carrying ABORT: + + + + + +Stewart, et al. Informational [Page 91] + +RFC 4460 SCTP Errata April 2006 + + + - The endpoint shall always fill in the Verification Tag + field of the outbound packet with the destination + endpoint's tag value if it is known. + + - If the ABORT is sent in response to an OOTB packet, the + endpoint MUST follow the procedure described in + Section 8.4. + + - The receiver MUST accept the packet if the Verification + Tag matches either its own tag, OR the tag of its peer. + Otherwise, the receiver MUST silently discard the packet + and take no further action. + + --------- + New text: (Section 8.5.1) + --------- + + B) Rules for packet carrying ABORT: + + - The endpoint MUST always fill in the Verification Tag + field of the outbound packet with the destination + endpoint's tag value, if it is known. + + - If the ABORT is sent in response to an OOTB packet, the + endpoint MUST follow the procedure described in + Section 8.4. + + - The receiver of an ABORT MUST accept the packet + if the Verification Tag field of the packet matches its + own tag and the T bit is not set + OR + if it is set to its peer's tag and the T bit is set in + the Chunk Flags. + Otherwise, the receiver MUST silently discard the packet + and take no further action. + + + --------- + Old text: (Section 8.5.1) + --------- + + C) Rules for packet carrying SHUTDOWN COMPLETE: + + - When sending a SHUTDOWN COMPLETE, if the receiver of the + SHUTDOWN ACK has a TCB then the destination endpoint's + tag MUST be used. Only where no TCB exists should the + sender use the Verification Tag from the SHUTDOWN ACK. + + + + +Stewart, et al. Informational [Page 92] + +RFC 4460 SCTP Errata April 2006 + + + - The receiver of a SHUTDOWN COMPLETE shall accept the + packet if the Verification Tag field of the packet matches + its own tag OR it is set to its peer's tag and the T bit + is set in the Chunk Flags. Otherwise, the receiver MUST + silently discard the packet and take no further action. + An endpoint MUST ignore the SHUTDOWN COMPLETE if it is + not in the SHUTDOWN-ACK-SENT state. + + --------- + New text: (Section 8.5.1) + --------- + + C) Rules for packet carrying SHUTDOWN COMPLETE: + + - When sending a SHUTDOWN COMPLETE, if the receiver of the + SHUTDOWN ACK has a TCB, then the destination endpoint's tag + MUST be used, and the T-bit MUST NOT be set. Only where no + TCB exists should the sender use the Verification Tag from + the SHUTDOWN ACK, and MUST set the T-bit. + + - The receiver of a SHUTDOWN COMPLETE shall accept the packet + if the Verification Tag field of the packet matches its own + tag and the T bit is not set + OR + if it is set to its peer's tag and the T bit is set in the + Chunk Flags. + Otherwise, the receiver MUST silently discard the packet + and take no further action. An endpoint MUST ignore the + SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT + state. + +2.41.3. Solution Description + + The description of the T bit now clearly describes the semantic of + the bit. The procedures for receiving the T bit have been clarified. + +2.42. Unknown Parameter Handling + +2.42.1. Description of the Problem + + The description given in Section 2.33 does not state clearly whether + an INIT-ACK or COOKIE-ECHO is sent. + +2.42.2. Text Changes to the Document + + The changes given here already include changes suggested in Section + 2.2, 2.27, and 2.33 of this document. + + + + +Stewart, et al. Informational [Page 93] + +RFC 4460 SCTP Errata April 2006 + + + --------- + Old text: (Section 3.2.1) + --------- + + 00 - Stop processing this SCTP packet and discard it do not process + any further chunks within it. + + 01 - Stop processing this SCTP packet and discard it, do not process + any further chunks within it, and report the unrecognized + parameter in an 'Unrecognized Parameter Type' (in either an + ERROR or in the INIT ACK). + + 10 - Skip this parameter and continue processing. + + 11 - Skip this parameter and continue processing but report the + unrecognized parameter in an 'Unrecognized Parameter Type' (in + either an ERROR or in the INIT ACK). + + --------- + New text: (Section 3.2.1) + --------- + + 00 - Stop processing this parameter; do not process + any further parameters within this chunk. + + 01 - Stop processing this parameter, do not process + any further parameters within this chunk, and report the + unrecognized parameter in an 'Unrecognized Parameter', as + described in 3.2.2. + + 10 - Skip this parameter and continue processing. + + 11 - Skip this parameter and continue processing but report the + unrecognized parameter in an 'Unrecognized Parameter', as + described in 3.2.2. + + Please note that in all four cases an INIT-ACK or COOKIE-ECHO + chunk is sent. In the 00 or 01 case the processing of the + parameters after the unknown parameter is canceled, but no + processing already done is rolled back. + + + + + + + + + + + +Stewart, et al. Informational [Page 94] + +RFC 4460 SCTP Errata April 2006 + + + --------- + New text: (Note: no old text; clarification added in Section 3.2) + --------- + + 3.2.2. Reporting of Unrecognized Parameters + + If the receiver of an INIT chunk detects unrecognized parameters + and has to report them according to Section 3.2.1, it MUST put + the 'Unrecognized Parameter' parameter(s) in the INIT-ACK chunk + sent in response to the INIT-chunk. Note that if the receiver + of the INIT chunk is NOT going to establish an association (e.g., + due to lack of resources), an 'Unrecognized Parameter' would NOT + be included with any ABORT being sent to the sender of the INIT. + + If the receiver of an INIT-ACK chunk detects unrecognized + parameters and has to report them according to Section 3.2.1, it + SHOULD bundle the ERROR chunk containing the 'Unrecognized + Parameters' error cause with the COOKIE-ECHO chunk sent in + response to the INIT-ACK chunk. If the receiver of the INIT-ACK + cannot bundle the COOKIE-ECHO chunk with the ERROR chunk, the + ERROR chunk MAY be sent separately but not before the COOKIE-ACK + has been received. + + Note: Any time a COOKIE-ECHO is sent in a packet, it MUST be the + first chunk. + +2.42.3. Solution Description + + The new text clearly states that an INIT-ACK or COOKIE-ECHO has to be + sent. + +2.43. Cookie Echo Chunk + +2.43.1. Description of the Problem + + The description given in Section 3.3.11 of RFC 2960 [5] is unclear as + to how the COOKIE-ECHO is composed. + +2.43.2. Text Changes to the Document + + --------- + Old text: (Section 3.3.11) + --------- + Cookie: variable size + + This field must contain the exact cookie received in the State + Cookie parameter from the previous INIT ACK. + + + + +Stewart, et al. Informational [Page 95] + +RFC 4460 SCTP Errata April 2006 + + + An implementation SHOULD make the cookie as small as possible + to insure interoperability. + + --------- + New text: (Section 3.3.11) + --------- + Cookie: variable size + + This field must contain the exact cookie received in the State + Cookie parameter from the previous INIT ACK. + + An implementation SHOULD make the cookie as small as possible + to ensure interoperability. + + Note: A Cookie Echo does NOT contain a State Cookie + Parameter; instead, the data within the State Cookie's + Parameter Value becomes the data within the Cookie Echo's + Chunk Value. This allows an implementation to change only + the first two bytes of the State Cookie parameter to become + a Cookie Echo Chunk. + +2.43.3. Solution Description + + The new text adds a note that helps clarify that a Cookie Echo chunk + is nothing more than the State Cookie parameter with only two bytes + modified. + +2.44. Partial Chunks + +2.44.1. Description of the Problem + + Section 6.10 of RFC 2960 [5] uses the notion of 'partial chunks' + without defining it. + +2.44.2. Text Changes to the Document + + --------- + Old text: (Section 6.10) + --------- + Partial chunks MUST NOT be placed in an SCTP packet. + + --------- + New text: (Section 6.10) + --------- + Partial chunks MUST NOT be placed in an SCTP packet. A partial + chunk is a chunk that is not completely contained in the SCTP + packet; i.e., the SCTP packet is too short to contain all the bytes + of the chunk as indicated by the chunk length. + + + +Stewart, et al. Informational [Page 96] + +RFC 4460 SCTP Errata April 2006 + + +2.44.3. Solution Description + + The new text adds a definition of 'partial chunks'. + +2.45. Non-unicast Addresses + +2.45.1. Description of the Problem + + Section 8.4 of RFC 2960 [5] forces the OOTB handling to discard all + non-unicast addresses. This leaves future use of anycast addresses + in question. With the addition of the add-ip feature, SCTP should be + able to easily handle anycast INIT s that can be followed, after + association setup, with a delete of the anycast address from the + association. + +2.45.2. Text Changes to the Document + + --------- + Old text: (Section 8.4) + --------- + 8.4 Handle "Out of the blue" Packets + + An SCTP packet is called an "out of the blue" (OOTB) packet if + it is correctly formed, i.e., passed the receiver's Adler-32 + check (see Section 6.8), but the receiver is not able to + identify the association to which this packet belongs. + + The receiver of an OOTB packet MUST do the following: + + 1) If the OOTB packet is to or from a non-unicast address, + silently discard the packet. Otherwise, + + + --------- + New text: (Section 8.4) + --------- + + 8.4. Handle "Out of the Blue" Packets + + An SCTP packet is called an "out of the blue" (OOTB) packet if + it is correctly formed (i.e., passed the receiver's CRC32c + check; see Section 6.8), but the receiver is not able to identify + the association to which this packet belongs. + + The receiver of an OOTB packet MUST do the following: + + 1) If the OOTB packet is to or from a non-unicast address, a + receiver SHOULD silently discard the packet. Otherwise, + + + +Stewart, et al. Informational [Page 97] + +RFC 4460 SCTP Errata April 2006 + + +2.45.3. Solution Description + + The loosening of the wording to a SHOULD will now allow future use of + anycast addresses. Note that no changes are made to Section + 11.2.4.1, since responding to broadcast addresses could lead to + flooding attacks and implementors should pay careful attention to + these words. + +2.46. Processing of ABORT Chunks + +2.46.1. Description of the Problem + + Section 3.3.7 of RFC 2960 [5] requires an SCTP endpoint to silently + discard ABORT chunks received for associations that do not exist. It + is not clear what this means in the COOKIE-WAIT state, for example. + Therefore, it was not clear whether an ABORT sent in response to an + INIT should be processed or silently discarded. + +2.46.2. Text Changes to the Document + + --------- + Old text: (Section 3.3.7) + --------- + + If an endpoint receives an ABORT with a format error or for an + association that doesn't exist, it MUST silently discard it. + + --------- + New text: (Section 3.3.7) + --------- + + If an endpoint receives an ABORT with a format error or no + TCB is found, it MUST silently discard it. + +2.46.3. Solution Description + + It is now clearly stated that an ABORT chunk should be processed + whenever a TCB is found. + + + + + + + + + + + + + +Stewart, et al. Informational [Page 98] + +RFC 4460 SCTP Errata April 2006 + + +2.47. Sending of ABORT Chunks + +2.47.1. Description of the Problem + + Section 5.1 of RFC 2960 [5] requires that an ABORT chunk be sent in + response to an INIT chunk when there is no listening end point. To + make port scanning harder, someone might not want these ABORTs to be + received by the sender of the INIT chunks. Currently, the only way + to enforce this is by using a firewall that discards the packets + containing the INIT chunks or the packets containing the ABORT + chunks. It is desirable that the same can be done without a middle + box. + +2.47.2. Text Changes to the Document + + --------- + Old text: (Section 5.1) + --------- + + If an endpoint receives an INIT, INIT ACK, or COOKIE ECHO chunk + but decides not to establish the new association due to missing + mandatory parameters in the received INIT or INIT ACK, invalid + parameter values, or lack of local resources, it MUST respond with + an ABORT chunk. + + --------- + New text: (Section 5.1) + --------- + + If an endpoint receives an INIT, INIT ACK, or COOKIE ECHO chunk + but decides not to establish the new association due to missing + mandatory parameters in the received INIT or INIT ACK, invalid + parameter values, or lack of local resources, it SHOULD respond + with an ABORT chunk. + +2.47.3. Solution Description + + The requirement of sending ABORT chunks is relaxed such that an + implementation can decide not to send ABORT chunks. + +2.48. Handling of Supported Address Types Parameter + +2.48.1. Description of the Problem + + The sender of the INIT chunk can include a 'Supported Address Types' + parameter to indicate which address families are supported. It is + unclear how an INIT chunk should be processed where the source + address of the packet containing the INIT chunk or listed addresses + + + +Stewart, et al. Informational [Page 99] + +RFC 4460 SCTP Errata April 2006 + + + within the INIT chunk indicate that more address types are supported + than those listed in the 'Supported Address Types' parameter. + +2.48.2. Text Changes to the Document + + The changes given here already include changes suggested in Section + 2.28 of this document. + + --------- + Old text: (Section 5.1.2) + --------- + + IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK + fails to resolve the address parameter due to an unsupported type, + it can abort the initiation process and then attempt a + re-initiation by using a 'Supported Address Types' parameter in + the new INIT to indicate what types of address it prefers. + + --------- + New text: (Section 5.1.2) + --------- + + IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK + fails to resolve the address parameter due to an unsupported type, + it can abort the initiation process and then attempt a re- + initiation by using a 'Supported Address Types' parameter in the + new INIT to indicate what types of address it prefers. + + IMPLEMENTATION NOTE: If an SCTP endpoint that only supports either + IPv4 or IPv6 receives IPv4 and IPv6 addresses in an INIT or INIT- + ACK chunk from its peer, it MUST use all the addresses belonging + to the supported address family. The other addresses MAY be + ignored. The endpoint SHOULD NOT respond with any kind of error + indication. + + IMPLEMENTATION NOTE: If an SCTP endpoint lists in the 'Supported + Address Types' parameter either IPv4 or IPv6, but uses the other + family for sending the packet containing the INIT chunk, or if it + also lists addresses of the other family in the INIT chunk, then + the address family that is not listed in the 'Supported Address + Types' parameter SHOULD also be considered as supported by the + receiver of the INIT chunk. The receiver of the INIT chunk SHOULD + NOT respond with any kind of error indication. + +2.48.3. Solution Description + + It is now clearly described how these Supported Address Types + parameters with incorrect data should be handled. + + + +Stewart, et al. Informational [Page 100] + +RFC 4460 SCTP Errata April 2006 + + +2.49. Handling of Unexpected Parameters + +2.49.1. Description of the Problem + + RFC 2960 [5] clearly describes how unknown parameters in the INIT and + INIT-ACK chunk should be processed. But it is not described how + unexpected parameters should be processed. A parameter is unexpected + if it is known and is an optional parameter in either the INIT or + INIT-ACK chunk but is received in the chunk for which it is not an + optional parameter. For example, the 'Supported Address Types' + parameter would be an unexpected parameter if contained in an INIT- + ACK chunk. + +2.49.2. Text Changes to the Document + + --------- + Old text: (Section 3.3.2) + --------- + + Note 4: This parameter, when present, specifies all the address + types the sending endpoint can support. The absence of this + parameter indicates that the sending endpoint can support any + address type. + + --------- + New text: (Section 3.3.2) + --------- + + Note 4: This parameter, when present, specifies all the address + types the sending endpoint can support. The absence of this + parameter indicates that the sending endpoint can support any + address type. + + IMPLEMENTATION NOTE: If an INIT chunk is received with known + parameters that are not optional parameters of the INIT chunk + then the receiver SHOULD process the INIT chunk and send back + an INIT-ACK. The receiver of the INIT chunk MAY bundle an ERROR + chunk with the COOKIE-ACK chunk later. However, restrictive + implementations MAY send back an ABORT chunk in response to + the INIT chunk. + + + + + + + + + + + +Stewart, et al. Informational [Page 101] + +RFC 4460 SCTP Errata April 2006 + + + --------- + Old text: (Section 3.3.3) + --------- + + IMPLEMENTATION NOTE: An implementation MUST be prepared to receive + a INIT ACK that is quite large (more than 1500 bytes) due to the + variable size of the state cookie AND the variable address list. + For example if a responder to the INIT has 1000 IPv4 addresses + it wishes to send, it would need at least 8,000 bytes to encode + this in the INIT ACK. + + --------- + New text: (Section 3.3.3) + --------- + + IMPLEMENTATION NOTE: An implementation MUST be prepared to receive + a INIT ACK that is quite large (more than 1500 bytes) due to the + variable size of the state cookie AND the variable address list. + For example, if a responder to the INIT has 1000 IPv4 addresses + it wishes to send, it would need at least 8,000 bytes to encode + this in the INIT ACK. + + IMPLEMENTATION NOTE: If an INIT-ACK chunk is received with known + parameters that are not optional parameters of the INIT-ACK + chunk, then the receiver SHOULD process the INIT-ACK chunk and + send back a COOKIE-ECHO. The receiver of the INIT-ACK chunk + MAY bundle an ERROR chunk with the COOKIE-ECHO chunk. However, + restrictive implementations MAY send back an ABORT chunk in + response to the INIT-ACK chunk. + +2.49.3. Solution Description + + It is now stated how unexpected parameters should be processed. + +2.50. Payload Protocol Identifier + +2.50.1. Description of the Problem + + The current description of the payload protocol identifier does NOT + highlight the fact that the field is NOT necessarily in network byte + order. + + + + + + + + + + +Stewart, et al. Informational [Page 102] + +RFC 4460 SCTP Errata April 2006 + + +2.50.2. Text Changes to the Document + + --------- + Old text: (Section 3.3.1) + --------- + Payload Protocol Identifier: 32 bits (unsigned integer) + + This value represents an application (or upper layer) specified + protocol identifier. This value is passed to SCTP by its upper + layer and sent to its peer. This identifier is not used by + SCTP but can be used by certain network entities as well as + the peer application to identify the type of information being + carried in this DATA chunk. This field must be sent even in + fragmented DATA chunks (to make sure it is available for agents + in the middle of the network). + + The value 0 indicates no application identifier is specified by + the upper layer for this payload data. + + --------- + New text: (Section 3.3.1) + --------- + Payload Protocol Identifier: 32 bits (unsigned integer) + + This value represents an application (or upper layer) specified + protocol identifier. This value is passed to SCTP by its upper + layer and sent to its peer. This identifier is not used by + SCTP but can be used by certain network entities, as well as by + the peer application, to identify the type of information being + carried in this DATA chunk. This field must be sent even in + fragmented DATA chunks (to make sure it is available for agents + in the middle of the network). Note that this field is NOT + touched by an SCTP implementation, therefore its byte order is + NOT necessarily Big Endian. The upper layer is responsible + for any byte order conversions to this field. + + The value 0 indicates that no application identifier is + specified by the upper layer for this payload data. + +2.50.3. Solution Description + + It is now explicitly stated that the upper layer is responsible for + the byte order of this field. + + + + + + + + +Stewart, et al. Informational [Page 103] + +RFC 4460 SCTP Errata April 2006 + + +2.51. Karn's Algorithm + +2.51.1. Description of the Problem + + The current wording of the use of Karn's algorithm is not descriptive + enough to ensure that an implementation in a multi-homed association + does not incorrectly mismeasure the RTT. + +2.51.2. Text Changes to the Document + + --------- + Old text: (Section 6.3.1) + --------- + + C5) Karn's algorithm: RTT measurements MUST NOT be made using + packets that were retransmitted (and thus for which it is + ambiguous whether the reply was for the first instance of the + packet or a later instance) + --------- + New text: (Section 6.3.1) + --------- + + C5) Karn's algorithm: RTT measurements MUST NOT be made using + chunks that were retransmitted (and thus for which it is + ambiguous whether the reply was for the first instance of + the chunk or for a later instance) + + IMPLEMENTATION NOTE: RTT measurements should only be + made using a chunk with TSN r if no chunk + with TSN less than or equal to r is retransmitted + since r is first sent. + +2.51.3. Solution Description + + The above clarification adds an implementation note that will provide + additional guidance in the application of Karn's algorithm. + +2.52. Fast Retransmit Algorithm + +2.52.1. Description of the Problem + + The original SCTP specification is overly conservative in requiring 4 + missing reports before fast retransmitting a segment. TCP uses 3 + missing reports or 4 acknowledgements indicating that the same + segment was received. + + + + + + +Stewart, et al. Informational [Page 104] + +RFC 4460 SCTP Errata April 2006 + + +2.52.2. Text Changes to the Document + + --------- + Old text: + --------- + + 7.2.4 Fast Retransmit on Gap Reports + + In the absence of data loss, an endpoint performs delayed + acknowledgement. However, whenever an endpoint notices a hole in + the arriving TSN sequence, it SHOULD start sending a SACK back + every time a packet arrives carrying data until the + hole is filled. + + Whenever an endpoint receives a SACK that indicates some TSN(s) + missing, it SHOULD wait for 3 further miss indications (via + subsequent SACK's) on the same TSN(s) before taking action with + regard to Fast Retransmit. + + + --------- + New text: + --------- + + 7.2.4. Fast Retransmit on Gap Reports + + In the absence of data loss, an endpoint performs delayed + acknowledgement. However, whenever an endpoint notices a hole in + the arriving TSN sequence, it SHOULD start sending a SACK back + every time a packet arrives carrying data until the + hole is filled. + + Whenever an endpoint receives a SACK that indicates that some + TSNs are missing, it SHOULD wait for 2 further miss indications + (via subsequent SACKs for a total of 3 missing reports) on the + same TSNs before taking action with regard to Fast Retransmit. + +2.52.3. Solution Description + + The above changes will make SCTP and TCP behave similarly in terms of + how fast they engage the Fast Retransmission algorithm upon receiving + missing reports. + +3. Security Considerations + + This document should add no additional security risks to SCTP and in + fact SHOULD correct some original security flaws within the original + document once it is incorporated into a RFC 2960 [5] BIS document. + + + +Stewart, et al. Informational [Page 105] + +RFC 4460 SCTP Errata April 2006 + + +4. Acknowledgements + + The authors would like to thank the following people who have + provided comments and input for this document: + + Barry Zuckerman, La Monte Yarroll, Qiaobing Xie, Wang Xiaopeng, + Jonathan Wood, Jeff Waskow, Mike Turner, John Townsend, Sabina + Torrente, Cliff Thomas, Yuji Suzuki, Manoj Solanki, Sverre Slotte, + Keyur Shah, Jan Rovins, Ben Robinson, Renee Revis, Ian Periam, RC + Monee, Sanjay Rao, Sujith Radhakrishnan, Heinz Prantner, Biren Patel, + Nathalie Mouellic, Mitch Miers, Bernward Meyknecht, Stan McClellan, + Oliver Mayor, Tomas Orti Martin, Sandeep Mahajan, David Lehmann, + Jonathan Lee, Philippe Langlois, Karl Knutson, Joe Keller, Gareth + Keily, Andreas Jungmaier, Janardhan Iyengar, Mutsuya Irie, John + Hebert, Kausar Hassan, Fred Hasle, Dan Harrison, Jon Grim, Laurent + Glaude, Steven Furniss, Atsushi Fukumoto, Ken Fujita, Steve Dimig, + Thomas Curran, Serkan Cil, Melissa Campbell, Peter Butler, Rob + Brennan, Harsh Bhondwe, Brian Bidulock, Caitlin Bestler, Jon Berger, + Robby Benedyk, Stephen Baucke, Sandeep Balani, and Ronnie Sellar. + + A special thanks to Mark Allman, who should actually be a co-author + for his work on the max-burst, but managed to wiggle out due to a + technicality. Also, we would like to acknowledge Lyndon Ong and Phil + Conrad for their valuable input and many contributions. + +5. IANA Considerations + + This document recommends changes for the RFC 2960 [5] BIS document. + As such, even though it lists new error cause code, this document in + itself does NOT define those new codes. Instead, the BIS document + will make the needed changes to RFC 2960 [5] and thus its IANA + section will require changes to be made. + +6. Normative References + + [1] Braden, R., "Requirements for Internet Hosts - Communication + Layers", STD 3, RFC 1122, October 1989. + + [2] Bradner, S., "Key words for use in RFCs to Indicate Requirement + Levels", BCP 14, RFC 2119, March 1997. + + [3] Caro, A., Shah, K., Iyengar, J., Amer, P., and R. Stewart, "SCTP + and TCP Variants: Congestion Control Under Multiple Losses", + Technical Report TR2003-04, Computer and Information Sciences + Department, University of Delaware, February 2003, + . + + + + + +Stewart, et al. Informational [Page 106] + +RFC 4460 SCTP Errata April 2006 + + + [4] Caro, A., Amer, P., and R. Stewart, "Retransmission Schemes for + End-to-end Failover with Transport Layer Multihoming", GLOBECOM, + November 2004., . + + [5] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer, + H., Taylor, T., Rytina, I., Kalla, M., Zhang, L., and V. + Paxson, "Stream Control Transmission Protocol", RFC 2960, + October 2000. + + [6] Stone, J., Stewart, R., and D. Otis, "Stream Control + Transmission Protocol (SCTP) Checksum Change", RFC 3309, + September 2002. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Stewart, et al. Informational [Page 107] + +RFC 4460 SCTP Errata April 2006 + + +Authors' Addresses + + Randall R. Stewart + Cisco Systems, Inc. + 4875 Forest Drive + Suite 200 + Columbia, SC 29206 + USA + + EMail: rrs@cisco.com + + + Ivan Arias-Rodriguez + Nokia Research Center + PO Box 407 + FIN-00045 Nokia Group + Finland + + EMail: ivan.arias-rodriguez@nokia.com + + + Kacheong Poon + Sun Microsystems, Inc. + 3571 N. First St. + San Jose, CA 95134 + USA + + EMail: kacheong.poon@sun.com + + + Armando L. Caro Jr. + BBN Technologies + 10 Moulton St. + Cambridge, MA 02138 + + EMail: acaro@bbn.com + URI: http://www.armandocaro.net + + + Michael Tuexen + Muenster Univ. of Applied Sciences + Stegerwaldstr. 39 + 48565 Steinfurt + Germany + + EMail: tuexen@fh-muenster.de + + + + + +Stewart, et al. Informational [Page 108] + +RFC 4460 SCTP Errata April 2006 + + +Full Copyright Statement + + Copyright (C) The Internet Society (2006). + + This document is subject to the rights, licenses and restrictions + contained in BCP 78, and except as set forth therein, the authors + retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM 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. + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at + ietf-ipr@ietf.org. + +Acknowledgement + + Funding for the RFC Editor function is provided by the IETF + Administrative Support Activity (IASA). + + + + + + + +Stewart, et al. Informational [Page 109] + diff --git a/lksctp-tools.spec.in b/lksctp-tools.spec.in new file mode 100644 index 0000000..1eda6a3 --- /dev/null +++ b/lksctp-tools.spec.in @@ -0,0 +1,176 @@ +# -*- rpm-spec -*- +# +# lksctp-tools.spec.in --- RPM'ed lksctp-tools +# Author : Francois-Xavier Kowalski +# Created On : Sat Jan 10 14:53:53 2004 +# Last Modified By: Vlad Yasevich +# Last Modified On: Fri Mar 27 12:38:42 EDT 2009 +# +# (c) Copyright Hewlett-Packard Company 2004 +# (C) Copyright IBM Corp. 2004 +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public +# License v2 as published by the Free Software Foundation; only +# version 2 of the License is valid for this software, unless +# explicitly otherwise stated. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License v2 along with this program; if not, write to the +# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, +# MA 02139, USA. + +%define kernel_version 2.6.28 +%define kernel_extraflags +%define lksctp_version @VERSION@ + +# older lksctp-tools file name did not conform to RPM file naming +# conventions + +#%define pack_version %{kernel_version}_%{kernel_extraflags}_%{lksctp_version} +#%define file_version %{kernel_version}-%{kernel_extraflags}-%{lksctp_version} + +%define pack_version %{lksctp_version} +%define file_version %{lksctp_version} + +Summary: User-space access to Linux Kernel SCTP +Name: @PACKAGE@ +Version: %{pack_version} +Release: 1 +License: LGPL +Group: System Environment/Libraries +URL: http://lksctp.sourceforge.net +Source0: %{name}-%{file_version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot +BuildRequires: gcc +#BuildRequires: tetex, tetex-latex, tetex-xdvi, tetex-dvips +#BuildRequires: ghostscript, enscript +BuildRequires: libtool, automake, autoconf + +%description +This is the lksctp-tools package for Linux Kernel SCTP Reference +Implementation. + +This package is intended to supplement the Linux Kernel SCTP Reference +Implementation now available in the Linux kernel source tree in +versions 2.5.36 and following. For more information on LKSCTP see the +package documentation README file, section titled "LKSCTP - Linux +Kernel SCTP." + +This package contains the base run-time library & command-line tools. + +%package devel +Summary: Development kit for lksctp-tools +Group: Development/Libraries +Requires: %{name} = %{version} +Requires: glibc-devel + +%description devel +Development kit for lksctp-tools + +- Man pages +- Header files +- Static libraries +- Symlinks to dynamic libraries +- Tutorial source code + +%package doc +Summary: Documents pertaining to SCTP +Group: System Environment/Libraries +Requires: %{name} = %{version} + +%description doc +Documents pertaining to LKSCTP & SCTP in general +- IETF RFC's & Internet Drafts + +%prep +%setup -q -n %{name}-%{file_version} + +%build +%configure --enable-shared --enable-static +make + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR="$RPM_BUILD_ROOT" + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +/sbin/ldconfig + +%postun +/sbin/ldconfig + +%files +%defattr(-,root,root,-) +%doc AUTHORS COPYING ChangeLog COPYING.lib +%{_bindir}/* +%{_libdir}/libsctp.so.* +%{_libdir}/@PACKAGE@/* + +%files devel +%defattr(-,root,root,-) +%{_includedir} +%{_libdir}/libsctp.so +%{_libdir}/libsctp.a +%{_libdir}/libsctp.la +%{_datadir}/@PACKAGE@/* +%{_mandir}/* + +%files doc +%defattr(-,root,root,-) +%doc doc/*.txt + +%changelog +* Fri Mar 27 2009 Vlad Yasevich 1.0.10-1 +- 1.0.10 Release + +* Sun Jun 13 2008 Vlad Yasevich 1.0.9-1 +- 1.0.9 Release + +* Fri Feb 01 2008 Vlad Yasevich 1.0.8-1 +- 1.0.8 Release + +* Fri Jun 29 2007 Vlad Yasevich 1.0.7-1 +- 1.0.7 Release + +* Fri Feb 3 2006 Sridhar Samudrala 1.0.6-1 +- 1.0.6 Release + +* Tue Jan 3 2006 Sridhar Samudrala 1.0.5-1 +- 1.0.5 Release + +* Fri Oct 28 2005 Sridhar Samudrala 1.0.4-1 +- 1.0.4 Release + +* Thu Sep 1 2005 Sridhar Samudrala 1.0.3-1 +- 1.0.3 Release + +* Thu Dec 30 2004 Sridhar Samudrala 1.0.2-1 +- 1.0.2 Release + +* Tue May 11 2004 Sridhar Samudrala 1.0.1-1 +- 1.0.1 Release + +* Thu Feb 26 2004 Sridhar Samudrala 1.0.0-1 +- 1.0.0 Release + +* Fri Feb 6 2004 Francois-Xavier Kowalski 0.9.0-1 +- package only .txt doc files + +* Wed Feb 4 2004 Francois-Xavier Kowalski 0.7.5-1 +- badly placed & undelivered files +- simplified delivery list + +* Tue Jan 27 2004 Francois-Xavier Kowalski 0.7.5-1 +- Integrate comment from project team + +* Sat Jan 10 2004 Francois-Xavier Kowalski 2.6.0_test7_0.7.4-1 +- Creation diff --git a/man/Makefile.am b/man/Makefile.am new file mode 100644 index 0000000..77dddba --- /dev/null +++ b/man/Makefile.am @@ -0,0 +1,12 @@ +# -*- Makefile -*- +# +include $(top_srcdir)/Makefile.vars +include $(top_srcdir)/Makefile.rules + +man7_MANS = sctp.7 + +man3_MANS = sctp_bindx.3 sctp_getladdrs.3 sctp_getpaddrs.3 sctp_opt_info.3 \ + sctp_peeloff.3 sctp_recvmsg.3 sctp_sendmsg.3 sctp_connectx.3 \ + sctp_send.3 + +EXTRA_DIST += $(man3_MANS) $(man7_MANS) diff --git a/man/Makefile.in b/man/Makefile.in new file mode 100644 index 0000000..0f2504f --- /dev/null +++ b/man/Makefile.in @@ -0,0 +1,461 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*-makefile-*- +# +# type: deep, strictness: gnu +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.rules $(top_srcdir)/Makefile.vars +subdir = man +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +man3dir = $(mandir)/man3 +am__installdirs = "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man7dir)" +man7dir = $(mandir)/man7 +NROFF = nroff +MANS = $(man3_MANS) $(man7_MANS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +MAINTAINERCLEANFILES = Makefile.in +DISTCLEANFILES = \\\#*\\\# Makefile +CLEANFILES = +MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io +EXTRA_DIST = $(man3_MANS) $(man7_MANS) +LATEX = @LATEX@ +DVIPS = @DVIPS@ +DVIPDFM = @DVIPDFM@ +ENSCRIPTBIN = @ENSCRIPTBIN@ +PS2PDF = @PS2PDF@ +edit = @sed \ + -e "s|\@bindir\@|$(bindir)|" \ + -e "s|\@libdir\@|$(libdir)|" \ + -e "s|\@PACKAGE\@|$(PACKAGE)|" + + +# -*- Makefile -*- +# +man7_MANS = sctp.7 +man3_MANS = sctp_bindx.3 sctp_getladdrs.3 sctp_getpaddrs.3 sctp_opt_info.3 \ + sctp_peeloff.3 sctp_recvmsg.3 sctp_sendmsg.3 sctp_connectx.3 \ + sctp_send.3 + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.vars $(top_srcdir)/Makefile.rules $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign man/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +install-man3: $(man3_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man3dir)" || $(mkdir_p) "$(DESTDIR)$(man3dir)" + @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.3*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 3*) ;; \ + *) ext='3' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst"; \ + done +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.3*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 3*) ;; \ + *) ext='3' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f '$(DESTDIR)$(man3dir)/$$inst'"; \ + rm -f "$(DESTDIR)$(man3dir)/$$inst"; \ + done +install-man7: $(man7_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man7dir)" || $(mkdir_p) "$(DESTDIR)$(man7dir)" + @list='$(man7_MANS) $(dist_man7_MANS) $(nodist_man7_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.7*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 7*) ;; \ + *) ext='7' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man7dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man7dir)/$$inst"; \ + done +uninstall-man7: + @$(NORMAL_UNINSTALL) + @list='$(man7_MANS) $(dist_man7_MANS) $(nodist_man7_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.7*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 7*) ;; \ + *) ext='7' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f '$(DESTDIR)$(man7dir)/$$inst'"; \ + rm -f "$(DESTDIR)$(man7dir)/$$inst"; \ + done +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(MANS) +installdirs: + for dir in "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man7dir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-man + +install-exec-am: + +install-info: install-info-am + +install-man: install-man3 install-man7 + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-man + +uninstall-man: uninstall-man3 uninstall-man7 + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-man3 \ + install-man7 install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am uninstall uninstall-am uninstall-info-am \ + uninstall-man uninstall-man3 uninstall-man7 + + +# -*-makefile-*- +# +# Generate pre-parsed C code. +%.i: %.c + $(COMPILE) -E -c $^ -o $@ + +.PRECIOUS: %.i +%.ci: %.i + -grep -v -e "^#" -e "^ *$$" $^ | indent > $@ + mv -f $@ $^ +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/man/sctp.7 b/man/sctp.7 new file mode 100644 index 0000000..268d31a --- /dev/null +++ b/man/sctp.7 @@ -0,0 +1,416 @@ +.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005. +.\" +.\" Permission is granted to distribute possibly modified copies +.\" of this manual provided the header is included verbatim, +.\" and in case of nontrivial modification author and date +.\" of the modification is added to the header. +.\" +.TH SCTP 7 2005-10-25 "Linux Man Page" "Linux Programmer's Manual" +.SH NAME +sctp \- SCTP protocol. +.SH SYNOPSIS +.nf +.B #include +.B #include +.B #include +.sp +.B sctp_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); +.B sctp_socket = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); +.fi +.SH DESCRIPTION +This is an implementation of the SCTP protocol as defined in RFC2960 and +RFC3309. It is a message oriented, reliable transport protocol with direct +support for multihoming that runs on top of +.BR ip (7), +and supports both v4 and v6 versions. +.PP +Like TCP, SCTP provides reliable, connection oriented data delivery with +congestion control. Unlike TCP, SCTP also provides message boundary +preservation, ordered and unordered message delivery, multi-streaming and +multi-homing. Detection of data corruption, loss of data and duplication of +data is achieved by using checksums and sequence numbers. A selective +retransmission mechanism is applied to correct loss or corruption of data. +.PP +This implementation supports a mapping of SCTP into sockets API as defined +in the draft-ietf-tsvwg-sctpsocket-10.txt(Sockets API extensions for SCTP). +Two styles of interfaces are supported. +.PP +A +.B one-to-many +style interface with 1 to MANY relationship between socket and associations +where the outbound association setup is implicit. The syntax of a one-to-many +style socket() call is +.PP +.B sd = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); +.PP +A typical server in this style uses the following socket calls in sequence +to prepare an endpoint for servicing requests. +.PP + 1. socket() + 2. bind() + 3. listen() + 4. recvmsg() + 5. sendmsg() + 6. close() +.PP +A typical client uses the following calls in sequence to setup an association +with a server to request services. +.PP + 1. socket() + 2. sendmsg() + 3. recvmsg() + 4. close() +.PP +A +.B one-to-one style +interface with a 1 to 1 relationship between socket and +association which enables existing TCP applications to be ported to SCTP with +very little effort. The syntax of a one-to-one style socket() call is +.PP +.B sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); +.PP +A typical server in one-to-one style uses the following +system call sequence to prepare an SCTP endpoint for servicing requests: +.PP + 1. socket() + 2. bind() + 3. listen() + 4. accept() +.PP +The accept() call blocks until a new association is set up. It returns with a +new socket descriptor. The server then uses the new socket descriptor to +communicate with the client, using recv() and send() calls to get requests and +send back responses. Then it calls +.PP + 5. close() +.PP +to terminate the association. A typical client uses the following system call +sequence to setup an association with a server to request services: +.PP + 1. socket() + 2. connect() +.PP +After returning from connect(), the client uses send() and recv() calls to +send out requests and receive responses from the server. The client calls +.PP + 3. close() +.PP +to terminate this association when done. +.SH "ADDRESS FORMATS" +SCTP is built on top of IP (see +.BR ip (7)). +The address formats defined by +.BR ip (7) +apply to SCTP. SCTP only supports point-to-point communication; broadcasting +and multicasting are not supported. +.SH SYSCTLS +These variables can be accessed by the +.B /proc/sys/net/sctp/* +files or with the +.BR sysctl (2) +interface. In addition, most IP sysctls also apply to SCTP. See +.BR ip (7). +.TP +.B addip_enable +Enable SCTP ADDIP(Dynamic Address Reconfiguration) Support. This is off +by default. +.TP +.B association_max_retrans +Maximum number of consecutive retransmissions to a peer before an endpoint +considers that the peer is unreachable and closes the association. The default +value is 10. +.TP +.B cookie_preserve_enable +Handle COOKIE PRESERVATIVE parameter in the INIT chunk. This is on by default. +.TP +.B hb_interval +This is the interval when a HEARTBEAT chunk is sent to a destination transport +address to monitor the reachability of an idle destination transport address. +The default is 30 seconds and is maintained in msecs. +.TP +.B max_burst +Maximum number of new data packets that can be sent in a burst. The default +value is 4. +.TP +.B max_init_retransmits +Maximum number of times an INIT chunk or a COOKIE ECHO chunk is retransmitted +before an endpoint aborts the initialization process and closes the association. +The default value is 8. +.TP +.B path_max_retrans +Maximum number of consecutive retransmissions over a destination transport +address of a peer endpoint before it is marked as inactive. The default value +is 5. +.TP +.B prsctp_enable +Enable PR-SCTP. This is on by default. +.TP +.B rcvbuf_policy +This controls the socket receive buffer accounting policy. The default value +is 0 and indicates that all the associations belonging to a socket share the +same receive buffer space. When set to 1, each association will have its own +receive buffer space. +.TP +.B rto_alpha_exp_divisor +This is the RTO.Alpha value when expressed in right shifts and is used in +RTO calculations. The default value is 3. +.TP +.B rto_beta_exp_divisor +This is the RTO.Beta value when expressed in right shifts and is used in +RTO calculations. The default value is 2. +.TP +.B rto_initial +This is the initial value of RTO(retransmission timeout) that is used in RTO +calculations. The default value is 3 seconds and is maintained in msecs. +.TP +.B rto_max +This is the maximum value of RTO(retransmission timeout) that is used in RTO +calculations. The default value is 60 seconds and is maintained in msecs. +.TP +.B rto_min +This is the minimum value of RTO(retransmission timeout) that is used in RTO +calculations. The default value is 1 second and is maintained in msecs. +.TP +.B sack_timeout +Delayed SACK timeout. The default value is 200msecs. +.TP +.B sndbuf_policy +This controls the socket sendbuffer accounting policy. The default value is +0 and indicates that all the associations belonging to a socket share the +same send buffer space. When set to 1, each association will have its own +send buffer space. +.TP +.B valid_cookie_life +This is the maximum lifespan of the Cookie sent in an INIT ACK chunk. The +default value is 60 secs and is maintained in msecs. +.SH "STATISTICS" +These variables can be accessed by the +.B /proc/net/sctp/* +files. +.TP +.B assocs +Displays the following information about the active associations. +assoc ptr, sock ptr, socket style, sock state, association state, hash bucket, +association id, bytes in transmit queue, bytes in receive queue, user id, +inode, local port, remote port, local addresses and remote addresses. +.TP +.B eps +Displays the following information about the active endpoints. +endpoint ptr, sock ptr, socket style, sock state, hash bucket, local port, +user id, inode and local addresses. +.TP +.B snmp +Displays the following statistics related to SCTP states, packets and chunks. +.TP +.TP +.B SctpCurrEstab +The number of associations for which the current state is either ESTABLISHED, +SHUTDOWN-RECEIVED or SHUTDOWN-PENDING. +.TP +.B SctpActiveEstabs +The number of times that associations have made a direct transition to the +ESTABLISHED state from the COOKIE-ECHOED state. The upper layer initiated the +association attempt. +.TP +.B SctpPassiveEstabs +The number of times that associations have made a direct transition to the +ESTABLISHED state from the CLOSED state. The remote endpoint initiated the +association attempt. +.TP +.B SctpAborteds +The number of times that associations have made a direct transition to the +CLOSED state from any state using the primitive 'ABORT'. Ungraceful +termination of the association. +.TP +.B SctpShutdowns +The number of times that associations have made a direct transition to the +CLOSED state from either the SHUTDOWN-SENT state or the SHUTDOWN-ACK-SENT +state. Graceful termination of the association. +.TP +.B SctpOutOfBlues +The number of out of the blue packets received by the host. An out of the blue +packet is an SCTP packet correctly formed, including the proper checksum, but +for which the receiver was unable to identify an appropriate association. +.TP +.B SctpChecksumErrors +The number of SCTP packets received with an invalid checksum. +.TP +.B SctpOutCtrlChunks +The number of SCTP control chunks sent (retransmissions are not included). +Control chunks are those chunks different from DATA. +.TP +.B SctpOutOrderChunks +The number of SCTP ordered data chunks sent (retransmissions are not included). +.TP +.B SctpOutUnorderChunks +The number of SCTP unordered chunks(data chunks in which the U bit is set +to 1) sent (retransmissions are not included). +.TP +.B SctpInCtrlChunks +The number of SCTP control chunks received (no duplicate chunks included). +.TP +.B SctpInOrderChunks +The number of SCTP ordered data chunks received (no duplicate chunks included). +.TP +.B SctpInUnorderChunks +The number of SCTP unordered chunks(data chunks in which the U bit is set +to 1) received (no duplicate chunks included). +.TP +.B SctpFragUsrMsgs +The number of user messages that have to be fragmented because of the MTU. +.TP +.B SctpReasmUsrMsgs +The number of user messages reassembled, after conversion into DATA chunks. +.TP +.B SctpOutSCTPPacks +The number of SCTP packets sent. Retransmitted DATA chunks are included. +.TP +.B SctpInSCTPPacks +The number of SCTP packets received. Duplicates are included. +.SH "SOCKET OPTIONS" +To set or get a SCTP socket option, call +.BR getsockopt (2) +to read or +.BR setsockopt (2) +to write the option with the option level argument set to +.BR SOL_SCTP. +.TP +.BR SCTP_RTOINFO. +This option is used to get or set the protocol parameters used to +initialize and bound retransmission timout(RTO). The structure sctp_rtoinfo +defined in /usr/include/netinet/sctp.h is used to access and modify these +parameters. +.TP +.B SCTP_ASSOCINFO +This option is used to both examine and set various association and endpoint +parameters. The sturcture sctp_assocparams defined in +/usr/include/netinet/sctp.h is used to access and modify these parameters. +.TP +.B SCTP_INITMSG +This option is used to get or set the protocol parameters for the default +association initialization. The structure sctp_initmsg defined in +/usr/include/netinet/sctp.h is used to access and modify these parameters. + +Setting initialization parameters is effective only on an unconnected +socket (for one-to-many style sockets only future associations are +effected by the change). With one-to-one style sockets, this option +is inherited by sockets derived from a listener socket. +.TP +.B SCTP_NODELAY +Turn on/off any Nagle-like algorithm. This means that packets are generally +sent as soon as possible and no unnecessary delays are introduced, at the cost +of more packets in the network. Expects an integer boolean flag. +.TP +.B SCTP_AUTOCLOSE +This socket option is applicable to the one-to-many style socket +only. When set it will cause associations that are idle for more than +the specified number of seconds to automatically close. An +association being idle is defined an association that has NOT sent or +received user data. The special value of 0 indicates that no +automatic close of any associations should be performed. The option +expects an integer defining the number of seconds of idle time before +an association is closed. +.TP +.B SCTP_SET_PEER_PRIMARY_ADDR +Requests that the peer mark the enclosed address as the association +primary. The enclosed address must be one of the association's +locally bound addresses. The structure sctp_setpeerprim defined in +/usr/include/netinet/sctp.h is used to make a set peer primary request. +.TP +.B SCTP_PRIMARY_ADDR +Requests that the local SCTP stack use the enclosed peer address as +the association primary. The enclosed address must be one of the +association peer's addresses. The structure sctp_prim defined in +/usr/include/netinet/sctp.h is used to make a get/set primary request. +.TP +.B SCTP_DISABLE_FRAGMENTS +This option is a on/off flag and is passed an integer where a non-zero is on +and a zero is off. If enabled no SCTP message fragmentation will be performed. +Instead if a message being sent exceeds the current PMTU size, the message will +NOT be sent and an error will be indicated to the user. +.TP +.B SCTP_PEER_ADDR_PARAMS +Using this option, applications can enable or disable heartbeats for any peer +address of an association, modify an address's heartbeat interval, force a +heartbeat to be sent immediately, and adjust the address's maximum number of +retransmissions sent before an address is considered unreachable. The structure +sctp_paddrparams defined in /usr/include/netinet/sctp.h is used to +access and modify an address's parameters. +.TP +.B SCTP_DEFAULT_SEND_PARAM +Applications that wish to use the sendto() system call may wish to specify +a default set of parameters that would normally be supplied through the +inclusion of ancillary data. This socket option allows such an application to +set the default sctp_sndrcvinfo structure. The application that wishes to use +this socket option simply passes in to this call the sctp_sndrcvinfo structure +defined in /usr/include/netinet/sctp.h. The input parameters accepted by this +call include sinfo_stream, sinfo_flags, sinfo_ppid, sinfo_context, +sinfo_timetolive. The user must set the sinfo_assoc_id field to identify the + association to affect if the caller is using the one-to-many style. +.TP +.B SCTP_EVENTS +This socket option is used to specify various notifications and ancillary data +the user wishes to receive. The structure sctp_event_subscribe defined in +/usr/include/netinet/sctp.h is used to access or modify the events of interest +to the user. +.TP +.B SCTP_I_WANT_MAPPED_V4_ADDR +This socket option is a boolean flag which turns on or off mapped V4 +addresses. If this option is turned on and the socket is type PF_INET6, +then IPv4 addresses will be mapped to V6 representation. If this option is +turned off, then no mapping will be done of V4 addresses and a user will +receive both PF_INET6 and PF_INET type addresses on the socket. + +By default this option is turned on and expects an integer to be passed where +non-zero turns on the option and zero turns off the option. +.TP +.B SCTP_MAXSEG +This socket option specifies the maximum size to put in any outgoing +SCTP DATA chunk. If a message is larger than this size it will be +fragmented by SCTP into the specified size. Note that the underlying +SCTP implementation may fragment into smaller sized chunks when the +PMTU of the underlying association is smaller than the value set by +the user. The option expects an integer. + +The default value for this option is 0 which indicates the user is +NOT limiting fragmentation and only the PMTU will effect SCTP's +choice of DATA chunk size. +.TP +.B SCTP_STATUS +Applications can retrieve current status information about an association, +including association state, peer receiver window size, number of unacked +data chunks, and number of data chunks pending receipt. This information is +read-only. The structure sctp_status defined in /usr/include/netinet/sctp.h +is used to access this information. +.TP +.B SCTP_GET_PEER_ADDR_INFO +Applications can retrieve information about a specific peer address +of an association, including its reachability state, congestion window, +and retransmission timer values. This information is read-only. The structure +sctp_paddr_info defined in /usr/include/netinet/sctp.h is used to access this +information. +.SH AUTHORS +Sridhar Samudrala +.SH "SEE ALSO" +.BR socket (7), +.BR socket (2), +.BR ip (7), +.BR bind (2), +.BR listen (2), +.BR accept (2), +.BR connect (2), +.BR sendmsg (2), +.BR recvmsg (2), +.BR sysctl (2), +.BR getsockopt (2), +.BR sctp_bindx (3), +.BR sctp_connectx (3), +.BR sctp_sendmsg (3), +.BR sctp_send (3), +.BR sctp_recvmsg (3), +.BR sctp_peeloff (3), +.BR sctp_getladdrs (3), +.BR sctp_getpaddrs (3), +.BR sctp_opt_info (3). +.sp +RFC2960, RFC3309 for the SCTP specification. diff --git a/man/sctp_bindx.3 b/man/sctp_bindx.3 new file mode 100644 index 0000000..61177d8 --- /dev/null +++ b/man/sctp_bindx.3 @@ -0,0 +1,92 @@ +.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005. +.\" +.\" Permission is granted to distribute possibly modified copies +.\" of this manual provided the header is included verbatim, +.\" and in case of nontrivial modification author and date +.\" of the modification is added to the header. +.\" +.TH SCTP_BINDX 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual" +.SH NAME +sctp_bindx \- Add or remove bind addresses on a socket. +.SH SYNOPSIS +.nf +.B #include +.B #include +.B #include +.sp +.BI "int sctp_bindx(int " sd ", struct sockaddr * " addrs ", int " addrcnt , +.BI " int " flags ); +.fi +.SH DESCRIPTION +.BR sctp_bindx +adds or removes a set of bind addresses passed in the array +.I addrs +to/from the socket +.I sd. +.I addrcnt +is the number of addresses in the array and the +.I flags +paramater indicates if the addresses need to be added or removed. +.PP +If +.I sd +is an IPv4 socket, the addresses passed must be IPv4 addresses. If +.I sd +is an IPv6 socket, the addresses passed can be either IPv4 or IPv6 +addresses. +.PP +.I addrs +is a pointer to an array of one or more socket addresses. Each address is +contained in its appropriate structure(i.e. struct sockaddr_in or struct +sockaddr_in6). The family of the address type must be used to distinguish +the address length. The caller specifies the number of addresses in the +array with +.I addrcnt. +.PP +The +.I flags +parameter can be either +.B SCTP_BINDX_ADD_ADDR +or +.B SCTP_BINDX_REM_ADDR. +An application can use +.B SCTP_BINDX_ADD_ADDR +to associate additional addresses with an endpoint after calling +.BR bind(2). +.B SCTP_BINDX_REM_ADDR +directs SCTP to remove the given addresses from the association. +A caller may not remove all addresses from an association. It will +fail with +.B EINVAL. +.SH "RETURN VALUE" +On success, 0 is returned. On failure, \-1 is returned, and +.I errno +is set appropriately. +.SH ERRORS +.TP +.B EBADF +.I sd +is not a valid descriptor. +.TP +.B ENOTSOCK +.I sd +is a descriptor for a file, not a socket. +.TP +.B EFAULT +Error while copying in or out from the user address space. +.TP +.B EINVAL +Invalid port or address or trying to remove all addresses from an association. +.TP +.B EACCES +The address is protected, and the user is not the super-user. +.SH "SEE ALSO" +.BR sctp (7) +.BR sctp_sendmsg (3), +.BR sctp_send (3), +.BR sctp_recvmsg (3), +.BR sctp_peeloff (3), +.BR sctp_getpaddrs (3), +.BR sctp_getladdrs (3), +.BR sctp_opt_info (3), +.BR sctp_connectx (3) diff --git a/man/sctp_connectx.3 b/man/sctp_connectx.3 new file mode 100644 index 0000000..4ee7fc6 --- /dev/null +++ b/man/sctp_connectx.3 @@ -0,0 +1,142 @@ +.\" (C) Copyright Frank Filz IBM Corp. 2005. +.\" +.\" Permission is granted to distribute possibly modified copies +.\" of this manual provided the header is included verbatim, +.\" and in case of nontrivial modification author and date +.\" of the modification is added to the header. +.\" +.TH SCTP_CONNECTX 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual" +.SH NAME +sctp_connectx \- initiate a connection on an SCTP socket using multiple +destination addresses. +.SH SYNOPSIS +.nf +.B #include +.B #include +.B #include +.sp +.BI "int sctp_connectx(int " sd ", struct sockaddr * " addrs ", int " addrcnt, +.BI " sctp_assoc_t * "id ); +.fi +.SH DESCRIPTION +.BR sctp_connectx +initiates a connection to a set of addresses passed in the array +.I addrs +to/from the socket +.I sd. +.I addrcnt +is the number of addresses in the array. +.PP +If +.I sd +is an IPv4 socket, the addresses passed must be IPv4 addresses. If +.I sd +is an IPv6 socket, the addresses passed can be either IPv4 or IPv6 +addresses. +.PP +.I addrs +is a pointer to an array of one or more socket addresses. Each address is +contained in its appropriate structure(i.e. struct sockaddr_in or struct +sockaddr_in6). The family of the address type must be used to distinguish +the address length. The caller specifies the number of addresses in the +array with +.I addrcnt. +.PP +.I id +is a pointer to the association id and, if provided, will be set to the +identifier of the newly created association. +.SH "RETURN VALUE" +On success, 0 is returned. On failure, \-1 is returned, and +.I errno +is set appropriately. +.SH ERRORS +.TP +.B EBADF +.I sd +is not a valid descriptor. +.TP +.B ENOTSOCK +.I sd +is a descriptor for a file, not a socket. +.TP +.B EFAULT +Error while copying in or out from the user address space. +.TP +.B EINVAL +Invalid port or address. +.TP +.B EACCES +The address is protected, and the user is not the super-user. +.TP +.B EISCONN +The socket is already connected. +.TP +.B ECONNREFUSED +No one listening on the remote address. +.TP +.B ETIMEDOUT +Timeout while attempting connection. The server may be too +busy to accept new connections. Note that for IP sockets the timeout may +be very long when syncookies are enabled on the server. +.TP +.B ENETUNREACH +Network is unreachable. +.TP +.B EADDRINUSE +Local address is already in use. +.TP +.B EINPROGRESS +The socket is non-blocking and the connection cannot be completed +immediately. It is possible to +.BR select (2) +or +.BR poll (2) +for completion by selecting the socket for writing. After +.B select +indicates writability, use +.BR getsockopt (2) +to read the +.B SO_ERROR +option at level +.B SOL_SOCKET +to determine whether +.B connect +completed successfully +.RB ( SO_ERROR +is zero) or unsuccessfully +.RB ( SO_ERROR +is one of the usual error codes listed here, +explaining the reason for the failure). +.TP +.B EALREADY +The socket is non-blocking and a previous connection attempt has not yet +been completed. +.TP +.B EAGAIN +No more free local ports or insufficient entries in the routing cache. For +.B PF_INET +see the +.B net.ipv4.ip_local_port_range +sysctl in +.BR ip (7) +on how to increase the number of local ports. +.TP +.B EAFNOSUPPORT +The passed address didn't have the correct address family in its +.I sa_family +field. +.TP +.B EACCES, EPERM +The user tried to connect to a broadcast address without having the socket +broadcast flag enabled or the connection request failed because of a local +firewall rule. +.SH "SEE ALSO" +.BR sctp (7) +.BR sctp_bindx (3), +.BR sctp_sendmsg (3), +.BR sctp_send (3), +.BR sctp_recvmsg (3), +.BR sctp_peeloff (3), +.BR sctp_getpaddrs (3), +.BR sctp_getladdrs (3), +.BR sctp_opt_info (3), diff --git a/man/sctp_getladdrs.3 b/man/sctp_getladdrs.3 new file mode 100644 index 0000000..89c39ec --- /dev/null +++ b/man/sctp_getladdrs.3 @@ -0,0 +1,76 @@ +.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005. +.\" +.\" Permission is granted to distribute possibly modified copies +.\" of this manual provided the header is included verbatim, +.\" and in case of nontrivial modification author and date +.\" of the modification is added to the header. +.\" +.TH SCTP_GETLADDRS 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual" +.SH NAME +sctp_getladdrs \- Returns all locally bound addresses on a socket. +.SH SYNOPSIS +.nf +.B #include +.B #include +.B #include +.sp +.BI "int sctp_getladdrs(int " sd ", sctp_assoc_t " assoc_id , +.BI " struct sockaddr **" addrs ); +.sp +.BI "void sctp_freeladdrs(struct sockaddr *" addrs ); +.fi +.SH DESCRIPTION +.BR sctp_getladdrs +returns all locally bound addresses on a socket. On return, +.I addrs +will point to a dynamically allocated packed array of +.B sockaddr +structures of the appropriate type for each local address. The caller +should use +.BR sctp_freeladdrs +to free the memory. Note that the in/out parameter +.I addrs +must not be NULL. +.PP +If +.I sd +is an IPv4 socket, the addresses returned will be all IPv4 addresses. If +.I sd +is an IPv6 socket, the addresses returned can be a mix of IPv4 or IPv6 +addresses. +.PP +For one-to-many style sockets, +.I id +specifies the association to query. For one-to-one style sockets, +.I id +is ignored. +.PP +If the +.I id +field is set to 0, then the locally bound addresses are returned +without regard to any particular association. +.PP +.BR sctp_freeladdrs +frees all the resources allocated by +.BR sctp_getladdrs +.SH "RETURN VALUE" +On success, +.BR sctp_getladdrs +returns the number of local addresses bound to the socket. If the socket +is unbound, 0 is returned and the value of +.I *addrs +is undefined. On error, +.BR sctp_getladdrs +returns -1 and the value of +.I *addrs +is undefined. +.SH "SEE ALSO" +.BR sctp (7) +.BR sctp_bindx (3), +.BR sctp_connectx (3), +.BR sctp_sendmsg (3), +.BR sctp_send (3), +.BR sctp_recvmsg (3), +.BR sctp_peeloff (3), +.BR sctp_getpaddrs (3), +.BR sctp_opt_info (3), diff --git a/man/sctp_getpaddrs.3 b/man/sctp_getpaddrs.3 new file mode 100644 index 0000000..748b600 --- /dev/null +++ b/man/sctp_getpaddrs.3 @@ -0,0 +1,70 @@ +.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005. +.\" +.\" Permission is granted to distribute possibly modified copies +.\" of this manual provided the header is included verbatim, +.\" and in case of nontrivial modification author and date +.\" of the modification is added to the header. +.\" +.TH SCTP_GETPADDRS 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual" +.SH NAME +sctp_getpaddrs \- Returns all peer addresses in an association. +.SH SYNOPSIS +.nf +.B #include +.B #include +.B #include +.sp +.BI "int sctp_getpaddrs(int " sd ", sctp_assoc_t " assoc_id , +.BI " struct sockaddr **" addrs ); +.sp +.BI "void sctp_freepaddrs(struct sockaddr *" addrs ); +.fi +.SH DESCRIPTION +.BR sctp_getpaddrs +returns all peer addresses in an association. On return, +.I addrs +will point to a dynamically allocated packed array of +.B sockaddr +structures of the appropriate type for each address. The caller should use +.BR sctp_freepaddrs +to free the memory. Note that the in/out parameter +.I addrs +must not be NULL. +.PP +If +.I sd +is an IPv4 socket, the addresses returned will be all IPv4 addresses. If +.I sd +is an IPv6 socket, the addresses returned can be a mix of IPv4 or IPv6 +addresses. +.PP +For one-to-many style sockets, +.I id +specifies the association to query. For one-to-one style sockets, +.I id +is ignored. +.PP +.BR sctp_freepaddrs +frees all the resources allocated by +.BR sctp_getpaddrs. +.SH "RETURN VALUE" +On success, +.BR sctp_getpaddrs +returns the number of peer addresses in the association. If there is no +association on this socket, 0 is returned and the value of +.I *addrs +is undefined. On error, +.BR sctp_getpaddrs +returns -1 and the value of +.I *addrs +is undefined. +.SH "SEE ALSO" +.BR sctp (7) +.BR sctp_bindx (3), +.BR sctp_connectx (3), +.BR sctp_sendmsg (3), +.BR sctp_send (3), +.BR sctp_recvmsg (3), +.BR sctp_peeloff (3), +.BR sctp_getladdrs (3), +.BR sctp_opt_info (3), diff --git a/man/sctp_opt_info.3 b/man/sctp_opt_info.3 new file mode 100644 index 0000000..47a19c3 --- /dev/null +++ b/man/sctp_opt_info.3 @@ -0,0 +1,54 @@ +.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005. +.\" +.\" Permission is granted to distribute possibly modified copies +.\" of this manual provided the header is included verbatim, +.\" and in case of nontrivial modification author and date +.\" of the modification is added to the header. +.\" +.TH SCTP_OPT_INFO 3 2004-01-30 "Linux 2.6" "Linux Programmer's Manual" +.SH NAME +sctp_optinfo \- Get options on a SCTP socket. +.SH SYNOPSIS +.nf +.B #include +.B #include +.B #include +.sp +.BI "int sctp_opt_info(int " sd ", sctp_assoc_t " id ", int " opt , +.BI " void * " arg ", socklen_t * " size); +.fi +.SH DESCRIPTION +.BR sctp_opt_info +is a wrapper library function that can be used to get SCTP level options on +a socket. +.I sd +is the socket descriptor for which the option is requested. For one-to-many +style sockets, +.I id +specifies the association to query. For one-to-one style sockets, +.I id +is ignored. +.I opt +specifes the SCTP socket option to get. +.I arg +is an option-specific structure buffer provided by the caller. +.I size +is a value-result parameter, initially containing the size of the buffer +pointed to by +.I arg +and modifed on return to indicate the actual size of the value returned. +.SH "RETURN VALUE" +On success, +.BR sctp_opt_info +returns 0 and on failure -1 is returned with errno set to the appropriate +error code. +.SH "SEE ALSO" +.BR sctp (7) +.BR sctp_bindx (3), +.BR sctp_connectx (3), +.BR sctp_sendmsg (3), +.BR sctp_send (3), +.BR sctp_recvmsg (3), +.BR sctp_peeloff (3), +.BR sctp_getpaddrs (3), +.BR sctp_getladdrs (3), diff --git a/man/sctp_peeloff.3 b/man/sctp_peeloff.3 new file mode 100644 index 0000000..7cbde5d --- /dev/null +++ b/man/sctp_peeloff.3 @@ -0,0 +1,56 @@ +.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005. +.\" +.\" Permission is granted to distribute possibly modified copies +.\" of this manual provided the header is included verbatim, +.\" and in case of nontrivial modification author and date +.\" of the modification is added to the header. +.\" +.TH SCTP_PEELOFF 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual" +.SH NAME +sctp_peeloff \- Branch off an association into a separate socket. +.SH SYNOPSIS +.nf +.B #include +.B #include +.B #include +.sp +.BI "int sctp_peeloff(int " sd ", sctp_assoc_t " assoc_id ); +.fi +.SH DESCRIPTION +.B sctp_peeloff +branches off an existing association +.I assoc_id +on a one-to-many style socket +.I sd +into a separate socket. The new socket is a one-to-one style socket. +.PP +This is particularly desirable when, for instance, the application wishes to +have a number of sporadic message senders/receivers remain under the original +one-to-many style socket, but branch off those assocations carrying high volume +data traffic into their own separate socket descriptors. +.SH "RETURN VALUE" +On success, the new socket descriptor representing the branched-off asociation is returned. +On error, \-1 is returned, and +.I errno +is set appropriately. +.SH ERRORS +.TP +.B EBADF +.I sd +is not a valid descriptor. +.TP +.B EINVAL +The assoc id passed is invalid or if the socket is a one-to-one style socket. +.TP +.B ENOTSOCK +Argument is a descriptor for a file, not a socket. +.SH "SEE ALSO" +.BR sctp (7) +.BR sctp_bindx (3), +.BR sctp_connectx (3), +.BR sctp_sendmsg (3), +.BR sctp_send (3), +.BR sctp_recvmsg (3), +.BR sctp_getpaddrs (3), +.BR sctp_getladdrs (3), +.BR sctp_opt_info (3), diff --git a/man/sctp_recvmsg.3 b/man/sctp_recvmsg.3 new file mode 100644 index 0000000..91f3172 --- /dev/null +++ b/man/sctp_recvmsg.3 @@ -0,0 +1,61 @@ +.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005. +.\" +.\" Permission is granted to distribute possibly modified copies +.\" of this manual provided the header is included verbatim, +.\" and in case of nontrivial modification author and date +.\" of the modification is added to the header. +.\" +.TH SCTP_RECVMSG 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual" +.SH NAME +sctp_recvmsg \- Receive a message from a SCTP socket. +.SH SYNOPSIS +.nf +.B #include +.B #include +.B #include +.sp +.BI "int sctp_recvmsg(int " sd ", void * " msg ", size_t " len , +.BI " struct sockaddr * " from ", socklen_t * " fromlen , +.BI " struct sctp_sndrcvinfo * " sinfo ", int * " msg_flags); +.fi +.SH DESCRIPTION +.BR sctp_recvmsg +is a wrapper library function that can be used to receive a message from +a socket while using the advanced features of SCTP. +.I sd +is the socket descriptor on which the message pointed to by +.I msg +of length +.I len +is received. +.PP +If +.I from +is not NULL, the source address of the message is filled in. The argument +.I fromlen +is a value-result parameter. initialized to the size of the buffer associated +with +.I from , +and modified on return to indicate the actual size of the address stored. +.PP +.I sinfo +is a pointer to a sctp_sndrcvinfo structure to be filled upon receipt of the +message. +.I msg_flags +is a pointer to a integer that is filled with any message flags like +.B MSG_NOTIFICATION or +.B MSG_EOR. +.SH "RETURN VALUE" +On success, +.BR sctp_recvmsg +returns the number of bytes received or -1 if an error occurred. +.SH "SEE ALSO" +.BR sctp (7) +.BR sctp_bindx (3), +.BR sctp_connectx (3), +.BR sctp_sendmsg (3), +.BR sctp_send (3), +.BR sctp_peeloff (3), +.BR sctp_getpaddrs (3), +.BR sctp_getladdrs (3), +.BR sctp_opt_info (3) diff --git a/man/sctp_send.3 b/man/sctp_send.3 new file mode 100644 index 0000000..9b0b3eb --- /dev/null +++ b/man/sctp_send.3 @@ -0,0 +1,48 @@ +.\" (C) Copyright Sridhar Samudrala IBM Corp. 2005. +.\" +.\" Permission is granted to distribute possibly modified copies +.\" of this manual provided the header is included verbatim, +.\" and in case of nontrivial modification author and date +.\" of the modification is added to the header. +.\" +.TH SCTP_SEND 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual" +.SH NAME +sctp_send \- Send a message from a SCTP socket. +.SH SYNOPSIS +.nf +.B #include +.B #include +.B #include +.sp +.BI "int sctp_send(int " sd ", const void * " msg ", size_t " len , +.BI " const struct sctp_sndrcvinfo *" sinfo ", +.BI " uint32_t " flags ); +.fi +.SH DESCRIPTION +.BR sctp_send +is a wrapper library function that can be used to send a message from a socket +without the use of the CMSG header structures. +.I sd +is the socket descriptor from which the message pointed to by +.I msg +of length +.I len +is sent. +.I sinfo +is a pointer to a sctp_sndrcvinfo structure. +.I flags +parameter is composed of a bitwise OR of the flags that can be be passed as +the 3rd argument of a standard sendmsg() call. +.SH "RETURN VALUE" +On success, +.BR sctp_sendmsg +returns the number of bytes sent or -1 if an error occurred. +.SH "SEE ALSO" +.BR sctp (7) +.BR sctp_bindx (3), +.BR sctp_recvmsg (3), +.BR sctp_peeloff (3), +.BR sctp_getpaddrs (3), +.BR sctp_getladdrs (3), +.BR sctp_opt_info (3), +.BR sctp_sendmsg (3) diff --git a/man/sctp_sendmsg.3 b/man/sctp_sendmsg.3 new file mode 100644 index 0000000..c5fe86d --- /dev/null +++ b/man/sctp_sendmsg.3 @@ -0,0 +1,84 @@ +.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005. +.\" +.\" Permission is granted to distribute possibly modified copies +.\" of this manual provided the header is included verbatim, +.\" and in case of nontrivial modification author and date +.\" of the modification is added to the header. +.\" +.TH SCTP_SENDMSG 3 2004-10-25 "Linux 2.6" "Linux Programmer's Manual" +.SH NAME +sctp_sendmsg \- Send a message from a SCTP socket. +.SH SYNOPSIS +.nf +.B #include +.B #include +.B #include +.sp +.BI "int sctp_sendmsg(int " sd ", const void * " msg ", size_t " len , +.BI " struct sockaddr *" to ", socklen_t " tolen , +.BI " uint32_t " ppid ", uint32_t " flags , +.BI " uint16_t " stream_no ", uint32_t " timetolive , +.BI " uint32_t " context ); +.fi +.SH DESCRIPTION +.BR sctp_sendmsg +is a wrapper library function that can be used to send a message from a socket +while using the advanced features of SCTP. +.I sd +is the socket descriptor from which the message pointed to by +.I msg +of length +.I len +is sent. +.I to +is the destination address of the message and +.I tolen +is the length of the destination address. +.I stream_no +identifies the stream number that the application wishes to send this message to. +.I flags +parameter is composed of a bitwise OR of the following values. +.TP +.B SCTP_UNORDERED +This flags requests the un-ordered delivery of the message. +.TP +.B SCTP_ADDR_OVER +This flag, in the one-to-many style, requests the SCTP stack to override the +primary destination address with address specified in +.I to. +.TP +.B SCTP_ABORT +Setting this flag causes the specified association to abort by sending an ABORT +message to the peer(one-to-many style only). The ABORT chunk will contain an +error cause 'User Initiated Abort' with cause code 12. The cause specific +information of this error cause is provided in +.I msg. +.TP +.B SCTP_EOF +Setting this flag invokes the SCTP graceful shutdown procedure on the specific +association(one-to-many style only). +.PP +.I timetolive +specifies the time duration in milliseconds. The sending side will expire the +message if the message has not been sent to the peer within this time period. +A value of 0 indicates that no timeout should occur on this message. +.I ppid +is an opaque unsigned value that is passed to the remote end along with the +message. +.I context +is a 32 bit opaque value that is passed back to the upper layer along with the +undelivered message if an error occurs on the send of the message. +.SH "RETURN VALUE" +On success, +.BR sctp_sendmsg +returns the number of bytes sent or -1 if an error occurred. +.SH "SEE ALSO" +.BR sctp (7) +.BR sctp_bindx (3), +.BR sctp_connectx (3), +.BR sctp_send (3), +.BR sctp_recvmsg (3), +.BR sctp_peeloff (3), +.BR sctp_getpaddrs (3), +.BR sctp_getladdrs (3), +.BR sctp_opt_info (3), diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..66f6caa --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,4 @@ +include $(top_srcdir)/Makefile.vars +include $(top_srcdir)/Makefile.rules + +SUBDIRS = apps func_tests include lib testlib withsctp diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..95a0d00 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,510 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*-makefile-*- +# +# type: deep, strictness: gnu +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.rules $(top_srcdir)/Makefile.vars +subdir = src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +MAINTAINERCLEANFILES = Makefile.in +DISTCLEANFILES = \\\#*\\\# Makefile +CLEANFILES = +MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io +EXTRA_DIST = +LATEX = @LATEX@ +DVIPS = @DVIPS@ +DVIPDFM = @DVIPDFM@ +ENSCRIPTBIN = @ENSCRIPTBIN@ +PS2PDF = @PS2PDF@ +edit = @sed \ + -e "s|\@bindir\@|$(bindir)|" \ + -e "s|\@libdir\@|$(libdir)|" \ + -e "s|\@PACKAGE\@|$(PACKAGE)|" + +SUBDIRS = apps func_tests include lib testlib withsctp +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.vars $(top_srcdir)/Makefile.rules $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(mkdir_p) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ + clean clean-generic clean-libtool clean-recursive ctags \ + ctags-recursive distclean distclean-generic distclean-libtool \ + distclean-recursive distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic maintainer-clean-recursive \ + mostlyclean mostlyclean-generic mostlyclean-libtool \ + mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-info-am + + +# -*-makefile-*- +# +# Generate pre-parsed C code. +%.i: %.c + $(COMPILE) -E -c $^ -o $@ + +.PRECIOUS: %.i +%.ci: %.i + -grep -v -e "^#" -e "^ *$$" $^ | indent > $@ + mv -f $@ $^ +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/apps/Makefile.am b/src/apps/Makefile.am new file mode 100644 index 0000000..0e6f9ee --- /dev/null +++ b/src/apps/Makefile.am @@ -0,0 +1,40 @@ +# Include these two in all the Makefile.am's!!! +include $(top_srcdir)/Makefile.vars +include $(top_srcdir)/Makefile.rules + +include $(top_srcdir)/Makefile.dirs + +# General compilation flags +INCLUDES = -I. -I$(top_srcdir)/src/include -I$(top_srcdir)/src/testlib +AM_CFLAGS = -g -Wall -Wstrict-prototypes -Wimplicit-function-declaration +AM_LDFLAGS = +LDADD = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la + +# programs to be installed with the distriubution +bin_PROGRAMS = sctp_darn sctp_test sctp_status + +# Test programs and libraries to build +noinst_PROGRAMS = bindx_test nagle_snd nagle_rcv myftp sctp_xconnect \ + peel_server peel_client sctp_test sctp_status + +$(top_builddir)/src/lib/libsctp.la: + make -C $(top_builddir)/src/lib libsctp.la + +$(top_builddir)/src/testlib/libsctputil.la: + make -C $(top_builddir)/src/testlib libsctputil.la + +# Specifying the sources +bindx_test_SOURCES = bindx_test.c +sctp_darn_SOURCES = sctp_darn.c sctp_darn.h +sctp_test_SOURCES = sctp_test.c +sctp_status_SOURCES = sctp_status.c +nagle_rcv_SOURCES = nagle_rcv.c +nagle_snd_SOURCES = nagle_snd.c +myftp_SOURCES = myftp.c +sctp_xconnect_SOURCES = sctp_xconnect.c +peel_server_SOURCES = peel_server.c +peel_client_SOURCES = peel_client.c + +# Tutorials +pkgdoc_DATA = sctp_darn.c sctp_darn.h sctp_test.c sctp_status.c diff --git a/src/apps/Makefile.in b/src/apps/Makefile.in new file mode 100644 index 0000000..17285de --- /dev/null +++ b/src/apps/Makefile.in @@ -0,0 +1,702 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*-makefile-*- +# +# type: deep, strictness: gnu + +# -*-makefile-*- +# +# Define here directories you want + + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.dirs $(top_srcdir)/Makefile.rules \ + $(top_srcdir)/Makefile.vars +bin_PROGRAMS = sctp_darn$(EXEEXT) sctp_test$(EXEEXT) \ + sctp_status$(EXEEXT) +noinst_PROGRAMS = bindx_test$(EXEEXT) nagle_snd$(EXEEXT) \ + nagle_rcv$(EXEEXT) myftp$(EXEEXT) sctp_xconnect$(EXEEXT) \ + peel_server$(EXEEXT) peel_client$(EXEEXT) sctp_test$(EXEEXT) \ + sctp_status$(EXEEXT) +subdir = src/apps +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdocdir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) +am_bindx_test_OBJECTS = bindx_test.$(OBJEXT) +bindx_test_OBJECTS = $(am_bindx_test_OBJECTS) +bindx_test_LDADD = $(LDADD) +bindx_test_DEPENDENCIES = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_myftp_OBJECTS = myftp.$(OBJEXT) +myftp_OBJECTS = $(am_myftp_OBJECTS) +myftp_LDADD = $(LDADD) +myftp_DEPENDENCIES = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_nagle_rcv_OBJECTS = nagle_rcv.$(OBJEXT) +nagle_rcv_OBJECTS = $(am_nagle_rcv_OBJECTS) +nagle_rcv_LDADD = $(LDADD) +nagle_rcv_DEPENDENCIES = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_nagle_snd_OBJECTS = nagle_snd.$(OBJEXT) +nagle_snd_OBJECTS = $(am_nagle_snd_OBJECTS) +nagle_snd_LDADD = $(LDADD) +nagle_snd_DEPENDENCIES = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_peel_client_OBJECTS = peel_client.$(OBJEXT) +peel_client_OBJECTS = $(am_peel_client_OBJECTS) +peel_client_LDADD = $(LDADD) +peel_client_DEPENDENCIES = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_peel_server_OBJECTS = peel_server.$(OBJEXT) +peel_server_OBJECTS = $(am_peel_server_OBJECTS) +peel_server_LDADD = $(LDADD) +peel_server_DEPENDENCIES = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_sctp_darn_OBJECTS = sctp_darn.$(OBJEXT) +sctp_darn_OBJECTS = $(am_sctp_darn_OBJECTS) +sctp_darn_LDADD = $(LDADD) +sctp_darn_DEPENDENCIES = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_sctp_status_OBJECTS = sctp_status.$(OBJEXT) +sctp_status_OBJECTS = $(am_sctp_status_OBJECTS) +sctp_status_LDADD = $(LDADD) +sctp_status_DEPENDENCIES = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_sctp_test_OBJECTS = sctp_test.$(OBJEXT) +sctp_test_OBJECTS = $(am_sctp_test_OBJECTS) +sctp_test_LDADD = $(LDADD) +sctp_test_DEPENDENCIES = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_sctp_xconnect_OBJECTS = sctp_xconnect.$(OBJEXT) +sctp_xconnect_OBJECTS = $(am_sctp_xconnect_OBJECTS) +sctp_xconnect_LDADD = $(LDADD) +sctp_xconnect_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/bin/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(bindx_test_SOURCES) $(myftp_SOURCES) $(nagle_rcv_SOURCES) \ + $(nagle_snd_SOURCES) $(peel_client_SOURCES) \ + $(peel_server_SOURCES) $(sctp_darn_SOURCES) \ + $(sctp_status_SOURCES) $(sctp_test_SOURCES) \ + $(sctp_xconnect_SOURCES) +DIST_SOURCES = $(bindx_test_SOURCES) $(myftp_SOURCES) \ + $(nagle_rcv_SOURCES) $(nagle_snd_SOURCES) \ + $(peel_client_SOURCES) $(peel_server_SOURCES) \ + $(sctp_darn_SOURCES) $(sctp_status_SOURCES) \ + $(sctp_test_SOURCES) $(sctp_xconnect_SOURCES) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +pkgdocDATA_INSTALL = $(INSTALL_DATA) +DATA = $(pkgdoc_DATA) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = $(datadir)/locale +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +MAINTAINERCLEANFILES = Makefile.in directories.h +DISTCLEANFILES = \\\ directories.h +CLEANFILES = +MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io +EXTRA_DIST = +LATEX = @LATEX@ +DVIPS = @DVIPS@ +DVIPDFM = @DVIPDFM@ +ENSCRIPTBIN = @ENSCRIPTBIN@ +PS2PDF = @PS2PDF@ +edit = @sed \ + -e "s|\@bindir\@|$(bindir)|" \ + -e "s|\@libdir\@|$(libdir)|" \ + -e "s|\@PACKAGE\@|$(PACKAGE)|" + +rootbindir = /bin +rootsbindir = /sbin +rootlibdir = /lib +pkgsysconfdir = $(sysconfdir)/@PACKAGE@ +pkgdocdir = $(datadir)/@PACKAGE@ +vpkgsysconfdir = $(pkgsysconfdir)/v@VERSION@ +vpkgdatadir = $(pkgdatadir)/v@VERSION@ +vpkglibdir = $(pkglibdir)/v@VERSION@ +vpkgdocdir = $(docdir)/v@VERSION@ + +# List here all the directories you want listed in the file to be used +# in your programs: +directories := \ + localedir \ + pkgsysconfdir \ + rootbindir \ + rootlibdir \ + rootsbindir \ + vpkgdatadir \ + vpkgdocdir \ + vpkglibdir \ + vpkgsysconfdir \ + \ + bindir \ + datadir \ + libdir \ + pkgdatadir \ + pkgdocdir \ + pkglibdir \ + sbindir + + +# Include these two in all the Makefile.am's!!! + +# General compilation flags +INCLUDES = -I. -I$(top_srcdir)/src/include -I$(top_srcdir)/src/testlib +AM_CFLAGS = -g -Wall -Wstrict-prototypes -Wimplicit-function-declaration +AM_LDFLAGS = +LDADD = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la + + +# Specifying the sources +bindx_test_SOURCES = bindx_test.c +sctp_darn_SOURCES = sctp_darn.c sctp_darn.h +sctp_test_SOURCES = sctp_test.c +sctp_status_SOURCES = sctp_status.c +nagle_rcv_SOURCES = nagle_rcv.c +nagle_snd_SOURCES = nagle_snd.c +myftp_SOURCES = myftp.c +sctp_xconnect_SOURCES = sctp_xconnect.c +peel_server_SOURCES = peel_server.c +peel_client_SOURCES = peel_client.c + +# Tutorials +pkgdoc_DATA = sctp_darn.c sctp_darn.h sctp_test.c sctp_status.c +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.vars $(top_srcdir)/Makefile.rules $(top_srcdir)/Makefile.dirs $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/apps/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/apps/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +bindx_test$(EXEEXT): $(bindx_test_OBJECTS) $(bindx_test_DEPENDENCIES) + @rm -f bindx_test$(EXEEXT) + $(LINK) $(bindx_test_LDFLAGS) $(bindx_test_OBJECTS) $(bindx_test_LDADD) $(LIBS) +myftp$(EXEEXT): $(myftp_OBJECTS) $(myftp_DEPENDENCIES) + @rm -f myftp$(EXEEXT) + $(LINK) $(myftp_LDFLAGS) $(myftp_OBJECTS) $(myftp_LDADD) $(LIBS) +nagle_rcv$(EXEEXT): $(nagle_rcv_OBJECTS) $(nagle_rcv_DEPENDENCIES) + @rm -f nagle_rcv$(EXEEXT) + $(LINK) $(nagle_rcv_LDFLAGS) $(nagle_rcv_OBJECTS) $(nagle_rcv_LDADD) $(LIBS) +nagle_snd$(EXEEXT): $(nagle_snd_OBJECTS) $(nagle_snd_DEPENDENCIES) + @rm -f nagle_snd$(EXEEXT) + $(LINK) $(nagle_snd_LDFLAGS) $(nagle_snd_OBJECTS) $(nagle_snd_LDADD) $(LIBS) +peel_client$(EXEEXT): $(peel_client_OBJECTS) $(peel_client_DEPENDENCIES) + @rm -f peel_client$(EXEEXT) + $(LINK) $(peel_client_LDFLAGS) $(peel_client_OBJECTS) $(peel_client_LDADD) $(LIBS) +peel_server$(EXEEXT): $(peel_server_OBJECTS) $(peel_server_DEPENDENCIES) + @rm -f peel_server$(EXEEXT) + $(LINK) $(peel_server_LDFLAGS) $(peel_server_OBJECTS) $(peel_server_LDADD) $(LIBS) +sctp_darn$(EXEEXT): $(sctp_darn_OBJECTS) $(sctp_darn_DEPENDENCIES) + @rm -f sctp_darn$(EXEEXT) + $(LINK) $(sctp_darn_LDFLAGS) $(sctp_darn_OBJECTS) $(sctp_darn_LDADD) $(LIBS) +sctp_status$(EXEEXT): $(sctp_status_OBJECTS) $(sctp_status_DEPENDENCIES) + @rm -f sctp_status$(EXEEXT) + $(LINK) $(sctp_status_LDFLAGS) $(sctp_status_OBJECTS) $(sctp_status_LDADD) $(LIBS) +sctp_test$(EXEEXT): $(sctp_test_OBJECTS) $(sctp_test_DEPENDENCIES) + @rm -f sctp_test$(EXEEXT) + $(LINK) $(sctp_test_LDFLAGS) $(sctp_test_OBJECTS) $(sctp_test_LDADD) $(LIBS) +sctp_xconnect$(EXEEXT): $(sctp_xconnect_OBJECTS) $(sctp_xconnect_DEPENDENCIES) + @rm -f sctp_xconnect$(EXEEXT) + $(LINK) $(sctp_xconnect_LDFLAGS) $(sctp_xconnect_OBJECTS) $(sctp_xconnect_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bindx_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/myftp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nagle_rcv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nagle_snd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peel_client.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peel_server.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sctp_darn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sctp_status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sctp_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sctp_xconnect.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +install-pkgdocDATA: $(pkgdoc_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgdocdir)" || $(mkdir_p) "$(DESTDIR)$(pkgdocdir)" + @list='$(pkgdoc_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(pkgdocDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgdocdir)/$$f'"; \ + $(pkgdocDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgdocdir)/$$f"; \ + done + +uninstall-pkgdocDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgdoc_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pkgdocdir)/$$f'"; \ + rm -f "$(DESTDIR)$(pkgdocdir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/../.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdocdir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-pkgdocDATA + +install-exec-am: install-binPROGRAMS + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-info-am \ + uninstall-pkgdocDATA + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool clean-noinstPROGRAMS ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-pkgdocDATA \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-info-am uninstall-pkgdocDATA + + +# -*-makefile-*- +# +# Generate pre-parsed C code. +%.i: %.c + $(COMPILE) -E -c $^ -o $@ + +.PRECIOUS: %.i +%.ci: %.i + -grep -v -e "^#" -e "^ *$$" $^ | indent > $@ + mv -f $@ $^ + +# To modify this target for another language, just copy, paste and +# modify the target to generate directories.h. We depend on +# config.status and Makefile.dirs, as anything changed is going to be +# reflected there. + +# This is for generating the list in C/C++ +directories.h: $(top_builddir)/config.status $(top_srcdir)/Makefile.dirs + @rm -f $@ + @echo -n "Creating $@ ..." + @echo "#ifndef __$(subst .,_,$@)__" > $@ + @echo "# define __$(subst .,_,$@)__" >> $@ + @echo "" >> $@ + @echo -e $(foreach v,$(directories),$(shell echo 'D_$(v) \"$($v)\"\\n')) \ + | sed 's/^ *D_/# define D_/' >> $@ + @echo "#endif" >> $@ + @echo " done" + +$(top_builddir)/src/lib/libsctp.la: + make -C $(top_builddir)/src/lib libsctp.la + +$(top_builddir)/src/testlib/libsctputil.la: + make -C $(top_builddir)/src/testlib libsctputil.la +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/apps/bindx_test.c b/src/apps/bindx_test.c new file mode 100644 index 0000000..ec7632e --- /dev/null +++ b/src/apps/bindx_test.c @@ -0,0 +1,132 @@ + /* -*-c-*- + ** + ** sctp-tools: Another bindx test. + ** + ** $Id: bindx_test.c,v 1.1.1.1 2002/08/06 22:31:05 inaky Exp $ + ** + ** Distributed under the terms of the GPL v2.0 as described in + ** $top_srcdir/COPYING. + ** + ** (C) Copyright IBM Corp. 2003 + ** (C) 2002 Intel Corporation + ** Iñaky Pérez-González : + ** Sridhar Samudrala + */ + +#define _GNU_SOURCE /* GNU extensions */ + +#include /* malloc() */ +#include /* inet_pton() */ +#include +#include /* socket() */ +#include /* fprintf */ +#include /* sockaddr_in */ +#include /* close() */ +#include /* strchr() */ +#include /* bindx() */ + + /* Global stuff */ + +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif + + /*! Main function: initialize, setup, run the main loop + ** + ** + */ + +int main (int argc, char **argv) +{ + void *addr_buf, *buf_ptr; + void *addr_buf_size = 0; + size_t addrs, cnt; + int sd, result, port; + + if (argc < 3) { + fprintf(stderr, + "Usage: bindx_test PORT IPADDR1 [IPADDR2 [...]]\n"); + return 1; + } + + port = atoi(argv[1]); + printf("bindx_test: INFO: Port is %d\n", port); + + /* Allocate the maximum space for the specified no. of addresses. + * Assume all of them are v6 addresses. + */ + addr_buf = malloc((argc -2) * sizeof(struct sockaddr_in6)); + if (addr_buf == NULL) { + perror("bindx_test: ERROR: addr buf allocation failed"); + return 1; + } + + /* Get the addresses from the cmd line */ + addrs = 0; /* healthy address iterator [and total counter] */ + cnt = 2; /* argument iterator */ + buf_ptr = addr_buf; + while (cnt < argc) { + printf("bindx_test: INFO: Arg %d: %s", cnt, argv[cnt]); + fflush(stderr); + if (strchr(argv[cnt], ':')) { + struct sockaddr_in6 *sa6; + + sa6 = (struct sockaddr_in6 *)buf_ptr; + printf(" IPv6 address number %d", addrs); + sa6->sin6_family = AF_INET6; + sa6->sin6_port = port; + if (inet_pton(AF_INET6, argv[cnt], &sa6->sin6_addr)) { + addrs++; + addr_buf_size += sizeof(struct sockaddr_in6); + buf_ptr += sizeof(struct sockaddr_in6); + } else + printf(" error"); + } else if (strchr(argv[cnt], '.')) { + struct sockaddr_in *sa; + + sa = (struct sockaddr_in *)buf_ptr; + printf (" IPv4 address number %d", addrs); + sa->sin_family = AF_INET; + sa->sin_port = port; + if (inet_pton (AF_INET, argv[cnt], &sa->sin_addr)) { + addrs++; + addr_buf_size += sizeof(struct sockaddr_in); + buf_ptr += sizeof(struct sockaddr_in); + } else + printf (" error"); + } else + printf (" Unknown"); + putchar ('\n'); + cnt++; + } + + printf ("bindx_test: INFO: Got %d addrs\n", addrs); + + /* Create the socket */ + sd = socket(PF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP); + if (sd == -1) { + perror("bindx_test: ERROR: Cannot open socket"); + return 1; + } + + /* add all */ + result = sctp_bindx(sd, (struct sockaddr *)addr_buf, addrs, + SCTP_BINDX_ADD_ADDR); + if (result == -1) + perror("bindx_test: ERROR: bindx addition error"); + else { + printf("bindx_test: OK: bindx address addition\n"); + + /* remove all but the last */ + result = sctp_bindx(sd, (struct sockaddr *)addr_buf, addrs-1, + SCTP_BINDX_REM_ADDR); + if (result == -1) + perror("bindx_test: ERROR: bindx address removal"); + else + printf("bindx_test: OK: bindx address removal\n"); + } + + close(sd); + free(addr_buf); + return result; +} diff --git a/src/apps/myftp.c b/src/apps/myftp.c new file mode 100644 index 0000000..6b81098 --- /dev/null +++ b/src/apps/myftp.c @@ -0,0 +1,410 @@ +/* myftp - simple file transfer over sctp testing tool. + * Copyright (c) 2002 Intel Corp. + * + * This file is part of the LKSCTP kernel Implementation. This + * is a submission by Xingang Guo from the Intel Corporation while + * participating on the LKSCTP project. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Written or modified by: + * Xingang Guo + * Jon Grimm + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + */ +#include +#include +#include +#define _GNU_SOURCE +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include + +#define BUFSIZE 1024 +static char buffer[BUFSIZE]; +#define DUMP_CORE { char *diediedie = 0; *diediedie = 0; } + +typedef enum { COMMAND_NONE, COMMAND_RECV, COMMAND_SEND } command_t; + +/* These are the global options. */ +#define MAX_NUM_HOST 5 +static char *local_host[MAX_NUM_HOST]; +static int num_local_host = 0; +static int local_port = 4444; + +static int buffer_size = BUFSIZE; +static char *remote_host = NULL; +static int remote_port = 4444; +static command_t command = COMMAND_NONE; +static char *filename = NULL; +static int interactive = 0; +static unsigned long delay = 0; +static int verbose = 0; + +static void +usage(char *argv0) +{ + fprintf(stderr, "Usage: %s [options]\n",argv0); + fprintf(stderr, "Options:\n"); + fprintf(stderr, "\t--local, -H Specify local interface\n"); + fprintf(stderr, "\t--local-port, -P Specify local port (default 4444)\n"); + fprintf(stderr, "\t--remote, -h Specify interface on remote host\n"); + fprintf(stderr, "\t--remote-port, -p Specify remote port (default 4444)\n"); + fprintf(stderr, "\t--listen, -l Work in receiving mode\n"); + fprintf(stderr, "\t--send, -s Work in sending mode\n"); + fprintf(stderr, "\t--file, -f File to read or write,\n"); + fprintf(stderr, "\t--buffer, -b Buffer size. (default 1024 bytes)\n"); + fprintf(stderr, "\t by default use standard input/output.\n"); + fprintf(stderr, "\t--quick, -q Send packets continueously,\n"); + fprintf(stderr, "\t do not wait for key. Default wait.\n"); + fprintf(stderr, "\t--delay, -d Delay between consecutive sends (see --quick)\n"); + fprintf(stderr, "\t--verbose, -v In verbose mode, display the progress.\n"); + fprintf(stderr, "\n\t--help, Print this message.\n\n"); +} /* usage() */ + +static int parse_arguments(int argc, char *argv[]) +{ + int option_index = 0; + int c; + static struct option long_options[] = { + {"local", 1, 0, 1}, + {"local-port", 1, 0, 2}, + {"remote", 1, 0, 3}, + {"remote-port", 1, 0, 4}, + {"file", 1, 0, 5}, + {"delay", 1, 0, 6}, + {"buffer", 1, 0, 7}, + {"listen", 0, 0, 10}, + {"send", 0, 0, 11}, + {"quick", 0, 0, 12}, + {"verbose", 0, 0, 13}, + {"help", 0, 0, 99}, + {0, 0, 0, 0} + }; + + /* Parse the arguments. */ + while (1) { + c = getopt_long(argc, argv, "H:P:h:p:f:d:b:qlsv",long_options,&option_index); + if (c == -1) break; + + switch (c) { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) printf (" with arg %s", optarg); + printf ("\n"); + break; + case 1: /* local host */ + case 'H': + local_host[num_local_host++] = optarg; + break; + case 2: /* local port */ + case 'P': + local_port = atoi(optarg); + break; + case 3: /* remote host */ + case 'h': + remote_host = optarg; + break; + case 4: /* remote port */ + case 'p': + remote_port = atoi(optarg); + break; + case 5: + case 'f': + filename = optarg; + break; + + case 6: + case 'd': + delay = strtoul(optarg,NULL,10); + printf("delay is %ld usec\n",delay); + break; + + case 7: + case 'b': + buffer_size = atoi(optarg); + if ( buffer_size > BUFSIZE ) { + buffer_size = BUFSIZE; + fprintf(stderr,"Warning, buffer size too large, set to %d\n",buffer_size); + } + case 12: + case 'q': interactive = 0; break; + + case 13: + case 'v': verbose = 1; break; + /* COMMANDS */ + case 10: /* listen */ + case 'l': + if (command) { + fprintf(stderr, "%s: pick ONE of listen or send\n", argv[0]); + return 1; + } + else command = COMMAND_RECV; + break; + + case 11: /* send */ + case 's': + if (command) { + fprintf(stderr, "%s: pick ONE of listen or send\n", argv[0]); + return 2; + } else command = COMMAND_SEND; + break; + + case '?': + case 99: + usage(argv[0]); + return 3; + break; + + default: + printf ("%s: unrecognized option 0%c\n", argv[0], c); + usage(argv[0]); + return 4; + } + } + + if (optind < argc) { + fprintf(stderr, "%s: non-option arguments are illegal: ", argv[0]); + while (optind < argc) fprintf(stderr, "%s ", argv[optind++]); + fprintf(stderr, "\n"); + usage(argv[0]); + return 5; + } + + + if (0 == num_local_host) { + fprintf(stderr, "%s: You MUST provide a local host.\n", argv[0]); + usage(argv[0]); + return 6; + } + + if ( filename == NULL && command == COMMAND_SEND) + fprintf(stderr,"%s: Use standard input to send\n",argv[0]); + + if ( filename == NULL && command == COMMAND_RECV ) + fprintf(stderr,"%s: Use standard output to write\n",argv[0]); + + return 0; +} /* parse_arguments() */ + +static void +emsg(char *prog,char *s) +{ + if ( prog != NULL ) fprintf(stderr,"%s: ",prog); + perror(s); + fflush(stdout); + //DUMP_CORE; + + exit(-1); +} + +static int build_endpoint(char *argv0) +{ + int retval,i; + + /* Create the local endpoint. */ + if ( (retval = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0 ) { + emsg(argv0,"socket"); + exit(retval); + } + + for ( i = 0;i < num_local_host;i++ ) { + struct hostent *hst; + struct sockaddr_in laddr; + + /* Get the transport address for the local host name. */ + fprintf(stderr,"Hostname %d is %s\n",i+1,local_host[i]); + if ( (hst = gethostbyname(local_host[i])) == NULL ) { + fprintf(stderr, "%s: bad hostname: %s\n", argv0, local_host[i]); + exit(1); + } + memcpy(&laddr.sin_addr, hst->h_addr_list[0],sizeof(laddr.sin_addr)); + laddr.sin_port = htons(local_port); + laddr.sin_family = AF_INET; + + /* Bind this socket to the test port. */ + if ( bind(retval, (struct sockaddr *)&laddr, sizeof(laddr)) ) { + emsg(argv0,"bind"); + exit(-1); + } + } + + fprintf(stderr,"Endpoint built.\n"); + + return retval; +} /* build_endpoint() */ + +/* Convenience structure to determine space needed for cmsg. */ +typedef union { + struct sctp_initmsg init; + struct sctp_sndrcvinfo sndrcvinfo; +} _sctp_cmsg_data_t; + + +/* Listen on the socket, printing out anything that arrives. */ +static void +command_recv(char *argv0, int sk) +{ + struct msghdr inmessage; + char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))]; + struct iovec iov; + int ret; + int fd; + int ct; + + listen(sk, 1); + /* Initialize inmessage with enough space for DATA... */ + memset(&inmessage, 0, sizeof(inmessage)); + iov.iov_base = buffer; + iov.iov_len = buffer_size; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + /* or a control message. */ + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + + /* creat a file */ + if ( filename == NULL ) fd = 1; + else if ( (fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE)) == -1 ) + emsg(argv0,"open"); + + fprintf(stderr,"%s Receiving...\n", argv0); + /* Get the messages sent */ + ct = 0; + while ( (ret = recvmsg(sk, &inmessage, MSG_WAITALL)) >= 0 ) { + if ( verbose ) + fprintf(stderr,"%s-%d received %d bytes\n", + argv0, ++ct, ret); + if ( !(inmessage.msg_flags & MSG_NOTIFICATION) ) { + //printf("%s write %d bytes\n",argv0,ret); + if ( write(fd,buffer,ret) != ret ) emsg(argv0,"write"); + } else { + union sctp_notification *sn; + sn = (union sctp_notification *)iov.iov_base; + if ((sn->sn_header.sn_type == SCTP_ASSOC_CHANGE) && + (sn->sn_assoc_change.sac_state + == SCTP_SHUTDOWN_COMP)) + break; + } + + } + + if ( ret < 0 ) emsg(argv0,"recvmsg"); + + close(fd); + close(sk); +} /* command_recv() */ + +/* Read lines from stdin and send them to the socket. */ +static void +command_send(char *argv0, int sk) +{ + struct msghdr outmsg; + struct iovec iov; + struct hostent *hst; + struct sockaddr_in remote_addr; + int fd; + int msglen; + int ct; + + /* Set up the destination. */ + hst = gethostbyname(remote_host); + if (hst == NULL || hst->h_length < 1) { + fprintf(stderr, "%s: bad hostname: %s\n", argv0, remote_host); + exit(1); + } + memcpy(&remote_addr.sin_addr, hst->h_addr_list[0], sizeof(remote_addr.sin_addr)); + remote_addr.sin_port = htons(remote_port); + remote_addr.sin_family = AF_INET; + + /* Initialize the message struct we use to pass messages to + * the remote socket. + */ + iov.iov_base = buffer; + iov.iov_len = buffer_size; + outmsg.msg_iov = &iov; + outmsg.msg_iovlen = 1; + outmsg.msg_control = NULL; + outmsg.msg_controllen = 0; + outmsg.msg_name = &remote_addr; + outmsg.msg_namelen = sizeof(remote_addr); + + /* open the file */ + if ( filename == NULL ) fd = 0; + else if ( (fd = open(filename,O_RDONLY)) == -1 ) emsg(argv0,"open"); + + fprintf(stderr,"%s ready to send...\n", argv0); + ct = 0; + while ( (msglen = read(fd,buffer,buffer_size)) > 0 ) { + /* Send to our neighbor. */ + iov.iov_len = msglen; + if ( sendmsg(sk, &outmsg, 0) != msglen ) emsg(argv0,"sendmsg"); + if ( verbose ) fprintf(stderr,"%s-%d send %d bytes\n",argv0,++ct,msglen); + if ( interactive && fd != 1 ) + getchar(); + // no flow control? no problem, make it slow + else if ( delay > 0 ) + usleep(delay); + } while ( msglen > 0 ); + + close(fd); + close(sk); +} /* command_send() */ + +int main(int argc, char *argv[]) +{ + int ret; + + if (( ret = parse_arguments(argc, argv) )) return ret; + + switch(command) { + case COMMAND_NONE: + fprintf(stderr, "%s: Please specify a command.\n", argv[0]); + break; + case COMMAND_RECV: + command_recv(argv[0],build_endpoint(argv[0])); + break; + case COMMAND_SEND: + command_send(argv[0],build_endpoint(argv[0])); + break; + default: + fprintf(stderr, "%s: illegal command %d\n", argv[0], command); + } /* switch(command) */ + + return 0; +} diff --git a/src/apps/nagle_rcv.c b/src/apps/nagle_rcv.c new file mode 100644 index 0000000..47695e4 --- /dev/null +++ b/src/apps/nagle_rcv.c @@ -0,0 +1,248 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2002, 2003 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2001 Intel Corp. + * Copyright (c) 2001 Nokia, Inc. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Ardelle Fan + * Sridhar Samudrala + */ + +/* This is a receiver for the performance test to verify Nagle's algorithm. + * It creates a socket, binds to a address specified as a parameter and + * goes into a receive loop waiting for 1,000,000 packets. Then it calculates + * the packet receive rate, i.e. packets/second. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 1; +int TST_CNT = 0; + +void +usage(char *progname) +{ + fprintf(stderr, "Usage: %s -H hostname [-P port]\n", progname); + fprintf(stderr, " -H, --local\t\t local hostname,\n"); + fprintf(stderr, " -P, --local-port\t local port,\n"); +} + +int +main(int argc, char *argv[]) +{ + int sk, i; + struct hostent *hst; + sockaddr_storage_t host; + sockaddr_storage_t msgname; + struct iovec iov; + struct msghdr inmessage; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + int error; + int pf_class, af_family; + char *big_buffer; + char *local_host = NULL; + int local_port = SCTP_TESTPORT_1; + int option_index = 0; + time_t from, to; + int bytes_received = 0; + int c; + static struct option long_options[] = { + {"local", 1, 0, 1}, + {"local-port", 1, 0, 2}, + {0, 0, 0, 0} + }; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Parse the arguments. */ + while (1) { + c = getopt_long (argc, argv, "H:P:", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 0: + printf("option %s", long_options[option_index].name); + if (optarg) { + printf(" with arg %s", optarg); + } + printf("\n"); + break; + case 1: /* local host */ + case 'H': + local_host = optarg; + break; + case 2: /* local port */ + case 'P': + local_port = atoi(optarg); + break; + case '?': + usage(argv[0]); + exit(0); + + default: + printf ("%s: unrecognized option 0%c\n", argv[0], c); + usage(argv[0]); + exit(1); + } + } + + if (optind < argc) + { + fprintf(stderr, "%s: non-option arguments are illegal: ", + argv[0]); + while (optind < argc) + fprintf(stderr, "%s ", argv[optind++]); + fprintf (stderr, "\n"); + usage(argv[0]); + exit(1); + } + + if (!local_host) { + fprintf(stderr, "%s: : option -H, --local is required\n", + argv[0]); + usage(argv[0]); + exit(1); + } + + /* Set some basic values which depend on the address family. */ +#if TEST_V6 + hst = gethostbyname2(local_host, AF_INET6); + if (hst == NULL || hst->h_length < 1) { + fprintf(stderr, "%s: bad hostname: %s\n", argv[0], local_host); + exit(1); + } + pf_class = PF_INET6; + af_family = AF_INET6; + + host.v6.sin6_family = AF_INET6; + memcpy(&host.v6.sin_addr, hst->h_addr_list[0], hst->h_length); + host.v6.sin6_port = htons(local_port); + +#else + hst = gethostbyname(local_host); + if (hst == NULL || hst->h_length < 1) { + fprintf(stderr, "%s: bad hostname: %s\n", argv[0], local_host); + exit(1); + } + pf_class = PF_INET; + af_family = AF_INET; + + host.v4.sin_family = AF_INET; + memcpy(&host.v4.sin_addr, hst->h_addr_list[0], hst->h_length); + host.v4.sin_port = htons(local_port); + +#endif /* TEST_V6 */ + + /* Create the endpoint which will talk to nagle_snd. */ + sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(sk); + + /* Bind the sockets to the test port. */ + test_bind(sk, &host.sa, sizeof(host)); + + /* Mark sk as being able to accept new associations. */ + test_listen(sk, 1); + + printf("Listening on port:%d\n", local_port); + + /* Initialize inmessage for receives. */ + memset(&inmessage, 0, sizeof(inmessage)); + big_buffer = test_malloc(REALLY_BIG); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + inmessage.msg_name = &msgname; + inmessage.msg_namelen = sizeof(msgname); + memset(&msgname, 0, sizeof(msgname)); + + /* Get the communication up message on sk. */ + error = test_recvmsg(sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + + printf("Established connection with "); + if (AF_INET == msgname.sa.sa_family) + printf("%d.%d.%d.%d(%d)\n", NIPQUAD(msgname.v4.sin_addr), + ntohs(msgname.v4.sin_port)); + if (AF_INET6 == msgname.sa.sa_family) + printf("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x(%d)\n", + NIP6(msgname.v6.sin6_addr), ntohs(msgname.v6.sin6_port)); + + time(&from); + for (i=0; i<1000000; i++) { + inmessage.msg_controllen = sizeof(incmsg); + inmessage.msg_namelen = sizeof(msgname); + error = test_recvmsg(sk, &inmessage, MSG_WAITALL); + if (inmessage.msg_flags & MSG_NOTIFICATION) + break; + printf("Received %d bytes of data\n", error); + bytes_received += error; + } + time(&to); + + printf("\t%d messages(%d bytes) successfully received in %ld " + "seconds.\n", i, bytes_received, to - from); + printf("The receive rate is %ld bytes/second\n", + bytes_received/(to - from)); + + /* Shut down the link. */ + error = 0; + close(sk); + + return 0; +} diff --git a/src/apps/nagle_snd.c b/src/apps/nagle_snd.c new file mode 100644 index 0000000..1340fa7 --- /dev/null +++ b/src/apps/nagle_snd.c @@ -0,0 +1,367 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2002, 2003 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2001 Intel Corp. + * Copyright (c) 2001 Nokia, Inc. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Ardelle Fan + * Sridhar Samudrala + */ + +/* This is a receiver for the performance test to verify Nagle's algorithm. + * It creates a socket, binds to a address specified as a parameter and + * sends 1,000,000 packets to a specified target. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 1; +int TST_CNT = 0; + +void +usage(char *argv0) +{ + fprintf(stderr, "Usage: %s -H localhost [-P localport] " + "-h remotehost [-p remoteport]\n" + "\t\t[-S msgsize] [-I interval] -N\n" + " -H, --local\t\tspecify one of the local addresses,\n" + " -P, --local-port\tspecify the port number for local addresses,\n" + " -h, --remote\t\tspecify one of the remote addresses,\n" + " -p, --remote-port\tspecify the port number for remote addresses,\n" + " -S, --size\t\tspecify the size(byte) of the sending message,\n" + " -I, --interval\t\tspecify the interval(second) that sending messages at,\n" + " -N, --nodelay\t\tspecify whether the SCTP allows Nagle's algorithm\n", + argv0); +} + +int +main(int argc, char *argv[]) +{ + int sk, i; + struct hostent *hst, *tgt; + sockaddr_storage_t host, target; + sockaddr_storage_t msgname; + struct iovec iov; + struct msghdr inmessage; + struct msghdr outmessage; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + struct iovec out_iov; + char *message; + int error, bytes_sent; + int pf_class, af_family; + sctp_assoc_t associd; + uint32_t ppid; + uint32_t stream; + char *remote_host = NULL; + int remote_port = SCTP_TESTPORT_1; + char *local_host = NULL; + int local_port = SCTP_TESTPORT_2; + int size = 1; + int interval = 0; + int nodelay = 0; + int option_index = 0; + char *big_buffer; + int c; + static struct option long_options[] = { + {"local", 1, 0, 1}, + {"local-port", 1, 0, 2}, + {"remote", 1, 0, 3}, + {"remote-port", 1, 0, 4}, + {"size", 1, 0, 5}, + {"interval", 1, 0, 6}, + {"nodelay", 0, 0, 10}, + {0, 0, 0, 0} + }; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Parse the arguments. */ + while (1) { + c = getopt_long (argc, argv, "H:P:h:p:S:I:N", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 0: + printf("option %s", long_options[option_index].name); + if (optarg) { + printf(" with arg %s", optarg); + } + printf("\n"); + break; + case 1: /* local host */ + case 'H': + local_host = optarg; + break; + case 2: /* local port */ + case 'P': + local_port = atoi(optarg); + break; + case 3: /* remote host */ + case 'h': + remote_host = optarg; + break; + case 4: /* remote port */ + case 'p': + remote_port = atoi(optarg); + break; + case 5: /* size */ + case 'S': + size = atoi(optarg); + break; + case 6: /* interval */ + case 'I': + interval = atoi(optarg); + break; + case 10: /* nodelay */ + case 'N': + nodelay = 1; + break; + case '?': + usage(argv[0]); + exit(0); + + default: + printf ("%s: unrecognized option 0%c\n", + argv[0], c); + usage(argv[0]); + exit(1); + } + } + + if (optind < argc) + { + fprintf(stderr, "%s: non-option arguments are illegal: ", + argv[0]); + while (optind < argc) + fprintf(stderr, "%s ", argv[optind++]); + fprintf (stderr, "\n"); + usage(argv[0]); + exit(1); + } + + if (!local_host || !remote_host) { + fprintf(stderr, "%s: : option --local and --remote are required\n", + argv[0]); + usage(argv[0]); + exit(1); + } + + /* Set some basic values which depend on the address family. */ +#if TEST_V6 + hst = gethostbyname2(local_host, AF_INET6); + if (hst == NULL || hst->h_length < 1) { + fprintf(stderr, "%s: bad hostname: %s\n", argv[0], local_host); + exit(1); + } + host.v6.sin6_family = AF_INET6; + memcpy(&host.v6.sin_addr, hst->h_addr_list[0], hst->h_length); + host.v6.sin6_port = htons(local_port); + + tgt = gethostbyname2(remote_host, AF_INET6); + if (tgt == NULL || tgt->h_length < 1) { + fprintf(stderr, "%s: bad hostname: %s\n", argv[0], remote_host); + exit(1); + } + target.v6.sin6_family = AF_INET6; + memcpy(&target.v6.sin_addr, tgt->h_addr_list[0], tgt->h_length); + target.v6.sin6_port = htons(remote_port); + + pf_class = PF_INET6; + af_family = AF_INET6; + +#else + hst = gethostbyname(local_host); + if (hst == NULL || hst->h_length < 1) { + fprintf(stderr, "%s: bad hostname: %s\n", argv[0], local_host); + exit(1); + } + + host.v4.sin_family = AF_INET; + memcpy(&host.v4.sin_addr, hst->h_addr_list[0], hst->h_length); + host.v4.sin_port = htons(local_port); + + tgt = gethostbyname(remote_host); + if (tgt == NULL || tgt->h_length < 1) { + fprintf(stderr, "%s: bad hostname: %s\n", argv[0], remote_host); + exit(1); + } + target.v4.sin_family = AF_INET; + memcpy(&target.v4.sin_addr, tgt->h_addr_list[0], tgt->h_length); + target.v4.sin_port = htons(remote_port); + + pf_class = PF_INET; + af_family = AF_INET; + +#endif /* TEST_V6 */ + + sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(sk); + + test_setsockopt(sk, SCTP_NODELAY, &nodelay, sizeof(int)); + + /* Bind the sockets to the test port. */ + test_bind(sk, &host.sa, sizeof(host)); + + /* Mark sk as being able to accept new associations. */ + test_listen(sk, 1); + + /* Build up a msghdr structure we can use for all sending. */ + outmessage.msg_name = ⌖ + outmessage.msg_namelen = sizeof(target); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid = rand(); /* Choose an arbitrary value. */ + stream = 1; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + + message = test_malloc((size + 1) * sizeof(u_int8_t)); + + for(i=0; i + 10 < size; i+= 10) + strncpy(message+i, "1234567890", 10); + strncpy(message+i, "1234567890", size-i); + *(message+size) = 0; + + outmessage.msg_iov->iov_base = message; + outmessage.msg_iov->iov_len = size + 1; + + printf("Initiating connection with %s:%d...\n", remote_host, + remote_port); + + /* Send the first message. This will create the association. */ + bytes_sent = test_sendmsg(sk, &outmessage, 0, size+1); + + memset(&inmessage, 0, sizeof(inmessage)); + big_buffer = test_malloc(REALLY_BIG); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + inmessage.msg_name = &msgname; + inmessage.msg_namelen = sizeof(msgname); + memset(&msgname, 0, sizeof(msgname)); + + /* Get the communication up message on sk. */ + error = test_recvmsg(sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + associd = ((struct sctp_assoc_change *)iov.iov_base)->sac_assoc_id; + + printf("Established connection with "); + if (AF_INET == msgname.sa.sa_family) + printf("%d.%d.%d.%d(%d)\n", NIPQUAD(msgname.v4.sin_addr), + ntohs(msgname.v4.sin_port)); + if (AF_INET6 == msgname.sa.sa_family) + printf("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x(%d)\n", + NIP6(msgname.v6.sin6_addr), ntohs(msgname.v6.sin6_port)); + + printf("Sending data to receiver...\n"); + + for (i=1; i<1000000; i++) { + + if (interval) + sleep(interval); + + outmessage.msg_name = ⌖ + outmessage.msg_namelen = sizeof(target); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + + ppid++; + + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + sinfo->sinfo_assoc_id = associd; + + outmessage.msg_iov->iov_base = message; + outmessage.msg_iov->iov_len = size + 1; + bytes_sent = test_sendmsg(sk, &outmessage, 0, size+1); + } + + printf("\n\n\t\tComplete all the data sendings to receiver...\n\n\n"); + + error = 0; + close(sk); + + free(message); + + /* Indicate successful completion. */ + return 0; + +} diff --git a/src/apps/peel_client.c b/src/apps/peel_client.c new file mode 100644 index 0000000..ede3fbc --- /dev/null +++ b/src/apps/peel_client.c @@ -0,0 +1,674 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2003 + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * In addition: + * + * Copyright (c) 2003 Cisco + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * a) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * b) Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * c) Neither the name of Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Randall Stewart + * Sridhar Samudrala + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef __NetBSD__ +#include +#endif + +#define SCTP_CRC32C_POLY 0x1EDC6F41 +#define SCTP_CRC32C(c,d) (c=(c>>8)^sctp_crc_c[(c^(d))&0xFF]) +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Copyright 2001, D. Otis. Use this program, code or tables */ +/* extracted from it, as desired without restriction. */ +/* */ +/* 32 Bit Reflected CRC table generation for SCTP. */ +/* To accommodate serial byte data being shifted out least */ +/* significant bit first, the table's 32 bit words are reflected */ +/* which flips both byte and bit MS and LS positions. The CRC */ +/* is calculated MS bits first from the perspective of the serial*/ +/* stream. The x^32 term is implied and the x^0 term may also */ +/* be shown as +1. The polynomial code used is 0x1EDC6F41. */ +/* Castagnoli93 */ +/* x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+ */ +/* x^11+x^10+x^9+x^8+x^6+x^0 */ +/* Guy Castagnoli Stefan Braeuer and Martin Herrman */ +/* "Optimization of Cyclic Redundancy-Check Codes */ +/* with 24 and 32 Parity Bits", */ +/* IEEE Transactions on Communications, Vol.41, No.6, June 1993 */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static unsigned char buffer1[4100]; +static unsigned char buffer2[4100]; +static unsigned char buffer3[4100]; +static unsigned char buffer4[4100]; +static struct sockaddr_in bindto,got,to; +static socklen_t len; + +unsigned long sctp_crc_c[256] = { + 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, + 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, + 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, + 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, + 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, + 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, + 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, + 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, + 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, + 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, + 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, + 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, + 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, + 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, + 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, + 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, + 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, + 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, + 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, + 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, + 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, + 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, + 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, + 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, + 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, + 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, + 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, + 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, + 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, + 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, + 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, + 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, + 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, + 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, + 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, + 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, + 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, + 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, + 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, + 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, + 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, + 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, + 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, + 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, + 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, + 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, + 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, + 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, + 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, + 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, + 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, + 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, + 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, + 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, + 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, + 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, + 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, + 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, + 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, + 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, + 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, + 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, + 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, + 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L, +}; + +u_int32_t +update_crc32(u_int32_t crc32, + unsigned char *buffer, + unsigned int length) +{ + int i; + for (i = 0; i < length; i++) { + SCTP_CRC32C(crc32, buffer[i]); + } + return (crc32); +} + +u_int32_t +sctp_csum_finalize(u_int32_t crc32) +{ + u_int32_t result; +#if BYTE_ORDER == BIG_ENDIAN + u_int8_t byte0, byte1, byte2, byte3; +#endif + /* Complement the result */ + result = ~crc32; +#if BYTE_ORDER == BIG_ENDIAN + /* + * For BIG-ENDIAN.. aka Motorola byte order the result is in + * little-endian form. So we must manually swap the bytes. Then + * we can call htonl() which does nothing... + */ + byte0 = result & 0x000000ff; + byte1 = (result >> 8) & 0x000000ff; + byte2 = (result >> 16) & 0x000000ff; + byte3 = (result >> 24) & 0x000000ff; + result = ((byte0 << 24) | + (byte1 << 16) | + (byte2 << 8) | + byte3); + crc32 = htonl(result); +#else + /* + * For INTEL platforms the result comes out in network order. + * No htonl is required or the swap above. So we optimize out + * both the htonl and the manual swap above. + */ + crc32 = result; +#endif + return (crc32); +} + +static u_int32_t at = 468700; + +void +prepare_buffers(void) +{ + /* Prepare buffers */ + u_int32_t temp,*p; + int i; + + p = (u_int32_t *)buffer1; + for(i=0;i<(sizeof(buffer1)/4);i++){ + *p = at; + at++; + p++; + } + /* backup over the last int */ + p--; + *p = 0; + temp = 0xffffffff; + temp = update_crc32(temp,buffer1,(sizeof(buffer1)-4)); + *p = sctp_csum_finalize(temp); + + p = (u_int32_t *)buffer2; + for(i=0;i<(sizeof(buffer2)/4);i++){ + *p = at; + at++; + p++; + } + p--; + *p = 0; + temp = 0xffffffff; + temp = update_crc32(temp,buffer2,(sizeof(buffer2)-4)); + *p = sctp_csum_finalize(temp); + + p = (u_int32_t *)buffer3; + for(i=0;i<(sizeof(buffer3)/4);i++){ + *p = at; + at++; + p++; + } + p--; + *p = 0; + temp = 0xffffffff; + temp = update_crc32(temp,buffer3,(sizeof(buffer3)-4)); + *p = sctp_csum_finalize(temp); + + p = (u_int32_t *)buffer4; + for(i=0;i<(sizeof(buffer4)/4);i++){ + *p = at; + at++; + p++; + } + p--; + *p = 0; + temp = 0xffffffff; + temp = update_crc32(temp,buffer4,(sizeof(buffer4)-4)); + *p = sctp_csum_finalize(temp); +} + +static int +my_handle_notification(int fd,char *notify_buf) { + union sctp_notification *snp; + struct sctp_assoc_change *sac; + struct sctp_paddr_change *spc; + struct sctp_remote_error *sre; + struct sctp_send_failed *ssf; + struct sctp_shutdown_event *sse; + int asocDown; + char *str; + char buf[256]; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + + asocDown = 0; + snp = (union sctp_notification *)notify_buf; + switch(snp->sn_header.sn_type) { + case SCTP_ASSOC_CHANGE: + sac = &snp->sn_assoc_change; + switch(sac->sac_state) { + + case SCTP_COMM_UP: + str = "COMMUNICATION UP"; + break; + case SCTP_COMM_LOST: + str = "COMMUNICATION LOST"; + asocDown = 1; + break; + case SCTP_RESTART: + str = "RESTART"; + break; + case SCTP_SHUTDOWN_COMP: + str = "SHUTDOWN COMPLETE"; + asocDown = 1; + break; + case SCTP_CANT_STR_ASSOC: + str = "CANT START ASSOC"; + printf("EXIT:SCTP_ASSOC_CHANGE: %s, assoc=%xh\n", str, + (uint32_t)sac->sac_assoc_id); + exit(0); + break; + default: + str = "UNKNOWN"; + } /* end switch(sac->sac_state) */ + printf("SCTP_ASSOC_CHANGE: %s, assoc=%xh\n", str, + (uint32_t)sac->sac_assoc_id); + break; + case SCTP_PEER_ADDR_CHANGE: + spc = &snp->sn_paddr_change; + switch(spc->spc_state) { + case SCTP_ADDR_AVAILABLE: + str = "ADDRESS AVAILABLE"; + break; + case SCTP_ADDR_UNREACHABLE: + str = "ADDRESS UNAVAILABLE"; + break; + case SCTP_ADDR_REMOVED: + str = "ADDRESS REMOVED"; + break; + case SCTP_ADDR_ADDED: + str = "ADDRESS ADDED"; + break; + case SCTP_ADDR_MADE_PRIM: + str = "ADDRESS MADE PRIMARY"; + break; + default: + str = "UNKNOWN"; + } /* end switch */ + sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr; + if (sin6->sin6_family == AF_INET6) { + inet_ntop(AF_INET6, (char*)&sin6->sin6_addr, buf, sizeof(buf)); + } else { + sin = (struct sockaddr_in *)&spc->spc_aaddr; + inet_ntop(AF_INET, (char*)&sin->sin_addr, buf, sizeof(buf)); + } + printf("SCTP_PEER_ADDR_CHANGE: %s, addr=%s, assoc=%xh\n", str, + buf, (uint32_t)spc->spc_assoc_id); + break; + case SCTP_REMOTE_ERROR: + sre = &snp->sn_remote_error; + printf("SCTP_REMOTE_ERROR: assoc=%xh\n", + (uint32_t)sre->sre_assoc_id); + break; + case SCTP_SEND_FAILED: + ssf = &snp->sn_send_failed; + printf("SCTP_SEND_FAILED: assoc=%xh\n", + (uint32_t)ssf->ssf_assoc_id); + break; + case SCTP_ADAPTATION_INDICATION: + { + struct sctp_adaptation_event *ae; + ae = &snp->sn_adaptation_event; + printf("\nSCTP_adaptation_indication bits:0x%x\n", + (u_int)ae->sai_adaptation_ind); + } + break; + case SCTP_PARTIAL_DELIVERY_EVENT: + { + struct sctp_pdapi_event *pdapi; + pdapi = &snp->sn_pdapi_event; + printf("SCTP_PD-API event:%u\n", + pdapi->pdapi_indication); + if(pdapi->pdapi_indication == 0){ + printf("PDI- Aborted\n"); + } + } + break; + + case SCTP_SHUTDOWN_EVENT: + sse = &snp->sn_shutdown_event; + printf("SCTP_SHUTDOWN_EVENT: assoc=%xh\n", + (uint32_t)sse->sse_assoc_id); + break; + default: + printf("Unknown notification event type=%xh\n", + snp->sn_header.sn_type); + } /* end switch(snp->sn_type) */ + if(asocDown){ + printf("Bring association back up\n"); + len = sizeof(to); + if(connect(fd,(struct sockaddr *)&to,len) == -1){ + printf("Sorry connect fails %d\n",errno); + } + return(1); + } + return(0); +} + + + +int +my_sctpReadInput(int fd) +{ + /* receive some number of datagrams and + * act on them. + */ + struct sctp_sndrcvinfo *s_info; + int sz,i,disped; + struct msghdr msg; + struct iovec iov[2]; + unsigned char from[200]; + char readBuffer[65535]; + char controlVector[65535]; + + disped = i = 0; + + s_info = NULL; + iov[0].iov_base = readBuffer; + iov[0].iov_len = sizeof(readBuffer); + iov[1].iov_base = NULL; + iov[1].iov_len = 0; + msg.msg_name = (caddr_t)from; + msg.msg_namelen = sizeof(from); + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_control = (caddr_t)controlVector; + msg.msg_controllen = sizeof(controlVector); + errno = 0; + sz = recvmsg(fd,&msg,0); + if(sz <= 0){ + printf("Read returns %d errno:%d control len is %d msgflg:%x\n", + sz,errno, + msg.msg_controllen,msg.msg_flags); + } + if (msg.msg_flags & MSG_NOTIFICATION) { + return(my_handle_notification(fd,readBuffer)); + }else{ + printf("Huh, I got data?.. ignored (%d bytes)\n",sz); + return(0); + } +} + + +int +clear_fds(int fd,int fd1) +{ + int felldown; + int max,notdone; + fd_set readfds,writefds,exceptfds; + struct timeval tv; + memset(&tv,0,sizeof(tv)); + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_ZERO(&exceptfds); + felldown = 0; + FD_SET(fd,&readfds); + FD_SET(fd1,&readfds); + if(fd > fd1){ + max = fd + 1; + }else{ + max = fd1 + 1; + } + notdone = 1; + while(notdone){ + select(max,&readfds,&writefds,&exceptfds,&tv); + notdone = 0; + if(FD_ISSET(fd,&readfds)){ + notdone++; + printf("clearing fd:%d\n",fd); + felldown += my_sctpReadInput(fd); + notdone = 1; + } + if(FD_ISSET(fd1,&readfds)){ + notdone++; + printf("clearing fd1:%d\n",fd1); + felldown += my_sctpReadInput(fd1); + } + } + return(felldown); +} + +void +process_out_data(int fd,int fd1) +{ + int notdone,x,ret; + while(1){ + /* Prepare the buffers */ + prepare_buffers(); + /* send out the 4 buffers */ + ret = sendto(fd,buffer1,sizeof(buffer1),0, + (struct sockaddr *)&to,sizeof(to)); + if(ret < sizeof(buffer1)){ + printf("Gak1, error:%d ret:%d\n",errno,ret); + } + + ret = sendto(fd1,buffer2,sizeof(buffer1),0, + (struct sockaddr *)&to,sizeof(to)); + if(ret < sizeof(buffer2)){ + printf("Gak2, error:%d ret:%d\n",errno,ret); + } + + + ret = sendto(fd,buffer3,sizeof(buffer1),0, + (struct sockaddr *)&to,sizeof(to)); + if(ret < sizeof(buffer3)){ + printf("Gak3, error:%d ret:%d\n",errno,ret); + } + + + ret = sendto(fd1,buffer4,sizeof(buffer1),0, + (struct sockaddr *)&to,sizeof(to)); + if(ret < sizeof(buffer4)){ + printf("Gak4, error:%d ret:%d\n",errno,ret); + } + + /* now wait until we get a assoc failing */ + notdone = 1; + while(notdone){ + x = clear_fds(fd,fd1); + if(x){ + notdone = 0; + } + sleep(1); + } + } +} + +int +main(int argc, char **argv) +{ + int i,fd,fd1; + char *addr=NULL; + uint16_t port=0; + int protocol_touse = IPPROTO_SCTP; + struct sctp_event_subscribe event; + + while((i= getopt(argc,argv,"p:h:")) != EOF){ + switch(i){ + case 'h': + addr = optarg; + break; + case 'p': + port = (uint16_t)strtol(optarg,NULL,0); + break; + }; + } + memset(&to,0,sizeof(to)); + if((addr == NULL) || (port == 0)){ + printf("Usage: %s -h addr -p port\n", argv[0]); + return(-1); + } + if(inet_pton(AF_INET, addr, (void *) &to.sin_addr)){ + //to.sin_len = sizeof(to); + to.sin_family = AF_INET; + printf("port selected is %d\n",port); + printf("addr %x\n",(u_int)ntohl(to.sin_addr.s_addr)); + to.sin_port = htons(port); + }else{ + printf("Can't translate the address\n"); + return(-1); + } + /**********************socket 1 *******************/ + fd = socket(AF_INET, SOCK_SEQPACKET, protocol_touse); + if(fd == -1){ + printf("can't open socket:%d\n",errno); + return(-1); + } + memset(&bindto,0,sizeof(bindto)); + //len = bindto.sin_len = sizeof(bindto); + len = sizeof(bindto); + bindto.sin_family = AF_INET; + bindto.sin_port = 0; + if(bind(fd,(struct sockaddr *)&bindto, len) < 0){ + printf("can't bind a socket:%d\n",errno); + close(fd); + return(-1); + } + if(getsockname(fd,(struct sockaddr *)&got,&len) < 0){ + printf("get sockname failed err:%d\n",errno); + close(fd); + return(-1); + } + printf("fd uses port %d\n",ntohs(got.sin_port)); + + /**********************socket 2 *******************/ + fd1 = socket(AF_INET, SOCK_SEQPACKET, protocol_touse); + if(fd1 == -1){ + printf("can't open socket:%d\n",errno); + close(fd); + return(-1); + } + memset(&bindto,0,sizeof(bindto)); + //len = bindto.sin_len = sizeof(bindto); + len = sizeof(bindto); + bindto.sin_family = AF_INET; + bindto.sin_port = 0; + if(bind(fd1,(struct sockaddr *)&bindto, len) < 0){ + printf("can't bind a socket:%d\n",errno); + close(fd); + close(fd1); + return(-1); + } + if(getsockname(fd1,(struct sockaddr *)&got,&len) < 0){ + printf("get sockname failed err:%d\n",errno); + close(fd); + close(fd1); + return(-1); + } + printf("fd1 uses port %d\n",ntohs(got.sin_port)); + + /* enable all event notifications */ + event.sctp_data_io_event = 1; + event.sctp_association_event = 1; + event.sctp_address_event = 1; + event.sctp_send_failure_event = 1; + event.sctp_peer_error_event = 1; + event.sctp_shutdown_event = 1; + event.sctp_partial_delivery_event = 1; + event.sctp_adaptation_layer_event = 1; + if (setsockopt(fd, IPPROTO_SCTP, + SCTP_EVENTS, &event, + sizeof(event)) != 0) { + printf("Gak, can't set events errno:%d\n",errno); + exit(0); + } + if (setsockopt(fd1, IPPROTO_SCTP, + SCTP_EVENTS, &event, + sizeof(event)) != 0) { + printf("Gak, can't set events errno:%d\n",errno); + exit(0); + } + + if(connect(fd,(struct sockaddr *)&to,len) == -1){ + printf("Sorry connect fails %d\n",errno); + close(fd); + return(-1); + } + if(connect(fd1,(struct sockaddr *)&to,len) == -1){ + printf("Sorry connect fails %d\n",errno); + close(fd); + return(-1); + } + printf("Connected\n"); + clear_fds(fd,fd1); + process_out_data(fd,fd1); + + return(0); +} + diff --git a/src/apps/peel_server.c b/src/apps/peel_server.c new file mode 100644 index 0000000..524b471 --- /dev/null +++ b/src/apps/peel_server.c @@ -0,0 +1,664 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2003 + * Copyright (c) 2003 Cisco + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * In addition: + * + * Copyright (c) 2003 Cisco + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * a) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * b) Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * c) Neither the name of Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Randall Stewart + * Sridhar Samudrala + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef __NetBSD__ +#include +#endif + +#define SCTP_CRC32C_POLY 0x1EDC6F41 +#define SCTP_CRC32C(c,d) (c=(c>>8)^sctp_crc_c[(c^(d))&0xFF]) +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Copyright 2001, D. Otis. Use this program, code or tables */ +/* extracted from it, as desired without restriction. */ +/* */ +/* 32 Bit Reflected CRC table generation for SCTP. */ +/* To accommodate serial byte data being shifted out least */ +/* significant bit first, the table's 32 bit words are reflected */ +/* which flips both byte and bit MS and LS positions. The CRC */ +/* is calculated MS bits first from the perspective of the serial*/ +/* stream. The x^32 term is implied and the x^0 term may also */ +/* be shown as +1. The polynomial code used is 0x1EDC6F41. */ +/* Castagnoli93 */ +/* x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+ */ +/* x^11+x^10+x^9+x^8+x^6+x^0 */ +/* Guy Castagnoli Stefan Braeuer and Martin Herrman */ +/* "Optimization of Cyclic Redundancy-Check Codes */ +/* with 24 and 32 Parity Bits", */ +/* IEEE Transactions on Communications, Vol.41, No.6, June 1993 */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static unsigned char buffer1[4100]; +static unsigned char buffer2[4100]; +static unsigned char buffer3[4100]; +static unsigned char buffer4[4100]; +static struct sockaddr_in bindto,got; +static socklen_t len; + +unsigned long sctp_crc_c[256] = { + 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, + 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, + 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, + 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, + 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, + 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, + 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, + 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, + 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, + 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, + 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, + 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, + 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, + 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, + 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, + 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, + 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, + 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, + 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, + 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, + 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, + 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, + 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, + 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, + 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, + 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, + 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, + 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, + 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, + 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, + 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, + 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, + 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, + 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, + 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, + 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, + 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, + 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, + 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, + 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, + 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, + 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, + 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, + 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, + 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, + 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, + 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, + 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, + 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, + 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, + 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, + 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, + 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, + 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, + 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, + 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, + 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, + 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, + 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, + 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, + 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, + 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, + 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, + 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L, +}; + +u_int32_t +update_crc32(u_int32_t crc32, + unsigned char *buffer, + unsigned int length) +{ + int i; + for (i = 0; i < length; i++) { + SCTP_CRC32C(crc32, buffer[i]); + } + return (crc32); +} + +u_int32_t +sctp_csum_finalize(u_int32_t crc32) +{ + u_int32_t result; +#if BYTE_ORDER == BIG_ENDIAN + u_int8_t byte0, byte1, byte2, byte3; +#endif + /* Complement the result */ + result = ~crc32; +#if BYTE_ORDER == BIG_ENDIAN + /* + * For BIG-ENDIAN.. aka Motorola byte order the result is in + * little-endian form. So we must manually swap the bytes. Then + * we can call htonl() which does nothing... + */ + byte0 = result & 0x000000ff; + byte1 = (result >> 8) & 0x000000ff; + byte2 = (result >> 16) & 0x000000ff; + byte3 = (result >> 24) & 0x000000ff; + result = ((byte0 << 24) | + (byte1 << 16) | + (byte2 << 8) | + byte3); + crc32 = htonl(result); +#else + /* + * For INTEL platforms the result comes out in network order. + * No htonl is required or the swap above. So we optimize out + * both the htonl and the manual swap above. + */ + crc32 = result; +#endif + return (crc32); +} + +int +check_buffers(void) +{ + /* Prepare buffers */ + u_int32_t temp,*csum; + int ret=0; + temp = 0xffffffff; + temp = update_crc32(temp,buffer1,(sizeof(buffer1)-4)); + temp = sctp_csum_finalize(temp); + csum = (u_int32_t *)(buffer1+(sizeof(buffer1)-4)); + if(*csum != temp){ + printf("Buffer1: Found csum:%x calculated:%x\n", + *csum,temp); + ret++; + } + temp = 0xffffffff; + temp = update_crc32(temp,buffer2,(sizeof(buffer2)-4)); + temp = sctp_csum_finalize(temp); + csum = (u_int32_t *)(buffer2+(sizeof(buffer2)-4)); + if(*csum != temp){ + printf("Buffer2: Found csum:%x calculated:%x\n", + *csum,temp); + ret++; + } + + temp = 0xffffffff; + temp = update_crc32(temp,buffer3,(sizeof(buffer3)-4)); + temp = sctp_csum_finalize(temp); + csum = (u_int32_t *)(buffer3+(sizeof(buffer3)-4)); + if(*csum != temp){ + printf("Buffer3: Found csum:%x calculated:%x\n", + *csum,temp); + ret++; + } + + temp = 0xffffffff; + temp = update_crc32(temp,buffer4,(sizeof(buffer4)-4)); + temp = sctp_csum_finalize(temp); + csum = (u_int32_t *)(buffer4+(sizeof(buffer4)-4)); + if(*csum != temp){ + printf("Buffer4: Found csum:%x calculated:%x\n", + *csum,temp); + ret++; + } + return(ret); +} + +static int +my_handle_notification(int fd,char *notify_buf) { + union sctp_notification *snp; + struct sctp_assoc_change *sac; + struct sctp_paddr_change *spc; + struct sctp_remote_error *sre; + struct sctp_send_failed *ssf; + struct sctp_shutdown_event *sse; + int asocUp; + char *str; + char buf[256]; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + + snp = (union sctp_notification *)notify_buf; + asocUp = 0; + switch(snp->sn_header.sn_type) { + case SCTP_ASSOC_CHANGE: + sac = &snp->sn_assoc_change; + switch(sac->sac_state) { + + case SCTP_COMM_UP: + str = "COMMUNICATION UP"; + asocUp++; + break; + case SCTP_COMM_LOST: + str = "COMMUNICATION LOST"; + break; + case SCTP_RESTART: + str = "RESTART"; + asocUp++; + break; + case SCTP_SHUTDOWN_COMP: + str = "SHUTDOWN COMPLETE"; + break; + case SCTP_CANT_STR_ASSOC: + str = "CANT START ASSOC"; + printf("EXIT:SCTP_ASSOC_CHANGE: %s, assoc=%xh\n", str, + (uint32_t)sac->sac_assoc_id); + exit(0); + break; + default: + str = "UNKNOWN"; + } /* end switch(sac->sac_state) */ + printf("SCTP_ASSOC_CHANGE: %s, assoc=%xh\n", str, + (uint32_t)sac->sac_assoc_id); + break; + case SCTP_PEER_ADDR_CHANGE: + spc = &snp->sn_paddr_change; + switch(spc->spc_state) { + case SCTP_ADDR_AVAILABLE: + str = "ADDRESS AVAILABLE"; + break; + case SCTP_ADDR_UNREACHABLE: + str = "ADDRESS UNAVAILABLE"; + break; + case SCTP_ADDR_REMOVED: + str = "ADDRESS REMOVED"; + break; + case SCTP_ADDR_ADDED: + str = "ADDRESS ADDED"; + break; + case SCTP_ADDR_MADE_PRIM: + str = "ADDRESS MADE PRIMARY"; + break; + default: + str = "UNKNOWN"; + } /* end switch */ + sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr; + if (sin6->sin6_family == AF_INET6) { + inet_ntop(AF_INET6, (char*)&sin6->sin6_addr, buf, sizeof(buf)); + } else { + sin = (struct sockaddr_in *)&spc->spc_aaddr; + inet_ntop(AF_INET, (char*)&sin->sin_addr, buf, sizeof(buf)); + } + printf("SCTP_PEER_ADDR_CHANGE: %s, addr=%s, assoc=%xh\n", str, + buf, (uint32_t)spc->spc_assoc_id); + break; + case SCTP_REMOTE_ERROR: + sre = &snp->sn_remote_error; + printf("SCTP_REMOTE_ERROR: assoc=%xh\n", + (uint32_t)sre->sre_assoc_id); + break; + case SCTP_SEND_FAILED: + ssf = &snp->sn_send_failed; + printf("SCTP_SEND_FAILED: assoc=%xh\n", + (uint32_t)ssf->ssf_assoc_id); + break; + case SCTP_ADAPTATION_INDICATION: + { + struct sctp_adaptation_event *ae; + ae = &snp->sn_adaptation_event; + printf("\nSCTP_adaptation_indication bits:0x%x\n", + (u_int)ae->sai_adaptation_ind); + } + break; + case SCTP_PARTIAL_DELIVERY_EVENT: + { + struct sctp_pdapi_event *pdapi; + pdapi = &snp->sn_pdapi_event; + printf("SCTP_PD-API event:%u\n", + pdapi->pdapi_indication); + if(pdapi->pdapi_indication == 0){ + printf("PDI- Aborted\n"); + } + } + break; + + case SCTP_SHUTDOWN_EVENT: + sse = &snp->sn_shutdown_event; + printf("SCTP_SHUTDOWN_EVENT: assoc=%xh\n", + (uint32_t)sse->sse_assoc_id); + break; + default: + printf("Unknown notification event type=%xh\n", + snp->sn_header.sn_type); + } /* end switch(snp->sn_type) */ + return(asocUp); +} + + +static char readBuffer[65535]; +static int sz=0; +static char controlVector[65535]; +static struct msghdr msg; +int +my_sctpReadInput(int fd,int maxread) +{ + /* receive some number of datagrams and + * act on them. + */ + struct sctp_sndrcvinfo *s_info; + int i,disped; + + struct iovec iov[2]; + unsigned char from[200]; + disped = i = 0; + + memset(&msg,0,sizeof(msg)); + memset(controlVector,0,sizeof(controlVector)); + memset(readBuffer,0,sizeof(readBuffer)); + s_info = NULL; + iov[0].iov_base = readBuffer; + iov[0].iov_len = maxread; + iov[1].iov_base = NULL; + iov[1].iov_len = 0; + msg.msg_name = (caddr_t)from; + msg.msg_namelen = sizeof(from); + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_control = (caddr_t)controlVector; + msg.msg_controllen = sizeof(controlVector); + errno = 0; + sz = recvmsg(fd,&msg,0); + printf("Read fd:%d returns %d errno:%d control len is %d msgflg:%x\n", + fd, + sz,errno, + msg.msg_controllen, + msg.msg_flags); + + if (msg.msg_flags & MSG_NOTIFICATION) { + printf("Got a notification\n"); + return(my_handle_notification(fd,readBuffer)); + }else{ + printf("Got data\n"); + return(-1); + } +} + + +int +poll_fd(int fd) +{ + int cameup; + int max,notdone; + fd_set readfds,writefds,exceptfds; + struct timeval tv; + memset(&tv,0,sizeof(tv)); + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_ZERO(&exceptfds); + cameup = 0; + max = fd + 1; + notdone = 1; + printf("poll_fd\n"); + FD_SET(fd,&readfds); + select(max,&readfds,&writefds,&exceptfds,NULL); + notdone = 0; + if(FD_ISSET(fd,&readfds)){ + printf("Read please\n"); + cameup += my_sctpReadInput(fd,4100); + } + return(cameup); +} + +static sctp_assoc_t +dig_out_asocid(void) +{ + struct sctp_sndrcvinfo *s_info; + struct cmsghdr *cmsg; + s_info = NULL; + if(msg.msg_controllen){ + /* parse through and see if we find + * the sctp_sndrcvinfo + */ + cmsg = (struct cmsghdr *)controlVector; + while(cmsg){ + if(cmsg->cmsg_level == IPPROTO_SCTP){ + if(cmsg->cmsg_type == SCTP_SNDRCV){ + /* Got it */ + s_info = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + break; + } + } + cmsg = CMSG_NXTHDR(&msg,cmsg); + } + }else{ + printf("No CMSG?\n"); + exit(0); + } + if(s_info == NULL){ + printf("No sinfo?\n"); + exit(0); + } + return(s_info->sinfo_assoc_id); +} + + +void +process(int fd,int magic) +{ + int fd1,num_asoc,ret,i; + sctp_assoc_t asoc; + struct timespec ts; + num_asoc = 0; + i = 1; + ts.tv_sec = 0; + ts.tv_nsec = 10000; + + while(i < 4099){ + printf("pass %d\n",i); + while(num_asoc < 2){ + ret = poll_fd(fd); + if(ret >0 ){ + num_asoc += ret; + }else if(ret == 0){ + sleep(1); + }else if(ret < 0){ + printf("Got data? %d\n",sz); + sleep(1); + } + printf("asoc count is %d\n",num_asoc); + } + again: + printf("Reading for %d bytes from fd:%d\n", + i,fd); + my_sctpReadInput(fd,i); + if(sz == i){ + memcpy(buffer1,readBuffer,i); + }else{ + printf("Huh I am messed up read %d wanted %d\n", + sz,i); + goto again; + } + if(msg.msg_flags & MSG_EOR){ + printf("Huh got EOR on paritial read?\n"); + exit(0); + } + asoc = dig_out_asocid(); + nanosleep(&ts,NULL); + + fd1 = sctp_peeloff(fd,asoc); + if(fd1 == -1){ + printf("peeloff failed %d/err:%d\n", + fd1,errno); + exit(0); + } + my_sctpReadInput(fd1,(4100-i)); + if(sz > 0){ + memcpy(&buffer1[i],readBuffer,sz); + printf("Copied %d bytes\n",sz); + }else{ + printf("Huh only read %d\n",sz); + } + if(magic >= i){ + printf("magic engaged\n"); + my_sctpReadInput(fd,i); + }else{ + my_sctpReadInput(fd,4100); + } + if(sz > 0){ + memcpy(buffer2,readBuffer,sz); + printf("copied %d bytes\n",sz); + }else{ + printf("Huh only read %d\n",sz); + } + my_sctpReadInput(fd1,4100); + if(sz > 0){ + memcpy(buffer3,readBuffer,sz); + printf("copied %d bytes\n",sz); + }else{ + printf("Huh only read %d\n",sz); + } + my_sctpReadInput(fd,4100); + if(sz > 0){ + memcpy(buffer4,readBuffer,sz); + printf("copied %d bytes\n",sz); + }else{ + printf("Huh only read %d\n",sz); + } + if(check_buffers()){ + exit(0); + } + close(fd1); + i++; + num_asoc--; + } +} + +int +main(int argc, char **argv) +{ + int i,fd; + uint16_t myport=0; + int magic=0; + struct sctp_event_subscribe event; + while((i= getopt(argc,argv,"m:M:")) != EOF){ + switch(i){ + case 'm': + myport = (uint16_t)strtol(optarg,NULL,0); + break; + case 'M': + magic = strtol(optarg,NULL,0); + break; + }; + } + /**********************socket 1 *******************/ + fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + if(fd == -1){ + printf("can't open socket:%d\n",errno); + return(-1); + } + memset(&bindto,0,sizeof(bindto)); + //len = bindto.sin_len = sizeof(bindto); + len = sizeof(bindto); + bindto.sin_family = AF_INET; + printf("bind port %d\n",myport); + bindto.sin_port = htons(myport); + if(bind(fd,(struct sockaddr *)&bindto, len) < 0){ + printf("can't bind a socket:%d\n",errno); + close(fd); + return(-1); + } + if(getsockname(fd,(struct sockaddr *)&got,&len) < 0){ + printf("get sockname failed err:%d\n",errno); + close(fd); + return(-1); + } + printf("fd uses port %d\n",ntohs(got.sin_port)); + listen(fd,100); + /* enable all event notifications */ + event.sctp_data_io_event = 1; + event.sctp_association_event = 1; + event.sctp_address_event = 1; + event.sctp_send_failure_event = 1; + event.sctp_peer_error_event = 1; + event.sctp_shutdown_event = 1; + event.sctp_partial_delivery_event = 1; + event.sctp_adaptation_layer_event = 1; + if (setsockopt(fd, IPPROTO_SCTP, + SCTP_EVENTS, &event, + sizeof(event)) != 0) { + printf("Gak, can't set events errno:%d\n",errno); + exit(0); + } + printf("to process\n"); + process(fd,magic); + return(0); +} + diff --git a/src/apps/sctp_darn.c b/src/apps/sctp_darn.c new file mode 100644 index 0000000..61673a2 --- /dev/null +++ b/src/apps/sctp_darn.c @@ -0,0 +1,2304 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2001, 2003 + * Copyright (c) 1999 Cisco + * Copyright (c) 1999, 2000, 2001 Motorola + * Copyright (c) 2001 Nokia + * Copyright (c) 2001 La Monte H.P. Yarroll + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * La Monte H.P. Yarroll + * Karl Knutson + * Hui Huang + * Daisy Chang + * Sridhar Samudrala + */ + +/* This is a userspace test application for the SCTP kernel + * implementation state machine. It is vaguely inspired by Stevens' + * program "sock". + * + * It has the limited ability to send messages and to listen for messages + * sent via SCTP. + */ + +#include +#include +#include +//#define _GNU_SOURCE +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sctp_darn.h" + +char *TCID = __FILE__; +int TST_TOTAL = 1; +int TST_CNT = 0; + +#define GEN_DATA_FIRST 0x21 +#define GEN_DATA_LAST 0x7e + +/* Display an IPv4 address in readable format. */ +#define NIPQUAD(addr) \ + ((unsigned char *)&addr)[0], \ + ((unsigned char *)&addr)[1], \ + ((unsigned char *)&addr)[2], \ + ((unsigned char *)&addr)[3] + +/* Display an IPv6 address in readable format. */ +#define NIP6(addr) \ + ntohs((addr).s6_addr16[0]), \ + ntohs((addr).s6_addr16[1]), \ + ntohs((addr).s6_addr16[2]), \ + ntohs((addr).s6_addr16[3]), \ + ntohs((addr).s6_addr16[4]), \ + ntohs((addr).s6_addr16[5]), \ + ntohs((addr).s6_addr16[6]), \ + ntohs((addr).s6_addr16[7]) + +/* These are the global options. */ +char *local_host = NULL; +int local_port = 0; +char *remote_host = NULL; +int remote_port = 0; +command_t command = COMMAND_NONE; +struct sockaddr *bindx_add_addrs = NULL; +int bindx_add_count = 0; +struct sockaddr *bindx_rem_addrs = NULL; +int bindx_rem_count = 0; +struct sockaddr *connectx_addrs = NULL; +int connectx_count = 0; +int interactive_mode = 0; +int poll_skn = 0; +int nonblocking = 0; +int opt_space = 0; +char gen_data = GEN_DATA_FIRST; +char *inter_outbuf = NULL; +int inter_outlen = 0; +int inter_sk = 0; +int poll_snd_size = 0; +int use_poll = 0; +int socket_type = SOCK_SEQPACKET; +sctp_assoc_t associd = 0; +int echo = 0; +char *interface = "eth0"; +int if_index = 0; +sockaddr_storage_t remote_addr; +sa_family_t ra_family; /* What family is remote_addr? */ +int ra_len = 0; /* How long is remote_addr? */ +void *ra_raw; /* This is the addr part of remote_addr. */ +int new_connection = 1; + +enum inter_cmd_num { + INTER_SND = 0, + INTER_RCV, + INTER_SNDBUF, + INTER_RCVBUF, + INTER_BINDX_ADD, + INTER_BINDX_REM, + INTER_SET_PRIM, + INTER_SET_PEER_PRIM, + INTER_SHUTDOWN, + INTER_ABORT, + INTER_NODELAY, + INTER_MAXSEG +}; + +enum shutdown_type { + SHUTDOWN_ABORT = 0, + SHUTDOWN_SHUTDOWN +}; + +struct inter_entry { + char *cmd; + int cmd_num; +}; + +struct inter_entry inter_commands[] = { + {"snd", INTER_SND}, + {"rcv", INTER_RCV}, + {"sndbuf", INTER_SNDBUF}, + {"rcvbuf", INTER_RCVBUF}, + {"bindx-add", INTER_BINDX_ADD}, + {"bindx-rem", INTER_BINDX_REM}, + {"primary", INTER_SET_PRIM}, + {"peer_primary", INTER_SET_PEER_PRIM}, + {"shutdown", INTER_SHUTDOWN}, + {"abort", INTER_ABORT}, + {"nodelay", INTER_NODELAY}, + {"maxseg", INTER_MAXSEG}, + {NULL, -1}, +}; + +#define POLL_SK_MAX 256 /* The max number of sockets to select/poll. */ +int poll_sks[POLL_SK_MAX]; /* The array for using select(). */ +struct pollfd poll_fds[POLL_SK_MAX]; /* The array for using poll(). */ +#define POLL_SND_SIZE 16384 /* Default message size in the poll mode. */ + + +struct sockaddr *append_addr(const char *parm, struct sockaddr *addrs, + int *ret_count) ; +int build_endpoint(char *argv0, int portnum); +static int parse_inter_commands(char *, char *, int); +static void snd_func(char *); +static void sndbuf_func(char *, int, int, int); +static void rcvbuf_func(char *, int, int, int); +static struct sockaddr *get_bindx_addr(char *, int *); +static int bindx_func(char *, int, struct sockaddr *, int, int, int); +static int connectx_func(char *, int, struct sockaddr *, int); +static void primary_func(char *, int, char *, int); +static void peer_primary_func(char *, int, char *, int); +static int nodelay_func(char *, int, int val, int set); +static int maxseg_func(char *, int, int val, int set); +static int shutdown_func(char *argv0, int *skp, int shutdown_type); +static int test_sk_for_assoc(int sk, sctp_assoc_t assoc_id); +static char * gen_message(int); +static sctp_assoc_t test_recv_assoc_change(int); +static sctp_assoc_t test_verify_assoc_change(struct msghdr *); +void print_addr_buf(void * laddrs, int n_laddrs); +int print_sockaddr(struct sockaddr *sa_addr); + +int +main(int argc, char *argv[]) { + int sk = -1; + int error = 0; + int i; + + signal(SIGPIPE, SIG_IGN); + + parse_arguments(argc, argv); + + switch(command) { + case COMMAND_NONE: + fprintf(stderr, "%s: Please specify a command.\n", + argv[0]); + exit(1); + break; + case COMMAND_LISTEN: + sk = build_endpoint(argv[0], local_port); + error = command_listen(argv[0], sk); + break; + case COMMAND_SEND: + sk = build_endpoint(argv[0], local_port); + error = command_send(argv[0], &sk); + break; + case COMMAND_POLL: + if (use_poll) { + for (i = 0; i < poll_skn; i++) { + poll_fds[i].fd = build_endpoint(argv[0], + local_port + i); + } + } else { + for (i = 0; i < poll_skn; i++) { + poll_sks[i] = build_endpoint(argv[0], + local_port + i); + } + } + error = command_poll(argv[0]); + break; + default: + fprintf(stderr, "%s: illegal command %d\n", + argv[0], command); + exit(1); + } + + /* Shut down the link. */ + if (COMMAND_POLL != command) { + close(sk); + } else { + /* Shutdown all links. */ + if (use_poll) { + for (i = 0; i < poll_skn; i++) { + close(poll_fds[i].fd); + } + } else { + for (i = 0; i < poll_skn; i++) { + close(poll_sks[i]); + } + } + } + + exit(error); +} + +/******************************************************************** + * 2nd Level Abstractions + ********************************************************************/ + +void +parse_arguments(int argc, char *argv[]) { + int option_index = 0; + int c; + struct sockaddr *tmp_addrs = NULL; + + static struct option long_options[] = { + {"local", 1, 0, 1}, + {"local-port", 1, 0, 2}, + {"remote", 1, 0, 3}, + {"remote-port", 1, 0, 4}, + {"listen", 0, 0, 10}, + {"send", 0, 0, 11}, + {"bindx-add", 1, 0, 15}, + {"bindx-rem", 1, 0, 16}, + {"use-poll", 0, 0, 20}, + {"echo", 0, 0, 'e'}, + {"interface", optional_argument, 0, 5,}, + {"connectx", 1, 0, 17}, + {0, 0, 0, 0} + }; + + /* Parse the arguments. */ + while (1) { + c = getopt_long (argc, argv, "B:H:IP:b:h:i:p:lm:nstz:ec:", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 0: + printf("option %s", long_options[option_index].name); + if (optarg) { + printf(" with arg %s", optarg); + } + printf("\n"); + break; + case 1: /* local host */ + case 'H': + local_host = optarg; + break; + case 2: /* local port */ + case 'P': + local_port = atoi(optarg); + break; + case 3: /* remote host */ + case 'h': + remote_host = optarg; + break; + case 4: /* remote port */ + case 'p': + remote_port = atoi(optarg); + break; + case 5: /* interface for sin6_scope_id */ + if (optarg) + interface = optarg; + if_index = if_nametoindex(interface); + if (!if_index) { + printf("Interface %s unknown\n", interface); + exit(1); + } + break; + /* COMMANDS */ + case 10: /* listen */ + case 'l': + if (command) { + fprintf(stderr, + "%s: pick ONE of listen or send\n", + argv[0]); + exit(1); + } else { + command = COMMAND_LISTEN; + } + break; + + case 11: /* send */ + case 's': + if (command) { + fprintf(stderr, + "%s: pick ONE of listen or send\n", + argv[0]); + exit(1); + } else { + command = COMMAND_SEND; + } + break; + + case 15: /* bindx_add */ + case 'B': + tmp_addrs = + append_addr(optarg, bindx_add_addrs, + &bindx_add_count); + if (NULL == tmp_addrs) { + /* We have no memory, so keep fprintf() + * from trying to allocate more. + */ + fprintf(stderr, "No memory to add "); + fprintf(stderr, optarg); + fprintf(stderr, "\n"); + exit(2); + } + bindx_add_addrs = tmp_addrs; + + break; + + case 16: /* bindx_rem */ + case 'b': + tmp_addrs = + append_addr(optarg, bindx_rem_addrs, + &bindx_rem_count); + if (NULL == tmp_addrs) { + /* We have no memory, so keep fprintf() + * from trying to allocate more. + */ + fprintf(stderr, "No memory to add "); + fprintf(stderr, optarg); + fprintf(stderr, "\n"); + exit(2); + } + bindx_rem_addrs = tmp_addrs; + break; + case 17: /* connectx */ + case 'c': + tmp_addrs = + append_addr(optarg, connectx_addrs, + &connectx_count); + if (NULL == tmp_addrs) { + /* We have no memory, so keep fprintf() + * from trying to allocate more. + */ + fprintf(stderr, "No memory to add "); + fprintf(stderr, optarg); + fprintf(stderr, "\n"); + exit(2); + } + connectx_addrs = tmp_addrs; + break; + case 20: /* use-poll */ + use_poll = 1; + break; + case 'I': + interactive_mode = 1; + break; + case 'i': + command = COMMAND_POLL; + poll_skn = atoi(optarg); + if (poll_skn <= 0 || poll_skn > POLL_SK_MAX) { + fprintf(stderr, "Too many sockets for "); + fprintf(stderr, "for polling\n"); + exit(2); + } + break; + case 'm': + opt_space = atoi(optarg); + break; + case 'n': + nonblocking = 1; + break; + case 't': + socket_type = SOCK_STREAM; + break; + case 'z': + poll_snd_size = atoi(optarg); + if (poll_snd_size <= 0) { + fprintf(stderr, "Bad message size.\n"); + exit(2); + } + break; + case 'e': + echo = 1; + break; + case '?': + usage(argv[0]); + exit(1); + + default: + printf ("%s: unrecognized option 0%c\n", + argv[0], c); + usage(argv[0]); + exit(1); + } + } + + if (optind < argc) + { + fprintf(stderr, "%s: non-option arguments are illegal: ", + argv[0]); + while (optind < argc) + fprintf(stderr, "%s ", argv[optind++]); + fprintf (stderr, "\n"); + usage(argv[0]); + exit(1); + } + + + if (NULL == local_host) { + fprintf(stderr, "%s: You MUST provide a local host.\n", + argv[0]); + usage(argv[0]); + exit(1); + } + + if (command == COMMAND_SEND && NULL == remote_host + && connectx_count == 0) { + fprintf(stderr, "%s: You MUST provide a remote host for sending.\n", + argv[0]); + usage(argv[0]); + exit(1); + } + + if (remote_host != NULL && connectx_count != 0) { + fprintf(stderr, "%s: You can not provide both -h and -c options.\n", + argv[0]); + usage(argv[0]); + exit(1); + } +} /* parse_arguments() */ + +/* Set up the local endpoint. */ +int +build_endpoint(char *argv0, int portnum) +{ + int retval; + struct hostent *hst; + sockaddr_storage_t local_addr; + sa_family_t la_family; /* What family is local_addr? */ + int la_len; /* How long is local_addr? */ + void *la_raw; /* This is the addr part of local_addr. */ + int error; + struct sctp_event_subscribe subscribe; + + /* Get the transport address for the local host name. */ + hst = gethostbyname(local_host); + if (hst == NULL) { + hst = gethostbyname2(local_host, AF_INET6); + } + + if (hst == NULL || hst->h_length < 1) { + fprintf(stderr, "%s: bad hostname: %s\n", argv0, local_host); + exit(1); + } + + la_family = hst->h_addrtype; + switch (la_family) { + case AF_INET: + la_len = sizeof(local_addr.v4); + la_raw = &local_addr.v4.sin_addr; + local_addr.v4.sin_port = htons(portnum); + local_addr.v4.sin_family = AF_INET; + break; + case AF_INET6: + la_len = sizeof(local_addr.v6); + la_raw = &local_addr.v6.sin6_addr; + local_addr.v6.sin6_port = htons(portnum); + local_addr.v6.sin6_family = AF_INET6; + local_addr.v6.sin6_scope_id = if_index; + break; + default: + fprintf(stderr, "Invalid address type.\n"); + exit(1); + break; + } + memcpy(la_raw, hst->h_addr_list[0], hst->h_length); + + /* Create the local endpoint. */ + retval = socket(la_family, socket_type, IPPROTO_SCTP); + if (retval < 0) { + fprintf(stderr, "%s: failed to create socket: %s.\n", + argv0, strerror(errno)); + exit(1); + } + + if (SOCK_SEQPACKET == socket_type) { + memset(&subscribe, 0, sizeof(subscribe)); + subscribe.sctp_data_io_event = 1; + subscribe.sctp_association_event = 1; + error = setsockopt(retval, SOL_SCTP, SCTP_EVENTS, + (char *)&subscribe, sizeof(subscribe)); + if (error) { + fprintf(stderr, "SCTP_EVENTS: error: %d\n", error); + exit(1); + } + } + + /* Bind this socket to the test port. */ + error = bind(retval, &local_addr.sa, la_len); + if (error != 0) { + fprintf(stderr, "%s: can not bind to %s:%d: %s.\n", + argv0, local_host, portnum, + strerror(errno)); + exit(1); + } + + /* Do we need to do bindx() to add any additional addresses? */ + if (bindx_add_addrs) { + if (0 != bindx_func(argv0, retval, bindx_add_addrs, + bindx_add_count, SCTP_BINDX_ADD_ADDR, portnum)) { + fprintf(stderr, "bindx_func (add) failed.\n"); + exit(1); + } + } /* if (bindx_add_addrs) */ + + /* Do we need to do bindx() to remove any bound addresses? */ + if (bindx_rem_addrs) { + if (0 != bindx_func(argv0, retval, bindx_rem_addrs, + bindx_rem_count, SCTP_BINDX_REM_ADDR, portnum)) { + fprintf(stderr, "bindx_func (remove) failed.\n"); + exit(1); + } + } /* if (bindx_rem_addrs) */ + + /* Do we want to run in the non-blocking mode? */ + if (nonblocking) { + error = fcntl(retval, F_SETFL, O_NONBLOCK); + if (error != 0) { + fprintf(stderr, "%s: error fcntl: %s.\n", + argv0, strerror(errno)); + exit(1); + } + } + + if (opt_space) { + sndbuf_func(argv0, retval, opt_space, 1); + rcvbuf_func(argv0, retval, opt_space, 1); + } + + return retval; + +} /* build_endpoint() */ + +/* Convenience structure to determine space needed for cmsg. */ +typedef union { + struct sctp_initmsg init; + struct sctp_sndrcvinfo sndrcvinfo; +} _sctp_cmsg_data_t; + + +/* Listen on the socket, printing out anything that arrives. */ +int +command_listen(char *argv0, int sk) +{ + char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))]; + struct iovec iov; + struct msghdr inmessage; + sockaddr_storage_t msgname; + char message[REALLY_BIG]; + int done = 0; + int error; + int c; + int recvsk = 0; + + /* Mark sk as being able to accept new associations */ + error = listen(sk, 5); + if (error != 0) { + printf("\n\n\t\tlisten Failure: %s.\n\n\n", + strerror(errno)); + exit(1); + } + + if (nonblocking) { + if (!interactive_mode) { + printf("Use -I for interactive mode with"); + printf(" -n nonblocking\n"); + exit(1); + } + } + + /* Initialize the global value for interactive mode functions. */ + if (interactive_mode) { + inter_sk = sk; + } + + /* Initialize inmessage with enough space for DATA... */ + memset(&inmessage, 0, sizeof(inmessage)); + if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) { + printf("%s: Can't allocate memory.\n", argv0); + exit(1); + } + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + /* or a control message. */ + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + inmessage.msg_name = &msgname; + inmessage.msg_namelen = sizeof(msgname); + + printf("%s listening...\n", argv0); + /* Get the messages sent */ + done = 0; + while (!done) { + if (interactive_mode) { + /* Read from the user. */ + if (remote_host) { + printf("%s:%d-%s:%d Interactive mode> ", + local_host, local_port, remote_host, + remote_port); + } else { + printf("%s:%d-", local_host, local_port); + if (associd) { + print_sockaddr(&remote_addr.sa); + } else { + printf("?:%d", remote_port); + } + printf(" Interactive mode> "); + } + fflush(stdout); + if (NULL == fgets(message, REALLY_BIG, stdin)) { + done = 1; + continue; + } + + if (0 <= (c = parse_inter_commands(argv0, message, + 0))) { + if (INTER_RCV != c) { + continue; + } + } else { + continue; + } + } + + if (socket_type == SOCK_STREAM) { + socklen_t len = 0; + + if (!recvsk) { + if ((recvsk = accept(sk, NULL, &len)) < 0) { + fprintf(stderr, "%s: error: %s.\n", + argv0, strerror(errno)); + exit(1); + } + } + + } else { + recvsk = sk; + } + + error = recvmsg(recvsk, &inmessage, MSG_WAITALL); + if (error < 0) { + if (nonblocking && (EAGAIN == errno)) { + error = 0; + continue; + } + + if (socket_type == SOCK_STREAM) { + if (ENOTCONN != errno) + break; + printf("No association is present now!!\n"); + close(recvsk); + recvsk = 0; + continue; + } + break; + } + + /* Update the associd when a notification is received on a + * UDP-style socket. + */ + if (inmessage.msg_flags & MSG_NOTIFICATION) + associd = test_verify_assoc_change(&inmessage); + + if (echo) { + if( !(MSG_NOTIFICATION & inmessage.msg_flags)) { + sendto(recvsk, inmessage.msg_iov->iov_base, + error, 0, (struct sockaddr *)&msgname, + sizeof(msgname)); + } + } + + test_print_message(sk, &inmessage, error); + + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + inmessage.msg_name = &msgname; + inmessage.msg_namelen = sizeof(msgname); + iov.iov_len = REALLY_BIG; + + /* Verify that the association is no longer present. */ + if (0 != test_sk_for_assoc(recvsk, associd)) { + printf("No association is present now!!\n"); + if (socket_type == SOCK_STREAM) { + close(recvsk); + recvsk = 0; + } + } + } + + if (error < 0) { + fprintf(stderr, "%s: error: %s.\n", + argv0, strerror(errno)); + exit(1); + } + + return error; + +} /* command_listen() */ + +/* Read lines from stdin and send them to the socket. */ +int +command_send(char *argv0, int *skp) +{ + struct msghdr outmsg; + struct iovec iov; + int done = 0; + char message[REALLY_BIG]; + struct hostent *hst; + int c; + struct sockaddr *addrs; + int msglen; + int error = 0; + int sk = *skp; + + /* Set up the destination. */ + if (remote_host != NULL) { + hst = gethostbyname(remote_host); + if (hst == NULL) { + hst = gethostbyname2(remote_host, AF_INET6); + } + + if (hst == NULL || hst->h_length < 1) { + fprintf(stderr, "%s: bad hostname: %s\n", + argv0, remote_host); + exit(1); + } + + ra_family = hst->h_addrtype; + switch (ra_family) { + case AF_INET: + ra_len = sizeof(remote_addr.v4); + ra_raw = &remote_addr.v4.sin_addr; + remote_addr.v4.sin_port = htons(remote_port); + remote_addr.v4.sin_family = AF_INET; + break; + case AF_INET6: + ra_len = sizeof(remote_addr.v6); + ra_raw = &remote_addr.v6.sin6_addr; + remote_addr.v6.sin6_port = htons(remote_port); + remote_addr.v6.sin6_family = AF_INET6; + remote_addr.v6.sin6_scope_id = if_index; + break; + default: + fprintf(stderr, "Invalid address type.\n"); + exit(1); + break; + } + memcpy(ra_raw, hst->h_addr_list[0], hst->h_length); + } + + /* Initialize the global value for interactive mode functions. */ + if (interactive_mode) { + inter_sk = sk; + } + + printf("%s ready to send...\n", argv0); + while (!done) { + /* Read from the user. */ + if (remote_host) { + if (interactive_mode) { + printf("%s:%d-%s:%d Interactive mode> ", + local_host, local_port, remote_host, + remote_port); + } else { + printf("%s:%d-%s:%d> ", + local_host, local_port, + remote_host, remote_port); + } + } else { + printf("%s:%d-", local_host, local_port); + if (associd) { + print_sockaddr(&remote_addr.sa); + } else { + printf("XXXXXX:%d", remote_port); + } + if (interactive_mode) { + printf(" Interactive mode> "); + } else { + printf("> "); + } + } + fflush(stdout); + if (NULL == fgets(message, REALLY_BIG, stdin)) { + done = 1; + continue; + } + + if (interactive_mode) { + /* This is the send only agent. */ + if (0 <= (c = parse_inter_commands(argv0, message, + 1))) { + if (INTER_SND == c) { + iov.iov_base = inter_outbuf; + msglen = inter_outlen; + iov.iov_len = msglen; + + } else { + continue; + } + + } else { + continue; + } + } else { + /* Send to our neighbor. */ + msglen = strlen(message) + 1; + iov.iov_len = msglen; + } + + /* For a UDP-style socket, verify if an existing association + * has gone. If so, receive the pending SCTP_ASSOC_CHANGE + * notification. + */ + if ((SOCK_SEQPACKET == socket_type) && associd && + (0 != test_sk_for_assoc(sk, associd))) { + associd = test_recv_assoc_change(sk); + printf("Old association gone, Starting a new one!\n"); + new_connection = 1; + } + + if (new_connection && connectx_count != 0) { + /* Do a sctp_connectx() to establish a connection. */ + error = connectx_func(argv0, sk, connectx_addrs, + connectx_count); + if (0 != error) { + if (error == -2) { + printf("Connection refused\n"); + if (SOCK_SEQPACKET == socket_type) { + associd = test_recv_assoc_change(sk); + } + continue; + } + fprintf(stderr, "connectx failed.\n"); + exit(1); + } + if (SOCK_SEQPACKET == socket_type) { + associd = test_recv_assoc_change(sk); + } else { + associd = 1; + } + int rc = sctp_getpaddrs(sk, associd, &addrs); + if (0 >= rc) { + if (rc == 0) { + fprintf(stderr, "sctp_getpaddrs failed, no peers.\n"); + } else { + fprintf(stderr, "sctp_getpaddrs failed %s(%d).\n", strerror(errno), errno); + } + exit(1); + } + printf("New connection, peer addresses\n"); + print_addr_buf(addrs, rc); + ra_family = addrs[0].sa_family; + switch (ra_family) { + case AF_INET: + ra_len = sizeof(remote_addr.v4); + break; + case AF_INET6: + ra_len = sizeof(remote_addr.v6); + break; + default: + fprintf(stderr, "Invalid address type.\n"); + exit(1); + } + memcpy(&remote_addr, &addrs[0], ra_len); + sctp_freepaddrs(addrs); + new_connection = 0; + } + + do { + if (SOCK_SEQPACKET == socket_type || + (connectx_count == 0 && new_connection)) { + /* Initialize the message struct we use to pass + * messages to the remote socket. + */ + if (!interactive_mode) { + iov.iov_base = message; + iov.iov_len = msglen; + } + outmsg.msg_iov = &iov; + outmsg.msg_iovlen = 1; + outmsg.msg_control = NULL; + outmsg.msg_controllen = 0; + outmsg.msg_name = &remote_addr; + outmsg.msg_namelen = ra_len; + + error = sendmsg(sk, &outmsg, 0); + } else { + error = send(sk, message, msglen, 0); + if (error == -1 && errno == EPIPE) { + error = close(sk); + if (error != 0) { + fprintf(stderr, "close failed %s\n", strerror(errno)); + exit(1); + } + *skp = sk = build_endpoint(argv0, local_port); + break; + } + } + + if (error != msglen) { + fprintf(stderr, "%s: error: %s.\n", + argv0, strerror(errno)); + if (nonblocking && EAGAIN == errno) { + if (interactive_mode) { + break; + } + continue; + } + exit(1); + } else { + break; + } + } while (error != msglen); + + /* If this is the first message sent over a UDP-style socket, + * get the associd from the SCTP_ASSOC_CHANGE notification. + */ + if ((SOCK_SEQPACKET == socket_type) && (0 == associd)) + associd = test_recv_assoc_change(sk); + + /* Verify there is no association. */ + if (0 != test_sk_for_assoc(sk, associd)) { + printf("No association is present now!!\n"); + new_connection = 1; + } else { + if (new_connection) { + int rc = sctp_getpaddrs(sk, associd, &addrs); + if (0 >= rc) { + if (rc == 0) { + fprintf(stderr, "sctp_getpaddrs failed, no peers.\n"); + } else { + fprintf(stderr, "sctp_getpaddrs failed %s(%d).\n", strerror(errno), errno); + } + exit(1); + } + printf("New connection, peer addresses\n"); + print_addr_buf(addrs, rc); + sctp_freepaddrs(addrs); + new_connection = 0; + } + } + + /* Clean up. */ + if (interactive_mode) { + free(inter_outbuf); + inter_outbuf = NULL; + } + } /* while(!done) */ + + return error; + +} /* command_send() */ + +/* Listen on the array of sockets, printing out anything that arrives. */ +int +command_poll(char *argv0) +{ + char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))]; + struct iovec iov; + struct msghdr inmessage; + int done = 0; + int error = 0; + int max_fd, i, ret; + int size; + fd_set *ibitsp = NULL; + fd_set *obitsp = NULL; + fd_set *xbitsp = NULL; + + struct msghdr outmsg; + struct hostent *hst; + int msglen; + int temp_fd, temp_set; + + + + /* If a remote host is specified, initialize the destination. */ + if (remote_host) { + /* Set up the destination. */ + hst = gethostbyname(remote_host); + if (hst == NULL) { + hst = gethostbyname2(remote_host, AF_INET6); + } + + if (hst == NULL || hst->h_length < 1) { + fprintf(stderr, "%s: bad hostname: %s\n", + argv0, remote_host); + exit(1); + } + + ra_family = hst->h_addrtype; + switch (ra_family) { + case AF_INET: + ra_len = sizeof(remote_addr.v4); + ra_raw = &remote_addr.v4.sin_addr; + remote_addr.v4.sin_port = htons(remote_port); + remote_addr.v4.sin_family = AF_INET; + break; + case AF_INET6: + ra_len = sizeof(remote_addr.v6); + ra_raw = &remote_addr.v6.sin6_addr; + remote_addr.v6.sin6_port = htons(remote_port); + remote_addr.v6.sin6_family = AF_INET6; + remote_addr.v6.sin6_scope_id = if_index; + break; + default: + fprintf(stderr, "Invalid address type.\n"); + exit(1); + break; + } + memcpy(ra_raw, hst->h_addr_list[0], hst->h_length); + + /* Initialize the message struct we use to pass messages to + * the remote socket. + */ + outmsg.msg_iov = &iov; + outmsg.msg_iovlen = 1; + outmsg.msg_control = NULL; + outmsg.msg_controllen = 0; + outmsg.msg_name = &remote_addr; + outmsg.msg_namelen = ra_len; + } + + + max_fd = -1; + + /* Set all of the sockets to be ready for listening. */ + if (use_poll) { + for (i = 0; i < poll_skn; i++) { + error = listen(poll_fds[i].fd, 1); + if (error != 0) { + printf("%s: Listen failed on socket number ", + argv0); + printf("%d: %s.\n", i, strerror(errno)); + exit(1); + } + } + printf("%s listening...\n", argv0); + } else { + for (i = 0; i < poll_skn; i++) { + error = listen(poll_sks[i], 1); + if (error != 0) { + printf("%s: Listen failed on socket number ", + argv0); + printf("%d: %s.\n", i, strerror(errno)); + exit(1); + } + if (poll_sks[i] > max_fd) { + max_fd = poll_sks[i]; + } + } + printf("%s listening...\n", argv0); + + size = howmany(max_fd + 1, NFDBITS) * sizeof(fd_mask); + if ((ibitsp = (fd_set *)malloc(size)) == NULL) { + printf("%s: Can't allocate memory.\n", argv0); + exit(1); + } + if ((obitsp = (fd_set *)malloc(size)) == NULL) { + printf("%s: Can't allocate memory.\n", argv0); + exit(1); + } + if ((xbitsp = (fd_set *)malloc(size)) == NULL) { + printf("%s: Can't allocate memory.\n", argv0); + exit(1); + } + memset(ibitsp, 0, size); + memset(obitsp, 0, size); + memset(xbitsp, 0, size); + } + + + /* Initialize inmessage with enough space for DATA... */ + memset(&inmessage, 0, sizeof(inmessage)); + if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) { + printf("%s: Can't allocate memory.\n", argv0); + exit(1); + } + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + /* or a control message. */ + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + + + done = 0; + /* Set the default send message size. */ + if (!poll_snd_size) { + poll_snd_size = POLL_SND_SIZE; + } + + while (!done) { + + if (use_poll) { + for (i = 0; i < poll_skn; i++) { + poll_fds[i].events = POLLIN; + } + if (remote_host) { + /* Poll output on the first socket. */ + poll_fds[0].events |= POLLOUT; + } + + if ((ret = poll(poll_fds, poll_skn, -1))) { + if (ret == -1) { + break; + } + } + } else { + for (i = 0; i < poll_skn; i++) { + FD_SET(poll_sks[i], ibitsp); + FD_SET(poll_sks[i], xbitsp); + } + if (remote_host) { + /* Only select output on the first socket. */ + FD_SET(poll_sks[0], obitsp); + } + + + if ((ret = select(max_fd + 1, ibitsp, obitsp, xbitsp, + (struct timeval *)0)) < 0) { + if (ret == -1) { + break; + } + } + + } + + if (remote_host) { + if (use_poll) { + temp_set = poll_fds[0].revents & POLLOUT; + temp_fd = poll_fds[0].fd; + } else { + temp_set = FD_ISSET(poll_sks[0], obitsp); + temp_fd = poll_sks[0]; + } + + if (temp_set) { + inter_outbuf = gen_message(poll_snd_size); + if (!inter_outbuf) { + fprintf(stderr, + "Cannot allocate out message.\n"); + exit(1); + } + iov.iov_base = inter_outbuf; + msglen = poll_snd_size; + iov.iov_len = msglen; + + error = sendmsg(temp_fd, &outmsg, 0); + fprintf(stderr, + "sent a message, msglen = %d\n", + msglen); + + if (error != msglen) { + fprintf(stderr, "%s: error: %s.\n", + argv0, strerror(errno)); + if ((!nonblocking) || + (EAGAIN != errno)) { + exit(1); + } + } + + /* Clean up. */ + free(inter_outbuf); + inter_outbuf = NULL; + } + + } /* while(!done) */ + + for (i = 0; !done && (i < poll_skn); i++) { + if (use_poll) { + temp_set = poll_fds[i].revents & POLLIN; + temp_fd = poll_fds[i].fd; + } else { + temp_set = FD_ISSET(poll_sks[i], ibitsp); + temp_fd = poll_sks[i]; + } + if (temp_set) { + error = recvmsg(temp_fd, &inmessage, + MSG_WAITALL); + if (error < 0) { + if ((EAGAIN == errno)) { + error = 0; + continue; + } + else { + fprintf(stderr, + "%s: error: %s.\n", + argv0, + strerror(errno)); + exit(1); + } + } + test_print_message(temp_fd, &inmessage, error); + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + iov.iov_len = REALLY_BIG; + } + + /* Update the associd when a notification is received + * on a UDP-style socket. + */ + if (inmessage.msg_flags & MSG_NOTIFICATION) + associd = test_verify_assoc_change(&inmessage); + + /* Verify there is no association. */ + if (0 != test_sk_for_assoc(poll_sks[i], associd)) { + printf("No association is present in sk " + "No.%d now!!\n",i); + } + } + + } + + if (!use_poll) { + free(ibitsp); + free(obitsp); + free(xbitsp); + } + + return error; + +} /* command_poll() */ + +/******************************************************************** + * 3rd Level Abstractions + ********************************************************************/ + +#define FPS(arg) fprintf(stderr, arg) + +void +usage(char *argv0) +{ + /* + * The bindx options, --bindx-add and --bindx-rem, are added to + * + * 1. provide first testcases for the new bindx system call + * + * 2. continue to grow sctp_darn with more functions and + * features so it will be equivalent to the "sock" tool for + * TCP as for SCTP. + * + * FIXME - + * + * It is not very effective to use these two options in the + * current command line mode of sctp_darn. For example, the + * --bindx-rem option can only be used in conjunction with the + * --bindx-add simply to test the function in the kernel + * path. Ideally, bindx needs to be tested by a tool which + * provides an interactive mode for users to change parameters + * and configuration dynamically with existing endpoints and + * associations. + */ + fprintf(stderr, "Usage: %s -H -P " + "[-h ] [-p ] -l|s\n" + " -H, --local\t\tspecify one of the local addresses,\n" + " -P, --local-port\tspecify the port number for local addresses,\n" + " -h, --remote\t\tspecify the peer address,\n" + " -p, --remote-port\tspecify the port number for the peer address,\n" + " -l, --listen\t\tprint messages received from the peer,\n" + " -s, --send\t\tsend messages to the peer,\n" + " -B, --bindx-add" + "\tadd the specified address(es) as additional bind\n" + "\t\t\taddresses to the local socket. Multiple addresses can\n" + "\t\t\tbe specified by using this argument multiple times.\n" + "\t\t\tFor example, '-B 10.0.0.1 -B 20.0.0.2'.\n" + " -b, --bindx-rem" + "\tremove the specified address(es) from the bind\n" + "\t\t\taddresses of the local socket. Multiple addresses can\n" + "\t\t\tbe specified by using this argument multiple times.\n" + "\t\t\tFor example, '-b 10.0.0.1 -b 20.0.0.2'.\n" + " -c, --connectx" + "\t\tuse the specified address(es) for connection to the\n" + "\t\t\tpeer socket. Multiple addresses can be specified by\n" + "\t\t\tusing this argument multiple times.\n" + "\t\t\tFor example, '-c 10.0.0.1 -c 20.0.0.2'.\n" + "\t\t\tThis option is incompatible with the -h option.\n" + " -I\t\t\tuse the interactive mode.\n" + " -i\t\t\tsetup the specified number of endpoints by using the\n" + "\t\t\tspecified local host (-H) and local port (-P). The port\n" + "\t\t\tnumber will be incremented by one for each additional\n" + "\t\t\tendpoint. All of these endpoints will be listening.\n" + "\t\t\tIf a remote host (-h) and a remote port are also\n" + "\t\t\tspecified, the first endpoint will start sending fixed\n" + "\t\t\tsized messages to the remote host.\n" + " -m\t\t\tspecify the sockopt sndbuf/rcvbuf size.\n" + " -n\t\t\tset the socket(s) to be in the non-blocking mode.\n" + "\t\t\tcollect messages from stdin and deliver them to the\n" + "\t\t\tpeer,\n" + "--use-poll\t\tuse system call poll() for polling among the\n" + "\t\t\tnumber of endpoints specified by the -i option. Without\n" + "\t\t\tthis option, select() would be used as default.\n" + " -t\t\t\tuse SOCK_STREAM tcp-style sockets.\n" + " -z\t\t\tspecify the message size to be sent. The default\n" + "\t\t\tmessage size generated would be 16K.\n" + " --interface=\"ifname\"\tselect interface for sin6_scope_id.\n", + argv0); +} + + +/* This function checks messages to see if they are of type 'event' + * and if they are well-formed. + */ +int +user_test_check_message(struct msghdr *msg, + int controllen, + sctp_cmsg_t event) +{ + + + if (msg->msg_controllen != controllen) { + fprintf(stderr, + "Got control structure of length %d, not %d\n", + msg->msg_controllen, controllen); + exit(1); + } + if (controllen > 0 && event != CMSG_FIRSTHDR(msg)->cmsg_type) { + fprintf(stderr, "Wrong kind of event: %d, not %d\n", + CMSG_FIRSTHDR(msg)->cmsg_type, event); + exit(1); + } + + return 1; + +} /* user_test_check_message() */ + +/* Add another address represented as the string 'parm' to the list + * addrs. The argument count is the number of addrs on input and is + * adjusted for output. + */ +struct sockaddr * +append_addr(const char *parm, struct sockaddr *addrs, int *ret_count) +{ + struct sockaddr *new_addrs = NULL; + void *aptr; + struct sockaddr *sa_addr; + struct sockaddr_in *b4ap; + struct sockaddr_in6 *b6ap; + struct hostent *hst4 = NULL; + struct hostent *hst6 = NULL; + int i4 = 0; + int i6 = 0; + int j; + int orig_count = *ret_count; + int count = orig_count; + + + /* Get the entries for this host. */ + hst4 = gethostbyname(parm); + hst6 = gethostbyname2(parm, AF_INET6); + + if ((NULL == hst4 || hst4->h_length < 1) + && (NULL == hst6 || hst6->h_length < 1)) { + fprintf(stderr, "bad hostname: %s\n", parm); + goto finally; + } + + + /* Figure out the number of addresses. */ + if (NULL != hst4) { + for (i4 = 0; NULL != hst4->h_addr_list[i4]; ++i4) { + count++; + } + } + if (NULL != hst6) { + for (i6 = 0; NULL != hst6->h_addr_list[i6]; ++i6) { + count++; + } + } + + /* Expand memory for the new addresses. Assume all the addresses + * are v6 addresses. + */ + new_addrs = (struct sockaddr *) + realloc(addrs, sizeof(struct sockaddr_in6) * count); + + if (NULL == new_addrs) { + count = *ret_count; + goto finally; + } + + /* Skip the existing addresses. */ + aptr = new_addrs; + for (j = 0; j < orig_count; j++) { + sa_addr = (struct sockaddr *)aptr; + switch(sa_addr->sa_family) { + case AF_INET: + aptr += sizeof(struct sockaddr_in); + break; + case AF_INET6: + aptr += sizeof(struct sockaddr_in6); + break; + default: + count = orig_count; + goto finally; + } + } + + /* Put the new addresses away. */ + if (NULL != hst4) { + for (j = 0; j < i4; ++j) { + b4ap = (struct sockaddr_in *)aptr; + bzero(b4ap, sizeof(*b4ap)); + b4ap->sin_family = AF_INET; + b4ap->sin_port = htons(local_port); + bcopy(hst4->h_addr_list[j], &b4ap->sin_addr, + hst4->h_length); + + aptr += sizeof(struct sockaddr_in); + } /* for (loop through the new v4 addresses) */ + } + + if (NULL != hst6) { + for (j = 0; j < i6; ++j) { + b6ap = (struct sockaddr_in6 *)aptr; + bzero(b6ap, sizeof(*b6ap)); + b6ap->sin6_family = AF_INET6; + b6ap->sin6_port = htons(local_port); + b6ap->sin6_scope_id = if_index; + bcopy(hst6->h_addr_list[j], &b6ap->sin6_addr, + hst6->h_length); + + aptr += sizeof(struct sockaddr_in6); + } /* for (loop through the new v6 addresses) */ + } + + finally: + + *ret_count = count; + + return new_addrs; + +} /* append_addr() */ + +static int +parse_inter_commands(char *argv0, char *input, int snd_only) +{ + int i; + char *p; + int len; + int set = 0; + int val; + struct sockaddr *tmp_addrs = NULL; + + + p = input; + if (*p == '?' || *p == '\n') { + printf("Interactive commands:\n"); + printf("snd= - Do a sendmsg with the specified"); + printf(" length.\n"); + printf("rcv= - Do a recvmsg."); + printf("The length is ignored for now.\n"); + printf("bindx-add= - Add a local address"); + printf(" with bindx. \n"); + printf("bindx-rem= - Remove a local address"); + printf(" with bindx. \n"); + printf("rcvbuf= - Get/Set receive buffer size\n"); + printf("sndbuf= - Get/Set send buffer size.\n"); + printf("primary= - Get/Set association's primary\n"); + printf("peer_primary=addr- Set association's peer_primary\n"); + printf("maxseg= - Get/Set Maximum fragment size.\n"); + printf("nodelay=<0|1> - Get/Set NODELAY option.\n"); + printf("shutdown - Shutdown the association.\n"); + printf("abort - Abort the association.\n"); + printf("? - Help. Display this message.\n"); + return -1; + } + + for (i = 0; i < REALLY_BIG; i++) { + if (('=' == *p) || + ('?' == *p) || + ('\n' == *p)) { + if ('=' == *p) { + set = 1; + } + *p++ = '\0'; + break; + } + p++; + } + if (i >= REALLY_BIG) { + printf("Invalid input.\n"); + return -1; + } + + i = 0; + while (NULL != inter_commands[i].cmd) { + if (!strcmp(input, inter_commands[i].cmd)) { + switch (i) { + case INTER_SND: + if (snd_only) { + if (*p < '0' || *p > '9') { + goto err_input; + } + snd_func(p); + } else { + goto err_input; + } + break; + case INTER_RCV: + if (snd_only) { + goto err_input; + } + break; + case INTER_SNDBUF: + if (set) { + if (*p < '0' || *p > '9') { + goto err_input; + } + } + len = (set) ? atoi(p) : 0; + sndbuf_func(argv0, inter_sk, len, set); + break; + case INTER_RCVBUF: + if (set) { + if (*p < '0' || *p > '9') { + goto err_input; + } + } + len = (set) ? atoi(p) : 0; + rcvbuf_func(argv0, inter_sk, len, set); + break; + case INTER_BINDX_ADD: + tmp_addrs = get_bindx_addr(p, &len); + bindx_func(argv0, inter_sk, tmp_addrs, len, + SCTP_BINDX_ADD_ADDR, local_port); + free(tmp_addrs); + break; + case INTER_BINDX_REM: + tmp_addrs = get_bindx_addr(p, &len); + bindx_func(argv0, inter_sk, tmp_addrs, len, + SCTP_BINDX_REM_ADDR, local_port); + free(tmp_addrs); + break; + case INTER_SET_PRIM: + primary_func(argv0, inter_sk, p, set); + break; + case INTER_SET_PEER_PRIM: + peer_primary_func(argv0, inter_sk, p, set); + break; + case INTER_SHUTDOWN: + shutdown_func(argv0, &inter_sk, SHUTDOWN_SHUTDOWN); + break; + case INTER_ABORT: + shutdown_func(argv0, &inter_sk, SHUTDOWN_ABORT); + break; + case INTER_NODELAY: + if (set) { + if (*p < '0' || *p > '9') { + goto err_input; + } + } + val = (set) ? atoi(p) : 0; + nodelay_func(argv0, inter_sk, val, set); + break; + case INTER_MAXSEG: + if (set) { + if (*p < '0' || *p > '9') { + goto err_input; + } + } + val = (set) ? atoi(p) : 0; + maxseg_func(argv0, inter_sk, val, set); + break; + default: + goto err_input; + break; + } + + return i; + } + i++; + } + +err_input: + printf("Invalid input.\n"); + return -1; + +} /* parse_inter_commands() */ + +static char * +gen_message(int len) +{ + + char *buf; + char *p; + int i; + + buf = malloc(len); + + if (NULL != buf) { + for (i = 0, p = buf; i < len; i++, p++) { + if (gen_data > GEN_DATA_LAST) { + gen_data = GEN_DATA_FIRST; + } + *p = gen_data++; + } + } + + return(buf); + +} /* gen_message() */ + +static void +snd_func(char *input) +{ + + int len; + + len = atoi(input); + if (!(inter_outbuf = gen_message(len))) { + fprintf(stderr, "Cannot allocate out message.\n"); + exit(1); + } + inter_outlen = len; + +} /* snd_func() */ + +static void +sndbuf_func(char *argv0, int sk, int len, int set) +{ + int error; + socklen_t optlen; + + if (set) { + error = setsockopt(sk, SOL_SOCKET, SO_SNDBUF, + (char *)&len, sizeof(len)); + } else { + optlen = sizeof(len); + error = getsockopt(sk, SOL_SOCKET, SO_SNDBUF, + (char *)&len, &optlen); + } + if (error != 0) { + fprintf(stderr, "%s: Error setting/getting sndbuf: %s.\n", + argv0, strerror(errno)); + exit(1); + } + + if (!set) { + printf("sndbuf is %d.\n", len); + } + +} /* sndbuf_func() */ + +static void +rcvbuf_func(char *argv0, int sk, int len, int set) +{ + int error; + socklen_t optlen; + + if (set) { + error = setsockopt(sk, SOL_SOCKET, SO_RCVBUF, + (char *)&len, sizeof(len)); + } else { + optlen = sizeof(len); + error = getsockopt(sk, SOL_SOCKET, SO_RCVBUF, + (char *)&len, &optlen); + } + if (error != 0) { + fprintf(stderr, "%s: Error setting/getting rcvbuf: %s.\n", + argv0, strerror(errno)); + exit(1); + } + + if (!set) { + printf("rcvbuf is %d.\n", len); + } + +} /* rcvbuf_func() */ + + +static struct sockaddr * +get_bindx_addr(char *in, int *count) +{ + + struct sockaddr *tmp_addrs = NULL; + char *p = in; + + /* Set the buffer for address parsing. */ + while ('\n' != *p) { + p++; + } + *p = '\0'; + + *count = 0; + + tmp_addrs = append_addr(in, tmp_addrs, count); + if (NULL == tmp_addrs) { + /* We have no memory, so keep fprintf() + * from trying to allocate more. + */ + fprintf(stderr, "No memory to add "); + fprintf(stderr, in); + fprintf(stderr, "\n"); + exit(2); + } + return tmp_addrs; + +} /* get_bindx_addr() */ + +static int +bindx_func(char *argv0, int sk, struct sockaddr *addrs, int count, int flag, int portnum) +{ + + int error; + int i; + struct sockaddr *sa_addr; + void *aptr; + + + if (0 == portnum) { + fprintf(stderr, "%s: A non-0 local port number is ", argv0); + fprintf(stderr, "required for bindx to work!\n"); + return -1 ; + } + + /* Set the port in every address. */ + aptr = addrs; + for (i = 0; i < count; i++) { + sa_addr = (struct sockaddr *)aptr; + + switch(sa_addr->sa_family) { + case AF_INET: + ((struct sockaddr_in *)sa_addr)->sin_port = + htons(portnum); + aptr += sizeof(struct sockaddr_in); + break; + case AF_INET6: + ((struct sockaddr_in6 *)sa_addr)->sin6_port = + htons(portnum); + aptr += sizeof(struct sockaddr_in6); + break; + default: + fprintf(stderr, "Invalid address family\n"); + return -1; + } + } + + error = sctp_bindx(sk, addrs, count, flag); + + if (error != 0) { + if (flag == SCTP_BINDX_ADD_ADDR) { + fprintf(stderr, "%s: error adding addrs: %s.\n", + argv0, strerror(errno)); + return -1; + } else { + fprintf(stderr, "%s: error removing addrs: %s.\n", + argv0, strerror(errno)); + return -1; + } + } + + return 0; + +} /* bindx_func() */ + +static int +connectx_func(char *argv0, int sk, struct sockaddr *addrs, int count) +{ + + int error; + int i; + struct sockaddr *sa_addr; + void *aptr; + + + if (0 == remote_port) { + fprintf(stderr, "%s: A non-0 remote port number is ", argv0); + fprintf(stderr, "required for connectx to work!\n"); + return -1 ; + } + + /* Set the port in every address. */ + aptr = addrs; + for (i = 0; i < count; i++) { + sa_addr = (struct sockaddr *)aptr; + + switch(sa_addr->sa_family) { + case AF_INET: + ((struct sockaddr_in *)sa_addr)->sin_port = + htons(remote_port); + aptr += sizeof(struct sockaddr_in); + break; + case AF_INET6: + ((struct sockaddr_in6 *)sa_addr)->sin6_port = + htons(remote_port); + aptr += sizeof(struct sockaddr_in6); + break; + default: + fprintf(stderr, "Invalid address family\n"); + return -1; + } + } + + error = sctp_connectx(sk, addrs, count, NULL); + + if (error != 0) { + if (errno == ECONNREFUSED) + return -2; + fprintf(stderr, "%s: error connecting to addrs: %s.\n", + argv0, strerror(errno)); + return -1; + } + + return 0; + +} /* connectx_func() */ + +static void +primary_func(char *argv0, int sk, char *cp, int set) +{ + struct sctp_prim prim; + struct sockaddr_in *in_addr; + struct sockaddr_in6 *in6_addr; + struct sockaddr *saddr; + socklen_t prim_len; + int ret; + char *p = cp; + char addr_buf[INET6_ADDRSTRLEN]; + const char *ap = NULL; + + prim_len = sizeof(struct sctp_prim); + if (!set) { + prim.ssp_assoc_id = associd; + ret = getsockopt(sk, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, + &prim, &prim_len); + if (ret < 0) + goto err; + + saddr = (struct sockaddr *)&prim.ssp_addr; + if (AF_INET == saddr->sa_family) { + in_addr = (struct sockaddr_in *)&prim.ssp_addr; + ap = inet_ntop(AF_INET, &in_addr->sin_addr, addr_buf, + INET6_ADDRSTRLEN); + } else if (AF_INET6 == saddr->sa_family) { + in6_addr = (struct sockaddr_in6 *)&prim.ssp_addr; + ap = inet_ntop(AF_INET6, &in6_addr->sin6_addr, addr_buf, + INET6_ADDRSTRLEN); + } + if (!ap) + goto err; + printf("%s\n", ap); + return; + } + + /* Set the buffer for address parsing. */ + while ('\n' != *p) + p++; + *p = '\0'; + + prim.ssp_assoc_id = associd; + if (strchr(cp, '.')) { + in_addr = (struct sockaddr_in *)&prim.ssp_addr; + in_addr->sin_port = htons(remote_port); + in_addr->sin_family = AF_INET; + ret = inet_pton (AF_INET, cp, &in_addr->sin_addr); + if (ret <= 0) + goto err; + } else if (strchr(cp, ':')) { + in6_addr = (struct sockaddr_in6 *)&prim.ssp_addr; + in6_addr->sin6_port = htons(remote_port); + in6_addr->sin6_family = AF_INET6; + ret = inet_pton(AF_INET6, cp, &in6_addr->sin6_addr); + if (ret <= 0) + goto err; + } else + goto err; + + ret = setsockopt(sk, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, + &prim, sizeof(struct sctp_prim)); + if (ret < 0) + goto err; + + return; +err: + if (!errno) + errno = EINVAL; + fprintf(stderr, "%s: error %s primary: %s.\n", argv0, + (set)?"setting":"getting", strerror(errno)); +} + +static void +peer_primary_func(char *argv0, int sk, char *cp, int set) +{ + struct sctp_setpeerprim setpeerprim; + struct sockaddr_in *in_addr; + struct sockaddr_in6 *in6_addr; + int peer_prim_len, ret; + char *p = cp; + + if (!set) { + goto err; + } + + peer_prim_len = sizeof(struct sctp_setpeerprim); + /* Set the buffer for address parsing. */ + while ('\n' != *p) + p++; + *p = '\0'; + + setpeerprim.sspp_assoc_id = associd; + if (strchr(cp, '.')) { + in_addr = (struct sockaddr_in *)&setpeerprim.sspp_addr; + in_addr->sin_port = htons(local_port); + in_addr->sin_family = AF_INET; + ret = inet_pton (AF_INET, cp, &in_addr->sin_addr); + if (ret <= 0) + goto err; + } else if (strchr(cp, ':')) { + in6_addr = (struct sockaddr_in6 *)&setpeerprim.sspp_addr; + in6_addr->sin6_port = htons(local_port); + in6_addr->sin6_family = AF_INET6; + ret = inet_pton(AF_INET6, cp, &in6_addr->sin6_addr); + if (ret <= 0) + goto err; + } else + goto err; + + ret = setsockopt(sk, IPPROTO_SCTP, SCTP_SET_PEER_PRIMARY_ADDR, + &setpeerprim, sizeof(struct sctp_setpeerprim)); + if (ret < 0) + goto err; + + return; +err: + if (!errno) + errno = EINVAL; + fprintf(stderr, "%s: error %s peer_primary: %s.\n", argv0, + (set)?"setting":"getting", strerror(errno)); +} + +static int +nodelay_func(char *argv0, int sk, int val, int set) +{ + socklen_t optlen; + int error; + + if (set) { + error = setsockopt(sk, SOL_SCTP, SCTP_NODELAY, + (char *)&val, sizeof(val)); + } else { + optlen = sizeof(val); + error = getsockopt(sk, SOL_SCTP, SCTP_NODELAY, + (char *)&val, &optlen); + } + if (error != 0) { + fprintf(stderr, "%s: Error setting/getting nodelay: %s.\n", + argv0, strerror(errno)); + exit(1); + } + + if (!set) { + printf("nodelay is %d.\n", val); + } + + return error; +} + +static int +maxseg_func(char *argv0, int sk, int val, int set) +{ + socklen_t optlen; + int error; + + if (set) { + error = setsockopt(sk, SOL_SCTP, SCTP_MAXSEG, + (char *)&val, sizeof(val)); + } else { + optlen = sizeof(val); + error = getsockopt(sk, SOL_SCTP, SCTP_MAXSEG, + (char *)&val, &optlen); + } + if (error != 0) { + fprintf(stderr, "%s: Error setting/getting maxseg: %s.\n", + argv0, strerror(errno)); + exit(1); + } + + if (!set) { + printf("maxseg is %d.\n", val); + } + + return error; +} + +static int +shutdown_func(char *argv0, int *skp, int shutdown_type) +{ + struct msghdr outmessage; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + int error=0, bytes_sent; + struct sctp_sndrcvinfo *sinfo; + struct hostent *hst; + char *sd_type; + int sk = *skp; + + if (shutdown_type == SHUTDOWN_ABORT) + sd_type = "ABORT"; + else + sd_type = "SHUTDOWN"; + + /* Verify that the association is present. */ + error = test_sk_for_assoc(sk, associd); + if (error != 0) { + printf("The association isn't present yet! Cannot %s!\n", sd_type); + return -1; + } + + if (socket_type == SOCK_SEQPACKET) { + /* Set up the destination. */ + if (remote_host) { + hst = gethostbyname(remote_host); + if (hst == NULL) { + hst = gethostbyname2(remote_host, AF_INET6); + } + + if (hst == NULL || hst->h_length < 1) { + fprintf(stderr, "%s: bad hostname: %s\n", + argv0, remote_host); + exit(1); + } + + ra_family = hst->h_addrtype; + switch (ra_family) { + case AF_INET: + ra_len = sizeof(remote_addr.v4); + ra_raw = &remote_addr.v4.sin_addr; + remote_addr.v4.sin_port = htons(remote_port); + remote_addr.v4.sin_family = AF_INET; + break; + case AF_INET6: + ra_len = sizeof(remote_addr.v6); + ra_raw = &remote_addr.v6.sin6_addr; + remote_addr.v6.sin6_port = htons(remote_port); + remote_addr.v6.sin6_family = AF_INET6; + break; + default: + fprintf(stderr, "Invalid address type.\n"); + exit(1); + break; + } + memcpy(ra_raw, hst->h_addr_list[0], hst->h_length); + } + + /* Initialize the message struct we use to pass messages to + * the remote socket. + */ + outmessage.msg_name = &remote_addr; + outmessage.msg_namelen = ra_len; + + outmessage.msg_iov = NULL; + outmessage.msg_iovlen = 0; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + if (shutdown_type == SHUTDOWN_ABORT) + sinfo->sinfo_flags |= SCTP_ABORT; + else + sinfo->sinfo_flags |= SCTP_EOF; + + sinfo->sinfo_assoc_id = associd; + + bytes_sent = sendmsg(sk, &outmessage, 0); + if (bytes_sent != 0) { + printf("Failure: %s.\n", strerror(errno)); + return -1; + } + + /* Receive the COMM_LOST or SHUTDOWN_COMP event. */ + test_recv_assoc_change(sk); + } else { + if (shutdown_type == SHUTDOWN_ABORT) { + struct linger { + int l_onoff; + int l_linger; + } data = {1, 0}; + error = setsockopt(sk, SOL_SOCKET, SO_LINGER, + (char *)&data, sizeof(data)); + if (error != 0) { + printf("setsockopt failed %s\n", strerror(errno)); + exit(1); + } + } + error = close(sk); + if (error != 0) { + printf("close failed %s\n", strerror(errno)); + exit(1); + } + *skp = sk = build_endpoint(argv0, local_port); + } + + /* Verify that the association is no longer present. */ + error = test_sk_for_assoc(sk, associd); + if (error != 0) { + printf("Successfully %s the original association\n", sd_type); + associd = 0; + new_connection = 1; + } else { + printf("%s failed\n", sd_type); + exit(1); + } + + return 0; +} + +static int +test_sk_for_assoc(int sk, sctp_assoc_t assoc_id) +{ + int error = 0; + struct sctp_status status; + socklen_t status_len; + + memset(&status, 0, sizeof(status)); + if (assoc_id) + status.sstat_assoc_id = assoc_id; + status_len = sizeof(struct sctp_status); + error = getsockopt(sk, SOL_SCTP, SCTP_STATUS, + (char *)&status, &status_len); + return error; +} + +/* Receive a notification and return the corresponding associd if the event is + * SCTP_COMM_UP. Return 0 for any other event. + */ +static sctp_assoc_t +test_recv_assoc_change(int sk) +{ + struct msghdr inmessage; + struct iovec iov; + char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))]; + int error; + + /* Initialize inmessage with enough space for DATA... */ + memset(&inmessage, 0, sizeof(inmessage)); + if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) { + printf("%s: Can't allocate memory.\n", __FUNCTION__); + exit(1); + } + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + /* or a control message. */ + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + + error = recvmsg(sk, &inmessage, MSG_WAITALL); + if (error < 0) { + printf("%s: recvmsg: %s\n", __FUNCTION__, strerror(errno)); + exit(1); + } + + return test_verify_assoc_change(&inmessage); +} + +/* Verify a notification and return the corresponding associd if the event is + * SCTP_COMM_UP. Return 0 for any other event. + */ +static sctp_assoc_t +test_verify_assoc_change(struct msghdr *msg) +{ + union sctp_notification *sn; + + if (!(msg->msg_flags & MSG_NOTIFICATION)) { + fprintf(stderr, "%s: Received data when notification is expected\n", + __FUNCTION__); + exit(1); + } + + sn = (union sctp_notification *)msg->msg_iov->iov_base; + if (SCTP_ASSOC_CHANGE != sn->sn_header.sn_type) { + fprintf(stderr, "%s: Received unexpected notification: %d", + __FUNCTION__, sn->sn_header.sn_type); + exit(1); + } + + switch(sn->sn_assoc_change.sac_state) + { + case SCTP_COMM_UP: + printf("Recieved SCTP_COMM_UP\n"); + break; + case SCTP_COMM_LOST: + printf("Recieved SCTP_COMM_LOST\n"); + break; + case SCTP_RESTART: + printf("Recieved SCTP_RESTART\n"); + break; + case SCTP_SHUTDOWN_COMP: + printf("Recieved SCTP_SHUTDOWN_COMP\n"); + break; + case SCTP_CANT_STR_ASSOC: + printf("Recieved SCTP_CANT_STR_ASSOC\n"); + break; + } + + if (SCTP_COMM_UP == sn->sn_assoc_change.sac_state) + return sn->sn_assoc_change.sac_assoc_id; + else + return 0; +} + +void print_addr_buf(void * laddrs, int n_laddrs) +{ + void *addr_buf = laddrs; + int i; + + for (i = 0; i < n_laddrs; i++) { + addr_buf += print_sockaddr((struct sockaddr *)addr_buf); + printf("\n"); + } +} + +int print_sockaddr(struct sockaddr *sa_addr) +{ + struct sockaddr_in *in_addr; + struct sockaddr_in6 *in6_addr; + + if (AF_INET == sa_addr->sa_family) { + in_addr = (struct sockaddr_in *)sa_addr; + printf("%d.%d.%d.%d:%d", + NIPQUAD(in_addr->sin_addr), + ntohs(in_addr->sin_port)); + return sizeof(struct sockaddr_in); + } else { + in6_addr = (struct sockaddr_in6 *)sa_addr; + printf("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%d", + NIP6(in6_addr->sin6_addr), + ntohs(in6_addr->sin6_port)); + return sizeof(struct sockaddr_in6); + } +} diff --git a/src/apps/sctp_darn.h b/src/apps/sctp_darn.h new file mode 100644 index 0000000..e2c1ef1 --- /dev/null +++ b/src/apps/sctp_darn.h @@ -0,0 +1,29 @@ +#ifndef __sctp_darn_h__ +#define __sctp_darn_h__ + +#define REALLY_BIG 65536 +#define SCTP_TESTPORT_1 1 +#define SCTP_TESTPORT_2 2 + +void parse_arguments(int argc, char *argv[]); +void usage(char *argv0); +int command_listen(char *arg0, int sk); +int command_send(char *arg0, int *skp); +int command_poll(char *arg0); +int test_print_message(int sk, struct msghdr *, size_t msg_len); + +typedef enum { + COMMAND_NONE = 0, + COMMAND_LISTEN, + COMMAND_SEND, + COMMAND_POLL, +} command_t; + +typedef union { + struct sockaddr_storage ss; + struct sockaddr_in v4; + struct sockaddr_in6 v6; + struct sockaddr sa; +} sockaddr_storage_t; + +#endif /* __sctp_darn_h__ */ diff --git a/src/apps/sctp_status.c b/src/apps/sctp_status.c new file mode 100644 index 0000000..ff30a9e --- /dev/null +++ b/src/apps/sctp_status.c @@ -0,0 +1,908 @@ +/* SCTP kernel reference Implementation + * (C) Copyright Fujitsu Ltd. 2008, 2009 + * + * The SCTP reference implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP reference implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Wei Yongjun + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_SEC 0 +#define DEFAULT_USEC 5000 + +#define REALLY_BIG 65536 + +#define SERVER 0 +#define CLIENT 1 +#define NOT_DEFINED 666 + +#define DEBUG_NONE 0 +#define DEBUG_MIN 1 +#define DEBUG_MAX 2 + +#define ORDER_PATTERN_UNORDERED 0 +#define ORDER_PATTERN_ORDERED 1 +#define ORDER_PATTERN_ALTERNATE 2 +#define ORDER_PATTERN_RANDOM 3 + +#define STREAM_PATTERN_SEQUENTIAL 0 +#define STREAM_PATTERN_RANDOM 1 + +#define MAX_BIND_RETRYS 10 +#define BIG_REPEAT 1000000 +#define REPEAT 10 + +#define DEFAULT_MAX_WINDOW 32768 +#define DEFAULT_MIN_WINDOW 1500 + +#define MSG_CNT 10 + +#define DEBUG_PRINT(level, print_this...) \ +{ \ + if (debug_level >= level) { \ + fprintf(stdout, print_this); \ + fflush(stdout); \ + } \ +} /* DEBUG_PRINT */ + +char *local_host = NULL; +int local_port = 0; +char *remote_host = NULL; +int remote_port = 0; +struct sockaddr_storage s_rem, s_loc; +int r_len, l_len; +int size_arg = 0; +int debug_level = DEBUG_NONE; +int order_pattern = ORDER_PATTERN_UNORDERED; +int order_state = 0; +int stream_pattern = STREAM_PATTERN_SEQUENTIAL; +int stream_state = 0; +int repeat = REPEAT; +int repeat_count = 0; +int max_msgsize = DEFAULT_MAX_WINDOW; +int msg_cnt = MSG_CNT; +int drain = 0; +int max_stream = 0; +int gsk = -1; +int period = 1; +char *statusfile = NULL; + +void printstatus(int sk); +void sighandler(int signo); +void settimerhandle(void); +void usage(char *argv0); +void start_test(int role); + +unsigned char msg[] = "012345678901234567890123456789012345678901234567890"; + +/* Convenience structure to determine space needed for cmsg. */ +typedef union { + struct sctp_initmsg init; + struct sctp_sndrcvinfo sndrcvinfo; +} _sctp_cmsg_data_t; + +int main(int argc, char *argv[]) { + int c, role = NOT_DEFINED; + char *interface = NULL; + struct sockaddr_in *t_addr; + struct sockaddr_in6 *t_addr6; + + /* Parse the arguments. */ + while ((c = getopt(argc, argv, ":H:L:P:h:p:c:d:lm:sx:X:o:M:r:Di:I:f:")) >= 0 ) { + switch (c) { + case 'H': + local_host = optarg; + break; + case 'P': + local_port = atoi(optarg); + break; + case 'h': + remote_host = optarg; + break; + case 'p': + remote_port = atoi(optarg); + break; + case 'l': + if (role != NOT_DEFINED) { + printf("%s: only -s or -l\n", argv[0]); + usage(argv[0]); + exit(1); + } + role = SERVER; + break; + case 's': + if (role != NOT_DEFINED) { + printf("%s: only -s or -l\n", argv[0]); + usage(argv[0]); + exit(1); + } + role = CLIENT; + break; + case 'D': + drain = 1; + break; + case 'd': + debug_level = atoi(optarg); + if (debug_level < DEBUG_NONE + || debug_level > DEBUG_MAX) { + usage(argv[0]); + exit(1); + } + break; + case 'I': + period = atoi(optarg); + if (period < 0) { + usage(argv[0]); + exit(1); + } + break; + case 'x': + repeat = atoi(optarg); + if (!repeat) { + repeat = BIG_REPEAT; + } + break; + case 'X': + msg_cnt = atoi(optarg); + if ((msg_cnt <= 0) || (msg_cnt > MSG_CNT)) { + usage(argv[0]); + exit(1); + } + break; + case 'c': + size_arg = atoi(optarg); + if (size_arg < 0) { + usage(argv[0]); + exit(1); + } + + break; + case 'o': + order_pattern = atoi(optarg); + if (order_pattern < ORDER_PATTERN_UNORDERED + || order_pattern > ORDER_PATTERN_RANDOM ) { + usage(argv[0]); + exit(1); + } + break; + case 'M': + max_stream = atoi(optarg); + if (max_stream < 0 + || max_stream >= (1<<16)) { + usage(argv[0]); + exit(1); + } + break; + case 'm': + max_msgsize = atoi(optarg); + break; + case 'i': + interface = optarg; + break; + case 'f': + statusfile = optarg; + break; + case '?': + default: + usage(argv[0]); + exit(0); + } + } /* while() */ + + if (NOT_DEFINED == role) { + usage(argv[0]); + exit(1); + } + + if (SERVER == role && NULL == local_host && remote_host != NULL) { + fprintf(stderr, "%s: Server needs local address, " + "not remote address\n", argv[0]); + usage(argv[0]); + exit(1); + } + if (CLIENT == role && NULL == remote_host) { + fprintf(stderr, "%s: Client needs at least remote address " + "& port\n", argv[0]); + usage(argv[0]); + exit(1); + } + + if (optind < argc) { + fprintf(stderr, "%s: non-option arguments are illegal: ", argv[0]); + while (optind < argc) + fprintf(stderr, "%s ", argv[optind++]); + fprintf (stderr, "\n"); + usage(argv[0]); + exit(1); + } + + if (remote_host != NULL && remote_port != 0) { + struct addrinfo *res; + int error; + char *host_s, *serv_s; + + if ((host_s = malloc(NI_MAXHOST)) == NULL) { + fprintf(stderr, "\n*** host_s malloc failed!!! ***\n"); + exit(1); + } + if ((serv_s = malloc(NI_MAXSERV)) == NULL) { + fprintf(stderr, "\n*** serv_s malloc failed!!! ***\n"); + exit(1); + } + + error = getaddrinfo(remote_host, 0, NULL, &res); + if (error) { + printf("%s.\n", gai_strerror(error)); + usage(argv[0]); + exit(1); + } + + switch (res->ai_family) { + case AF_INET: + t_addr = (struct sockaddr_in *)&s_rem; + + t_addr->sin_family = AF_INET; + t_addr->sin_port = htons(remote_port); + inet_pton(AF_INET, remote_host, &t_addr->sin_addr); + + r_len = sizeof (struct sockaddr_in); +#ifdef __FreeBSD__ + t_addr->sin_len = r_len; +#endif + break; + case AF_INET6: + t_addr6 = (struct sockaddr_in6 *)&s_rem; + + if (interface) + t_addr6->sin6_scope_id = if_nametoindex(interface); + t_addr6->sin6_family = AF_INET6; + t_addr6->sin6_port = htons(remote_port); + inet_pton(AF_INET6, remote_host, &t_addr6->sin6_addr); + + r_len = sizeof (struct sockaddr_in6); + +#ifdef __FreeBSD__ + t_addr6->sin6_len = r_len; +#endif + break; + } + + getnameinfo((struct sockaddr *)&s_rem, r_len, host_s, + NI_MAXHOST, serv_s, NI_MAXSERV, NI_NUMERICHOST); + + DEBUG_PRINT(DEBUG_MAX, "remote:addr=%s, port=%s, family=%d\n", + host_s, serv_s, res->ai_family); + } + + if (local_host != NULL) { + struct addrinfo *res; + int error; + char *host_s, *serv_s; + struct sockaddr_in *t_addr; + struct sockaddr_in6 *t_addr6; + + if ((host_s = malloc(NI_MAXHOST)) == NULL) { + fprintf(stderr, "\n*** host_s malloc failed!!! ***\n"); + exit(1); + } + if ((serv_s = malloc(NI_MAXSERV)) == NULL) { + fprintf(stderr, "\n*** serv_s malloc failed!!! ***\n"); + exit(1); + } + + if (strcmp(local_host, "0") == 0) + local_host = "0.0.0.0"; + + error = getaddrinfo(local_host, 0, NULL, &res); + if (error) { + printf("%s.\n", gai_strerror(error)); + usage(argv[0]); + exit(1); + } + + switch (res->ai_family) { + case AF_INET: + t_addr = (struct sockaddr_in *)&s_loc; + t_addr->sin_family = AF_INET; + t_addr->sin_port = htons(local_port); + inet_pton(AF_INET, local_host, &t_addr->sin_addr); + + l_len = sizeof (struct sockaddr_in); +#ifdef __FreeBSD__ + t_addr->sin_len = l_len; +#endif + break; + case AF_INET6: + t_addr6 = (struct sockaddr_in6 *)&s_loc; + + if (interface) + t_addr6->sin6_scope_id = if_nametoindex(interface); + t_addr6->sin6_family = AF_INET6; + t_addr6->sin6_port = htons(local_port); + + inet_pton(AF_INET6, local_host, &t_addr6->sin6_addr); + + l_len = sizeof (struct sockaddr_in6); + +#ifdef __FreeBSD__ + t_addr6->sin6_len = l_len; +#endif + break; + } + + error = getnameinfo((struct sockaddr *)&s_loc, l_len, host_s, + NI_MAXHOST, serv_s, NI_MAXSERV, NI_NUMERICHOST); + + if (error) + printf("%s..\n", gai_strerror(error)); + + DEBUG_PRINT(DEBUG_MAX, "local:addr=%s, port=%s, family=%d\n", + host_s, serv_s, res->ai_family); + } + + /* Let the testing begin. */ + start_test(role); + + return 0; +} + +int bind_r(int sk, struct sockaddr_storage *saddr) { + int error = 0, i = 0; + char *host_s, *serv_s; + + if ((host_s = malloc(NI_MAXHOST)) == NULL) { + fprintf(stderr, "\n\t\t*** host_s malloc failed!!! ***\n"); + exit(1); + } + if ((serv_s = malloc(NI_MAXSERV)) == NULL) { + fprintf(stderr, "\n\t\t*** serv_s malloc failed!!! ***\n"); + exit(1); + } + + do { + if (i > 0) sleep(1); /* sleep a while before new try... */ + + error = getnameinfo((struct sockaddr *)saddr, l_len, host_s, + NI_MAXHOST, serv_s, NI_MAXSERV, + NI_NUMERICHOST); + + if (error) + printf("%s\n", gai_strerror(error)); + + DEBUG_PRINT(DEBUG_MIN, + "\tbind(sk=%d, [a:%s,p:%s]) -- attempt %d/%d\n", + sk, host_s, serv_s, i+1, MAX_BIND_RETRYS); + + error = bind(sk, (struct sockaddr *)saddr, l_len); + + if (error != 0) { + if( errno != EADDRINUSE ) { + fprintf(stderr, "\n\n\t\t***bind: can " + "not bind to %s:%s: %s ****\n", + host_s, serv_s, strerror(errno)); + exit(1); + } + } + i++; + if (i >= MAX_BIND_RETRYS) { + fprintf(stderr, "Maximum bind() attempts. " + "Die now...\n\n"); + exit(1); + } + } while (error < 0 && i < MAX_BIND_RETRYS); + + return 0; +} /* bind_r() */ + +int listen_r(int sk, int listen_count) { + int error = 0; + + DEBUG_PRINT(DEBUG_MIN, "\tlisten(sk=%d,backlog=%d)\n", + sk, listen_count); + + /* Mark sk as being able to accept new associations */ + error = listen(sk, 1); + if (error != 0) { + fprintf(stderr, "\n\n\t\t*** listen: %s ***\n\n\n", strerror(errno)); + exit(1); + } + + return 0; +} /* listen_r() */ + +int accept_r(int sk){ + socklen_t len = 0; + + DEBUG_PRINT(DEBUG_MIN, "\taccept(sk=%d)\n", sk); + + gsk = accept(sk, NULL, &len); + if (gsk < 0) { + fprintf(stderr, "\n\n\t\t*** accept: %s ***\n\n\n", strerror(errno)); + exit(1); + } + + return 0; +} /* accept_r() */ + +int connect_r(int sk, const struct sockaddr *serv_addr, socklen_t addrlen) { + int error = 0; + + DEBUG_PRINT(DEBUG_MIN, "\tconnect(sk=%d)\n", sk); + + /* Mark sk as being able to accept new associations */ + error = connect(sk, serv_addr, addrlen); + if (error != 0) { + fprintf(stderr, "\n\n\t\t*** connect: %s ***\n\n\n", + strerror(errno)); + exit(1); + } + + gsk = sk; + + return 0; +} /* connect_r() */ + +int close_r(int sk) { + int error = 0; + + DEBUG_PRINT(DEBUG_MIN, "\tclose(sk=%d)\n",sk); + + error = close(sk); + if (error != 0) { + fprintf(stderr, "\n\n\t\t*** close: %s ***\n\n", + strerror(errno)); + exit(1); + } + fflush(stdout); + return 0; +} /* close_r() */ + +int receive_r(int sk) +{ + int error = 0; + char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))]; + struct iovec iov; + struct msghdr inmessage; + + /* Initialize inmessage with enough space for DATA... */ + memset(&inmessage, 0, sizeof(inmessage)); + if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) { + fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n"); + exit(1); + } + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + /* or a control message. */ + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + + /* Get the messages sent */ + while (1) { + DEBUG_PRINT(DEBUG_MIN, "\trecvmsg(sk=%d) ", sk); + + error = recvmsg(sk, &inmessage, MSG_WAITALL); + if (error < 0 && error != EAGAIN) { + fprintf(stderr, "\n\t\t*** recvmsg: %s ***\n\n", + strerror(errno)); + fflush(stdout); + close(sk); + free(iov.iov_base); + exit(1); + } else if (error == 0) { + printf("\n\t\trecvmsg() returned 0 !!!!\n"); + fflush(stdout); + } + + if(MSG_NOTIFICATION & inmessage.msg_flags) + continue; /* got a notification... */ + + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + iov.iov_len = REALLY_BIG; + break; + } + + free(iov.iov_base); + return 0; +} /* receive_r () */ + +void server(int sk) { + if (max_msgsize > DEFAULT_MAX_WINDOW) { + if (setsockopt(sk, IPPROTO_SCTP, SO_RCVBUF, &max_msgsize, + sizeof(max_msgsize)) < 0) { + perror("setsockopt(SO_RCVBUF)"); + exit(1); + } + } + + receive_r(sk); +} /* server() */ + +void * build_msg(int len) { + int i = len - 1; + int n; + char *msg_buf, *p; + + msg_buf = malloc(len); + if (NULL == msg_buf) { + fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n"); + exit(1); + } + p = msg_buf; + + do { + n = ((i > 50)?50:i); + memcpy(p, msg, ((i > 50)?50:i)); + p += n; + i -= n; + } while (i > 0); + + msg_buf[len-1] = '\0'; + + return(msg_buf); + +} /* build_msg() */ + +int send_r(int sk, int stream, int order, int send_size, int assoc_i) { + int error = 0; + struct msghdr outmsg; + struct iovec iov; + char *message = NULL; + int msglen = 0; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + + if (send_size > 0) { + message = build_msg(send_size); + msglen = strlen(message) + 1; + iov.iov_base = message; + iov.iov_len = msglen; + } else { + exit(1); + } + + outmsg.msg_name = &s_rem; + outmsg.msg_namelen = sizeof(struct sockaddr_storage); + outmsg.msg_iov = &iov; + outmsg.msg_iovlen = 1; + outmsg.msg_control = outcmsg; + outmsg.msg_controllen = sizeof(outcmsg); + outmsg.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&outmsg); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + + outmsg.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo)); + sinfo->sinfo_ppid = rand(); + sinfo->sinfo_stream = stream; + sinfo->sinfo_flags = 0; + if (!order) + sinfo->sinfo_flags = SCTP_UNORDERED; + + DEBUG_PRINT(DEBUG_MIN, "\tsendmsg(sk=%d, assoc=%d) %4d bytes.\n", + sk, assoc_i, send_size); + DEBUG_PRINT(DEBUG_MAX, "\t SNDRCV"); + if (DEBUG_MAX == debug_level) { + printf("(stream=%u ", sinfo->sinfo_stream); + printf("flags=0x%x ", sinfo->sinfo_flags); + printf("ppid=%u)\n", sinfo->sinfo_ppid); + } + + /* Send to our neighbor. */ + error = sendmsg(sk, &outmsg, MSG_WAITALL); + if (error != msglen) { + fprintf(stderr, "\n\t\t*** sendmsg: %s ***\n\n", + strerror(errno)); + fflush(stdout); + exit(1); + } + + if (send_size > 0) free(message); + return 0; +} /* send_r() */ + +int next_order(int state, int pattern) +{ + switch (pattern){ + case ORDER_PATTERN_UNORDERED: + state = 0; + break; + case ORDER_PATTERN_ORDERED: + state = 1; + break; + case ORDER_PATTERN_ALTERNATE: + state = state ? 0 : 1; + break; + case ORDER_PATTERN_RANDOM: + state = rand() % 2; + break; + } + + return state; +} + +int next_stream(int state, int pattern) +{ + switch (pattern){ + case STREAM_PATTERN_RANDOM: + state = rand() % (max_stream + 1); + break; + case STREAM_PATTERN_SEQUENTIAL: + state = state + 1; + if (state > max_stream) + state = 0; + break; + } + + return state; +} + +int next_msg_size(int msg_cnt) +{ + int msg_size; + + if (size_arg) { + msg_size = size_arg; + } else { + msg_size = (rand() % max_msgsize) + 1; + } + + return msg_size; + +} /* next_msg_size() */ + +void client(int sk) { + int msg_size; + int i; + + for (i = 0; i < msg_cnt; i++) { + msg_size = next_msg_size(i); + order_state = next_order(order_state, order_pattern); + stream_state = next_stream(stream_state, stream_pattern); + + if (send_r(sk, stream_state, order_state, msg_size, 0) < 0) { + close(sk); + break; + } + + /* The sender is echoing so do discard the echoed data. */ + if (drain && ((i + 1) % period == 0)) { + receive_r(sk); + } + } +} /* client() */ + +void start_test(int role) { + int sk, pid; + int i = 0; + + DEBUG_PRINT(DEBUG_NONE, "\nStarting tests...\n"); + + repeat_count = repeat; + + DEBUG_PRINT(DEBUG_MIN, "\tsocket(SOCK_STREAM, IPPROTO_SCTP)"); + + if ((sk = socket(s_loc.ss_family, SOCK_STREAM, IPPROTO_SCTP)) < 0 ) { + fprintf(stderr, "\n\n\t\t*** socket: failed to create" + " socket: %s ***\n", strerror(errno)); + exit(1); + } + DEBUG_PRINT(DEBUG_MIN, " -> sk=%d\n", sk); + + bind_r(sk, &s_loc); + + if (role == SERVER) { + listen_r(sk, 1); + accept_r(sk); + } else { + connect_r(sk, (struct sockaddr *)&s_rem, r_len); + } + + if ((pid = fork()) == 0) { + settimerhandle(); + printstatus(gsk); + while(1); + } else { + if (!debug_level) { + printf(" "); + } + + for(i = 0; i < repeat_count; i++) { + + if (role == SERVER) { + DEBUG_PRINT(DEBUG_NONE, "Server: Receiving packets.(%d/%d)\n", + i+1, repeat_count); + server(gsk); + } else { + DEBUG_PRINT(DEBUG_NONE, "Client: Sending packets.(%d/%d)\n", + i+1, repeat_count); + client(sk); + } + + fflush(stdout); + } + + if (role == SERVER) close_r(gsk); + close_r(sk); + } +} /* start_test() */ + +void settimerhandle(void) { + struct sigaction act; + struct itimerval interval; + + act.sa_handler = sighandler; + act.sa_flags = 0; + sigemptyset(&act.sa_mask); + sigaction(SIGPROF, &act, NULL); + + interval.it_value.tv_sec = DEFAULT_SEC; + interval.it_value.tv_usec = DEFAULT_USEC; + interval.it_interval = interval.it_value; + + setitimer(ITIMER_PROF, &interval, NULL); +} + +void usage(char *argv0) { + fprintf(stderr, "\nusage:\n"); + fprintf(stderr, " server:\n"); + fprintf(stderr, " %8s -H local-addr -P local-port -l [-d level] [-x]\n" + "\t [-L num-ports] [-S num-ports]\n" + "\t [-a assoc-pattern]\n" + "\t [-i interface]\n" + "\t [-f status-file]\n", + argv0); + fprintf(stderr, "\n"); + fprintf(stderr, " client:\n"); + fprintf(stderr, " %8s -H local-addr -P local-port -h remote-addr\n" + "\t -p remote-port -s [-c case ] [-d level]\n" + "\t [-x repeat] [-o order-pattern] ream-pattern]\n" + "\t [-M max-stream]\n" + "\t [-m max-msgsize]\n" + "\t [-L num-ports] [-S num-ports]\n" + "\t [-i interface]\n" + "\t [-f status-file]\n", + argv0); + fprintf(stderr, "\n"); + fprintf(stderr, "\t-c value = Packets of specifed size.\n"); + fprintf(stderr, "\t-m msgsize(1500-65515, default value 32768)\n"); + fprintf(stderr, "\t-x number of repeats\n"); + fprintf(stderr, "\t-o order-pattern\n"); + fprintf(stderr, "\t 0 = all unordered(default) \n"); + fprintf(stderr, "\t 1 = all ordered \n"); + fprintf(stderr, "\t 2 = alternating \n"); + fprintf(stderr, "\t 3 = random\n"); + fprintf(stderr, "\t-M max-stream (default value 0)\n"); + fprintf(stderr, "\t-D drain. If in client mode do a read following send.\n"); + fprintf(stderr, "\n"); + fflush(stderr); + +} /* usage() */ + +void sighandler(int signo) { + DEBUG_PRINT(DEBUG_MAX, "timeout sig\n"); + printstatus(gsk); +} + +char* get_sstat_state(int state) { + switch(state) { + case SCTP_EMPTY: + return "EMPTY"; + case SCTP_CLOSED: + return "CLOSED"; + case SCTP_COOKIE_WAIT: + return "COOKIE_WAIT"; + case SCTP_COOKIE_ECHOED: + return "COOKIE_ECHOED"; + case SCTP_ESTABLISHED: + return "ESTABLISHED"; + case SCTP_SHUTDOWN_PENDING: + return "SHUTDOWN_PENDING"; + case SCTP_SHUTDOWN_SENT: + return "SHUTDOWN_SENT"; + case SCTP_SHUTDOWN_RECEIVED: + return "SHUTDOWN_RECEIVED"; + case SCTP_SHUTDOWN_ACK_SENT: + return "SHUTDOWN_ACK_SENT"; + default: + return "UNKNOW"; + } +} + +void printstatus(int sk) { + static int cwnd = 0; + static int count = 0; + struct sctp_status status; + socklen_t optlen; + FILE * fp; + + optlen = sizeof(struct sctp_status); + if(getsockopt(sk, IPPROTO_SCTP, SCTP_STATUS, &status, &optlen) < 0) { + fprintf(stderr, "Error getting status: %s.\n", strerror(errno)); + exit(1); + } + + if (statusfile != NULL) { + if (count == 0) + unlink(statusfile); + + if((fp = fopen(statusfile, "a+")) == NULL) { + perror("fopen"); + exit(1); + } + } else + fp = stdout; + + if (count == 0) + fprintf(fp, "NO. ASSOC-ID STATE RWND UNACKDATA PENDDATA INSTRMS OUTSTRMS " + "FRAG-POINT SPINFO-STATE SPINFO-CWDN SPINFO-SRTT SPINFO-RTO SPINFO-MTU\n"); + + if (cwnd != status.sstat_primary.spinfo_cwnd) { + count++; + + fprintf(fp, "%-3d %-8d %-17s %-8d %-9d %-8d %-7d %-8d %-10d %-12s %-11d %-11d %-10d %d\n", count, + status.sstat_assoc_id, get_sstat_state(status.sstat_state), + status.sstat_rwnd, status.sstat_unackdata, status.sstat_penddata, + status.sstat_instrms, status.sstat_outstrms, status.sstat_fragmentation_point, + (status.sstat_primary.spinfo_state == 1) ? "ACTIVE" : "INACTIVE", + status.sstat_primary.spinfo_cwnd, status.sstat_primary.spinfo_srtt, + status.sstat_primary.spinfo_rto, status.sstat_primary.spinfo_mtu); + } + + cwnd = status.sstat_primary.spinfo_cwnd; + + fflush(fp); + + if (fp != stdout) + fclose(fp); + + if (status.sstat_primary.spinfo_state != 1) { + close_r(sk); + exit(1); + } +} diff --git a/src/apps/sctp_test.c b/src/apps/sctp_test.c new file mode 100644 index 0000000..d7c8e5f --- /dev/null +++ b/src/apps/sctp_test.c @@ -0,0 +1,1547 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2001, 2003 + * Copyright (c) 1999 Cisco + * Copyright (c) 1999, 2000, 2001 Motorola + * Copyright (c) 2001-2002 Nokia + * Copyright (c) 2001 La Monte H.P. Yarroll + * + * This is a userspace test application for the SCTP kernel + * implementation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ^^^^^^^^^^^^^^^^^^^^^^^^ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Written or modified by: + * Hui Huang + * Sridhar Samudrala + * Jon Grimm + * Daisy Chang + * Ryan Layer + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define REALLY_BIG 65536 + +#define SERVER 0 +#define CLIENT 1 +#define MIXED 2 +#define NOT_DEFINED 666 + +#define REPEAT 10 +#define BIG_REPEAT 1000000 +#define MAX_BIND_RETRYS 10 +#define BODYSIZE 10 +#define MSG_CNT 10 /* If this is changed the msg_sizes array + needs to be modified accordingly. */ + +#define DEFAULT_MAX_WINDOW 32768 +#define DEFAULT_MIN_WINDOW 1500 + +#define DEBUG_NONE 0 +#define DEBUG_MIN 1 +#define DEBUG_MAX 2 + +#define STREAM_PATTERN_SEQUENTIAL 0 +#define STREAM_PATTERN_RANDOM 1 + +#define ORDER_PATTERN_UNORDERED 0 +#define ORDER_PATTERN_ORDERED 1 +#define ORDER_PATTERN_ALTERNATE 2 +#define ORDER_PATTERN_RANDOM 3 + +#define ASSOC_PATTERN_SEQUENTIAL 0 +#define ASSOC_PATTERN_RANDOM 1 + +#define NCASES 6 +#define MAX_POLL_SKS 256 + +#define DEBUG_PRINT(level, print_this...) \ +{ \ + if (debug_level >= level) { \ + fprintf(stdout, print_this); \ + fflush(stdout); \ + } \ +} /* DEBUG_PRINT */ + +/* Convenience structure to determine space needed for cmsg. */ +typedef union { + struct sctp_initmsg init; + struct sctp_sndrcvinfo sndrcvinfo; +} _sctp_cmsg_data_t; + +#ifdef __FreeBSD__ +typedef union { + int raw; + struct sctp_initmsg init; + struct sctp_sndrcvinfo sndrcv; +} sctp_cmsg_data_t; +#endif + +#define CMSG_SPACE_INITMSG (CMSG_SPACE(sizeof(struct sctp_initmsg))) +#define CMSG_SPACE_SNDRCV (CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))) + +typedef struct { + int rem_port; + int order_state; + int stream_state; + int msg_cnt; + int msg_sent; + int cycle; +} _assoc_state; + +typedef struct { + int sk; + int assoc_i; + _assoc_state *assoc_state; +} _poll_sks; + +char *local_host = NULL; +int local_port = 0; +char *remote_host = NULL; +int remote_port = 0; +/* struct sockaddr_in s_rem, s_loc; */ +struct sockaddr_storage s_rem, s_loc; +int r_len, l_len; +int test_case = 0; +int size_arg = 0; +int xflag = 0; +int debug_level = DEBUG_MAX; +int do_exit = 1; +int stream_pattern = STREAM_PATTERN_SEQUENTIAL; +int stream_state = 0; +int order_pattern = ORDER_PATTERN_UNORDERED; +int order_state = 0; +int max_stream = 0; +int seed = 0; +int max_msgsize = DEFAULT_MAX_WINDOW; +int assoc_pattern = ASSOC_PATTERN_SEQUENTIAL; +int socket_type = SOCK_SEQPACKET; +int repeat_count = 0; +int listeners = 0; +int tosend = 0; +_poll_sks poll_sks[MAX_POLL_SKS]; +int repeat = REPEAT; +int msg_cnt = MSG_CNT; +int drain = 0; +int role = NOT_DEFINED; + +unsigned char msg[] = "012345678901234567890123456789012345678901234567890"; + +static int msg_sizes[NCASES][MSG_CNT] = + {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1452, 2904, 4356, 1452, 2904, 4356, 1452, 2904, 4356, 1452}, + {1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453}, + {1, 1453, 32768, 1, 1453, 32768, 1, 1453, 32768, 1}, + {1, 1000, 2000, 3000, 5000, 10000, 15000, 20000, 25000, 32768}, + {32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768}, + }; + +static const char *sac_state_tbl[] = { + "COMMUNICATION_UP", + "COMMUNICATION_LOST", + "RESTART", + "SHUTDOWN_COMPLETE", + "CANT_START_ASSOCICATION" +}; + +void usage(char *argv0) +{ + fprintf(stderr, "\nusage:\n"); + fprintf(stderr, " server:\n"); + fprintf(stderr, " %8s -H local-addr -P local-port -l [-d level] [-x]\n" + "\t [-L num-ports] [-S num-ports]\n" + "\t [-a assoc-pattern]\n" + "\t [-i interface]\n", + argv0); + fprintf(stderr, "\n"); + fprintf(stderr, " client:\n"); + fprintf(stderr, " %8s -H local-addr -P local-port -h remote-addr\n" + "\t -p remote-port -s [-c case ] [-d level]\n" + "\t [-x repeat] [-o order-pattern] ream-pattern]\n" + "\t [-M max-stream] [-r rand-seed]\n" + "\t [-m max-msgsize]\n" + "\t [-L num-ports] [-S num-ports]\n" + "\t [-a assoc-pattern]\n" + "\t [-i interface]\n", + argv0); + fprintf(stderr, "\n"); + fprintf(stderr, "\t-a assoc_pattern in the mixed mode\n"); + fprintf(stderr, "\t 0 = sequential ascending(default)\n"); + fprintf(stderr, "\t 1 = random\n"); + fprintf(stderr, "\t-d debug\n"); + fprintf(stderr, "\t 0 = none\n"); + fprintf(stderr, "\t 1 = min(default)\n"); + fprintf(stderr, "\t 2 = max\n"); + fprintf(stderr, "\t-c testcase\n"); + fprintf(stderr, "\t 0 = 1 byte packets.\n"); + fprintf(stderr, "\t 1 = 1452 byte packets.\n"); + fprintf(stderr, "\t (fragmentation point for an i/f with "); + fprintf(stderr, "1500 as mtu.)\n"); + fprintf(stderr, "\t 2 = 1453 byte packets.\n"); + fprintf(stderr, "\t (min. size at which fragmentation occurs\n"); + fprintf(stderr, "\t for an i/f with 1500 as mtu.)\n"); + fprintf(stderr, "\t 3 = Sequence of 1, 1453, 32768 byte packets.\n"); + fprintf(stderr, "\t 4 = Sequence of following size packets.\n"); + fprintf(stderr, "\t (1, 1000, 2000, 3000, 5000, 10000,"); + fprintf(stderr, "15000, 20000, 25000, 32768)\n"); + fprintf(stderr, "\t 5 = 32768 byte packets.\n"); + fprintf(stderr, "\t (default max receive window size.)\n"); + fprintf(stderr, "\t 6 = random size packets.\n"); + fprintf(stderr, "\t -ve value = Packets of specifed size.\n"); + fprintf(stderr, "\t-m msgsize(1500-65515, default value 32768)\n"); + fprintf(stderr, "\t-x number of repeats\n"); + fprintf(stderr, "\t-o order-pattern\n"); + fprintf(stderr, "\t 0 = all unordered(default) \n"); + fprintf(stderr, "\t 1 = all ordered \n"); + fprintf(stderr, "\t 2 = alternating \n"); + fprintf(stderr, "\t 3 = random\n"); + fprintf(stderr, "\t-t stream-pattern\n"); + fprintf(stderr, "\t 0 = sequential ascending(default)\n"); + fprintf(stderr, "\t 1 = random\n"); + fprintf(stderr, "\t-M max-stream (default value 0)\n"); + fprintf(stderr, "\t-r seed (default 0, use time())\n"); + fprintf(stderr, "\t-L num-ports (default value 0). Run the mixed mode\n"); + fprintf(stderr, "\t-S num-ports (default value 0). Run the mixed mode\n"); + fprintf(stderr, "\t-D drain. If in client mode do a read following send.\n"); + fprintf(stderr, "\t-T use SOCK_STREAM tcp-style sockets.\n"); + fprintf(stderr, "\n"); + fflush(stderr); + +} /* usage() */ + +void * +build_msg(int len) +{ + int i = len - 1; + int n; + char *msg_buf, *p; + + msg_buf = malloc(len); + if (NULL == msg_buf) { + fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n"); + exit(1); + } + p = msg_buf; + + do { + n = ((i > 50)?50:i); + memcpy(p, msg, ((i > 50)?50:i)); + p += n; + i -= n; + } while (i > 0); + + msg_buf[len-1] = '\0'; + + return(msg_buf); + +} /* build_msg() */ + +static int +print_cmsg(int type, sctp_cmsg_data_t *data) +{ + switch(type) { + case SCTP_INIT: + DEBUG_PRINT(DEBUG_MAX, "\tINIT\n"); + if (DEBUG_MAX == debug_level) { + printf("\t\tsinit_num_ostreams=%d ", + data->init.sinit_num_ostreams); + printf("sinit_max_instreams=%d ", + data->init.sinit_max_instreams); + printf("sinit_max_attempts=%d ", + data->init.sinit_max_attempts); + printf("sinit_max_init_timeo=%d\n", + data->init.sinit_max_init_timeo); + } + break; + case SCTP_SNDRCV: + DEBUG_PRINT(DEBUG_MAX, "\t SNDRCV"); + if (DEBUG_MAX == debug_level) { + printf("(stream=%u ", data->sndrcv.sinfo_stream); + printf("ssn=%u ", data->sndrcv.sinfo_ssn); + printf("tsn=%u ", data->sndrcv.sinfo_tsn); + printf("flags=0x%x ", data->sndrcv.sinfo_flags); + printf("ppid=%u\n", data->sndrcv.sinfo_ppid); + printf("cumtsn=%u\n", data->sndrcv.sinfo_cumtsn); + } + break; + default: + DEBUG_PRINT(DEBUG_MIN, "\tUnknown type: %d\n", type); + break; + } + fflush(stdout); + return 0; + +} /* print_cmsg() */ + +/* This function prints the message. */ +static int +print_message(const int sk, struct msghdr *msg, size_t msg_len) { + struct cmsghdr *scmsg; + sctp_cmsg_data_t *data; + int i; + + if (!(MSG_NOTIFICATION & msg->msg_flags)) { + int index = 0; + + DEBUG_PRINT(DEBUG_MIN, "Data %d bytes.", msg_len); + + DEBUG_PRINT(DEBUG_MAX, " First %d bytes: ", + (msg_len < BODYSIZE)?msg_len:BODYSIZE); + /* Make sure that everything is printable and that we + * are NUL terminated... + */ + while ( msg_len > 0 ) { + char *text, tmptext[BODYSIZE]; + int len; + + memset(tmptext, 0x0, BODYSIZE); + + text = msg->msg_iov[index].iov_base; + len = msg->msg_iov[index].iov_len; + + if (msg_len == 1 && text[0] == 0) { + DEBUG_PRINT(DEBUG_MIN, " text[0]=%d", + text[0]); + break; + } + + if ( len > msg_len ) { + /* text[(len = msg_len) - 1] = '\0'; */ + text[(len = msg_len)] = '\0'; + } + + if ( (msg_len -= len) > 0 ) { index++; } + + for (i = 0; i < len - 1; ++i) { + if (!isprint(text[i])) text[i] = '.'; + } + + strncpy(tmptext, text, BODYSIZE); + tmptext[BODYSIZE-1] = '\0'; + + DEBUG_PRINT(DEBUG_MAX, "%s", tmptext); + } + + DEBUG_PRINT(DEBUG_MIN, "\n"); + fflush(stdout); + } else { /* if(we have notification) */ + struct sctp_assoc_change *sac; + struct sctp_send_failed *ssf; + struct sctp_paddr_change *spc; + struct sctp_remote_error *sre; + union sctp_notification *snp; + char addrbuf[INET6_ADDRSTRLEN]; + const char *ap; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + int index = 0; + + snp = (union sctp_notification *)msg->msg_iov[index].iov_base; + + DEBUG_PRINT(DEBUG_MIN, "Notification:"); + + switch (snp->sn_header.sn_type) { + case SCTP_ASSOC_CHANGE: + sac = &snp->sn_assoc_change; + DEBUG_PRINT(DEBUG_MIN, + " SCTP_ASSOC_CHANGE(%s)\n", + sac_state_tbl[sac->sac_state]); + DEBUG_PRINT(DEBUG_MAX, + "\t\t(assoc_change: state=%hu, " + "error=%hu, instr=%hu " + "outstr=%hu)\n", + sac->sac_state, sac->sac_error, + sac->sac_inbound_streams, + sac->sac_outbound_streams); + break; + case SCTP_PEER_ADDR_CHANGE: + spc = &snp->sn_paddr_change; + DEBUG_PRINT(DEBUG_MIN, + " SCTP_PEER_ADDR_CHANGE\n"); + if (spc->spc_aaddr.ss_family == AF_INET) { + sin = (struct sockaddr_in *) + &spc->spc_aaddr; + ap = inet_ntop(AF_INET, &sin->sin_addr, + addrbuf, + INET6_ADDRSTRLEN); + } else { + sin6 = (struct sockaddr_in6 *) + &spc->spc_aaddr; + ap = inet_ntop(AF_INET6, + &sin6->sin6_addr, + addrbuf, + INET6_ADDRSTRLEN); + } + DEBUG_PRINT(DEBUG_MAX, + "\t\t(peer_addr_change: %s " + "state=%d, error=%d)\n", + ap, spc->spc_state, + spc->spc_error); + break; + case SCTP_SEND_FAILED: + ssf = &snp->sn_send_failed; + DEBUG_PRINT(DEBUG_MIN, + " SCTP_SEND_FAILED\n"); + DEBUG_PRINT(DEBUG_MAX, + "\t\t(sendfailed: len=%hu " + "err=%d)\n", + ssf->ssf_length, ssf->ssf_error); + break; + case SCTP_REMOTE_ERROR: + sre = &snp->sn_remote_error; + DEBUG_PRINT(DEBUG_MIN, + " SCTP_REMOTE_ERROR\n"); + DEBUG_PRINT(DEBUG_MAX, + "\t\t(remote_error: err=%hu)\n", + ntohs(sre->sre_error)); + break; + case SCTP_SHUTDOWN_EVENT: + DEBUG_PRINT(DEBUG_MIN, + " SCTP_SHUTDOWN_EVENT\n"); + break; + default: + DEBUG_PRINT(DEBUG_MIN, + " Unknown type: %hu\n", + snp->sn_header.sn_type); + break; + } + + fflush(stdout); + return 1; + + } /* notification received */ + + for (scmsg = CMSG_FIRSTHDR(msg); + scmsg != NULL; + scmsg = CMSG_NXTHDR(msg, scmsg)) { + + data = (sctp_cmsg_data_t *)CMSG_DATA(scmsg); + if (debug_level) print_cmsg(scmsg->cmsg_type, data); + } + + + fflush(stdout); + return 0; + +} /* print_message() */ + +int socket_r(void) +{ + struct sctp_event_subscribe subscribe; + int sk, error; + + DEBUG_PRINT(DEBUG_MIN, "\tsocket(%s, IPPROTO_SCTP)", + (socket_type == SOCK_SEQPACKET) ? "SOCK_SEQPACKET" : "SOCK_STREAM"); + + if ((sk = socket(s_loc.ss_family, socket_type, IPPROTO_SCTP)) < 0 ) { + if (do_exit) { + fprintf(stderr, "\n\n\t\t*** socket: failed to create" + " socket: %s ***\n", + strerror(errno)); + exit(1); + } else { + return -1; + } + } + DEBUG_PRINT(DEBUG_MIN, " -> sk=%d\n", sk); + + memset(&subscribe, 0, sizeof(subscribe)); + subscribe.sctp_data_io_event = 1; + subscribe.sctp_association_event = 1; + error = setsockopt(sk, SOL_SCTP, SCTP_EVENTS, (char *)&subscribe, + sizeof(subscribe)); + if (error) { + fprintf(stderr, "SCTP_EVENTS: error: %d\n", error); + exit(1); + } + + return sk; + +} /* socket_r() */ + +int bind_r(int sk, struct sockaddr_storage *saddr) +{ + int error = 0, i = 0; + char *host_s, *serv_s; + + if ((host_s = malloc(NI_MAXHOST)) == NULL) { + fprintf(stderr, "\n\t\t*** host_s malloc failed!!! ***\n"); + exit(1); + } + if ((serv_s = malloc(NI_MAXSERV)) == NULL) { + fprintf(stderr, "\n\t\t*** serv_s malloc failed!!! ***\n"); + exit(1); + } + + do { + if (i > 0) sleep(1); /* sleep a while before new try... */ + + error = getnameinfo((struct sockaddr *)saddr, l_len, host_s, + NI_MAXHOST, serv_s, NI_MAXSERV, + NI_NUMERICHOST); + + if (error) + printf("%s\n", gai_strerror(error)); + + DEBUG_PRINT(DEBUG_MIN, + "\tbind(sk=%d, [a:%s,p:%s]) -- attempt %d/%d\n", + sk, host_s, serv_s, i+1, MAX_BIND_RETRYS); + + error = bind(sk, (struct sockaddr *)saddr, l_len); + + if (error != 0) { + if( errno != EADDRINUSE ) { + if (do_exit) { + fprintf(stderr, "\n\n\t\t***bind: can " + "not bind to %s:%s: %s ****\n", + host_s, serv_s, + strerror(errno)); + exit(1); + } else { + return -1; + } + } + } + i++; + if (i >= MAX_BIND_RETRYS) { + fprintf(stderr, "Maximum bind() attempts. " + "Die now...\n\n"); + exit(1); + } + } while (error < 0 && i < MAX_BIND_RETRYS); + + return 0; + +} /* bind_r() */ + +int listen_r(int sk, int listen_count) +{ + int error = 0; + + DEBUG_PRINT(DEBUG_MIN, "\tlisten(sk=%d,backlog=%d)\n", + sk, listen_count); + + /* Mark sk as being able to accept new associations */ + error = listen(sk, 1); + if (error != 0) { + if (do_exit) { + fprintf(stderr, "\n\n\t\t*** listen: %s ***\n\n\n", + strerror(errno)); + exit(1); + } + else return -1; + } + return 0; + +} /* listen_r() */ + +int accept_r(int sk){ + socklen_t len = 0; + int subsk; + + DEBUG_PRINT(DEBUG_MIN, "\taccept(sk=%d)\n", sk); + + subsk = accept(sk, NULL, &len); + if (subsk < 0) { + fprintf(stderr, "\n\n\t\t*** accept: %s ***\n\n\n", strerror(errno)); + exit(1); + } + + return subsk; +} /* accept_r() */ + +int connect_r(int sk, const struct sockaddr *serv_addr, socklen_t addrlen) +{ + int error = 0; + + DEBUG_PRINT(DEBUG_MIN, "\tconnect(sk=%d)\n", sk); + + /* Mark sk as being able to accept new associations */ + error = connect(sk, serv_addr, addrlen); + if (error != 0) { + if (do_exit) { + fprintf(stderr, "\n\n\t\t*** connect: %s ***\n\n\n", + strerror(errno)); + exit(1); + } + else return -1; + } + return 0; + +} /* connect_r() */ + +int receive_r(int sk, int once) +{ + int recvsk = sk, i = 0, error = 0; + char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))]; + struct iovec iov; + struct msghdr inmessage; + + /* Initialize inmessage with enough space for DATA... */ + memset(&inmessage, 0, sizeof(inmessage)); + if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) { + fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n"); + exit(1); + } + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + /* or a control message. */ + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + + /* Get the messages sent */ + while (1) { + + if (recvsk == sk && socket_type == SOCK_STREAM && + role == SERVER) + recvsk = accept_r(sk); + + DEBUG_PRINT(DEBUG_MIN, "\trecvmsg(sk=%d) ", sk); + + error = recvmsg(recvsk, &inmessage, MSG_WAITALL); + if (error < 0 && error != EAGAIN) { + if (errno == ENOTCONN && socket_type == SOCK_STREAM && + role == SERVER) { + printf("No association is present now!!\n"); + close(recvsk); + recvsk = sk; + continue; + } + + fprintf(stderr, "\n\t\t*** recvmsg: %s ***\n\n", + strerror(errno)); + fflush(stdout); + if (do_exit) exit(1); + else goto error_out; + } + else if (error == 0) { + if (socket_type == SOCK_STREAM && role == SERVER) { + printf("No association is present now!!\n"); + close(recvsk); + recvsk = sk; + continue; + } + printf("\n\t\trecvmsg() returned 0 !!!!\n"); + fflush(stdout); + } + + if (print_message(recvsk, &inmessage, error) > 0) + continue; /* got a notification... */ + + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + iov.iov_len = REALLY_BIG; + i++; + if (once) + break; + } + + if (recvsk != sk) + close(recvsk); + + free(iov.iov_base); + return 0; +error_out: + close(sk); + free(iov.iov_base); + return -1; + +} /* receive_r () */ + +int next_order(int state, int pattern) +{ + switch (pattern){ + case ORDER_PATTERN_UNORDERED: + state = 0; + break; + case ORDER_PATTERN_ORDERED: + state = 1; + break; + case ORDER_PATTERN_ALTERNATE: + state = state ? 0 : 1; + break; + case ORDER_PATTERN_RANDOM: + state = rand() % 2; + break; + } + + return state; +} + +int next_stream(int state, int pattern) +{ + switch (pattern){ + case STREAM_PATTERN_RANDOM: + state = rand() % (max_stream + 1); + break; + case STREAM_PATTERN_SEQUENTIAL: + state = state + 1; + if (state > max_stream) + state = 0; + break; + } + + return state; +} + +int next_msg_size(int msg_cnt) +{ + int msg_size; + + if (size_arg) { + msg_size = size_arg; + } else if (test_case < NCASES) { + msg_size = msg_sizes[test_case][msg_cnt]; + } else { + msg_size = (rand() % max_msgsize) + 1; + } + + return msg_size; + +} /* next_msg_size() */ + +int next_assoc(int i, int state, int pattern) +{ + int j; + int found = 0; + _assoc_state *as; + + + switch (pattern){ + case ASSOC_PATTERN_RANDOM: + state = rand() % tosend; + break; + case ASSOC_PATTERN_SEQUENTIAL: + state = state + 1; + if (state >= tosend) + state = 0; + break; + } + + as = poll_sks[i].assoc_state; + j = state; + do { + if (as[j].msg_sent < repeat_count) { + found = 1; + break; + } + if (++j >= tosend) { + j = 0; + } + } while (j != state); + + if (found) { + return j; + } else { + return -1; + } + +} /* next_assoc() */ + +int send_r(int sk, int stream, int order, int send_size, int assoc_i) +{ + int error = 0; + struct msghdr outmsg; + struct iovec iov; + char *message = NULL; + int msglen = 0; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + + if (send_size > 0) { + message = build_msg(send_size); + msglen = strlen(message) + 1; + iov.iov_base = message; + iov.iov_len = msglen; + } + else { + if (do_exit) { + exit(1); + } else { + goto error_out; + } + } + + outmsg.msg_name = &s_rem; + outmsg.msg_namelen = sizeof(struct sockaddr_storage); + outmsg.msg_iov = &iov; + outmsg.msg_iovlen = 1; + outmsg.msg_control = outcmsg; + outmsg.msg_controllen = sizeof(outcmsg); + outmsg.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&outmsg); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + + outmsg.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo)); + sinfo->sinfo_ppid = rand(); + sinfo->sinfo_stream = stream; + sinfo->sinfo_flags = 0; + if (!order) + sinfo->sinfo_flags = SCTP_UNORDERED; + + DEBUG_PRINT(DEBUG_MIN, "\tsendmsg(sk=%d, assoc=%d) %4d bytes.\n", + sk, assoc_i, send_size); + DEBUG_PRINT(DEBUG_MAX, "\t SNDRCV"); + if (DEBUG_MAX == debug_level) { + printf("(stream=%u ", sinfo->sinfo_stream); + printf("flags=0x%x ", sinfo->sinfo_flags); + printf("ppid=%u\n", sinfo->sinfo_ppid); + } + + /* Send to our neighbor. */ + error = sendmsg(sk, &outmsg, MSG_WAITALL); + if (error != msglen) { + fprintf(stderr, "\n\t\t*** sendmsg: %s ***\n\n", + strerror(errno)); + fflush(stdout); + + if (do_exit) { + exit(1); + } else { + if (!drain) + goto error_out; + } + } + + if (send_size > 0) free(message); + return 0; +error_out: + if (send_size > 0) free(message); + return -1; + +} /* send_r() */ + +int close_r(int sk) +{ + int error = 0; + + DEBUG_PRINT(DEBUG_MIN, "\tclose(sk=%d)\n",sk); + + error = close(sk); + if (error != 0) { + if (do_exit) { + fprintf(stderr, "\n\n\t\t*** close: %s ***\n\n", + strerror(errno)); + exit(1); + } else { + return -1; + } + } + fflush(stdout); + return 0; + +} /* close_r() */ + +void +server(int sk) +{ + if (max_msgsize > DEFAULT_MAX_WINDOW) { + if (setsockopt(sk, SOL_SOCKET, SO_RCVBUF, &max_msgsize, + sizeof(max_msgsize)) < 0) { + perror("setsockopt(SO_RCVBUF)"); + exit(1); + } + } + + receive_r(sk, 0); + +} /* server() */ + +void +client(int sk) +{ + int msg_size; + int i; + + for (i = 0; i < msg_cnt; i++) { + + msg_size = next_msg_size(i); + order_state = next_order(order_state, order_pattern); + stream_state = next_stream(stream_state, stream_pattern); + + if (send_r(sk, stream_state, order_state, msg_size, 0) < 0) { + close(sk); + break; + } + /* The sender is echoing so do discard the echoed data. */ + if (drain) { + receive_r(sk, 1); + } + } +} /* client() */ + +void +mixed_mode_test(void) +{ + int error, i, j, max_fd, sks, size; + int assoc_i, n_msg_size, n_order, n_stream; + int done = 0; + fd_set *ibitsp = NULL, *obitsp = NULL, *xbitsp = NULL; + char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))]; + struct iovec iov; + struct msghdr inmessage; + _assoc_state *as; + + + /* Set up the listeners. If listeners is 0, set up one socket for + * transmitting only. + */ + iov.iov_base = NULL; + max_fd = -1; + sks = (0 == listeners) ? 1 : listeners; + memset(poll_sks, 0, sizeof(sks * sizeof(_poll_sks))); + + for (i = 0; i < sks; i++) { + poll_sks[i].sk = socket_r(); + + if (s_loc.ss_family == AF_INET6) + ( (struct sockaddr_in6 *)&s_loc)->sin6_port = + htons(local_port + i); + else + ( (struct sockaddr_in *)&s_loc)->sin_port = + htons(local_port + i); + + bind_r(poll_sks[i].sk, &s_loc); + if (listeners) { + listen_r(poll_sks[i].sk, 100); + } + if (max_msgsize > DEFAULT_MAX_WINDOW) { + if (setsockopt(poll_sks[i].sk, SOL_SOCKET, SO_RCVBUF, + &max_msgsize, sizeof(max_msgsize)) < 0) { + perror("setsockopt(SO_RCVBUF)"); + exit(1); + } + } + + if (tosend) { + if ((poll_sks[i].assoc_state = (_assoc_state *)malloc( + sizeof(_assoc_state) * tosend)) == NULL) { + printf("Can't allocate memory.\n"); + goto clean_up; + } + memset(poll_sks[i].assoc_state, 0, + sizeof(_assoc_state) * tosend); + } + + if (poll_sks[i].sk > max_fd) { + max_fd = poll_sks[i].sk; + } + } + + size = howmany(max_fd + 1, NFDBITS) * sizeof(fd_mask); + if ((ibitsp = (fd_set *)malloc(size)) == NULL) { + printf("Can't allocate memory.\n"); + goto clean_up; + } + if ((obitsp = (fd_set *)malloc(size)) == NULL) { + printf("Can't allocate memory.\n"); + goto clean_up; + } + if ((xbitsp = (fd_set *)malloc(size)) == NULL) { + printf("Can't allocate memory.\n"); + goto clean_up; + } + + memset(ibitsp, 0, size); + memset(obitsp, 0, size); + memset(xbitsp, 0, size); + + + /* Initialize inmessage with enough space for DATA... */ + memset(&inmessage, 0, sizeof(inmessage)); + if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) { + fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n"); + goto clean_up; + } + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + /* or a control message. */ + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + + /* Set up the remote port number per association for output. */ + for (i = 0; i < sks; i++) { + as = poll_sks[i].assoc_state; + for (j = 0; j < tosend; j++) { + as[j].rem_port = remote_port + j; + } + } + + while (!done) { + + for (i = 0; i < sks; i++) { + FD_SET(poll_sks[i].sk, ibitsp); + FD_SET(poll_sks[i].sk, obitsp); + FD_SET(poll_sks[i].sk, xbitsp); + } + if ((error = select(max_fd + 1, ibitsp, obitsp, xbitsp, + (struct timeval *)0)) < 0) { + fprintf(stderr, "\n\t\t*** select() failed "); + fprintf(stderr, "with error: %s\n\n", + strerror(errno)); + fflush(stdout); + goto clean_up; + } + + for (i = 0; i < sks; i++) { + /* Is there anything to read from the socket? */ + if (listeners && FD_ISSET(poll_sks[i].sk, ibitsp)) { + + FD_CLR(poll_sks[i].sk, ibitsp); + error = recvmsg(poll_sks[i].sk, &inmessage, + MSG_WAITALL); + if (error < 0) { + fprintf(stderr, + "\n\t\t*** recvmsg: %s ***\n\n", + strerror(errno)); + fflush(stdout); + goto clean_up; + } + else if (error == 0) { + printf("\n\t\trecvmsg() returned "); + printf("0 !!!!\n"); + fflush(stdout); + } + + print_message(poll_sks[i].sk, &inmessage, + error); + + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + iov.iov_len = REALLY_BIG; + } + + /* Is this socket writeable? */ + if (tosend && FD_ISSET(poll_sks[i].sk, obitsp)) { + + FD_CLR(poll_sks[i].sk, obitsp); + + /* Pick an association. */ + assoc_i = next_assoc(i, poll_sks[i].assoc_i, + assoc_pattern); + if (assoc_i < 0) { + /* No work to do on any associations. + * We are probably done. */ + if (!listeners) { + done = 1; + } + continue; + } + poll_sks[i].assoc_i = assoc_i; + + as = poll_sks[i].assoc_state; + n_msg_size = next_msg_size(as[assoc_i].msg_cnt); + n_order = as[assoc_i].order_state = + next_order(as[assoc_i].order_state, + order_pattern); + n_stream = as[assoc_i].stream_state = + next_stream(as[assoc_i].stream_state, + stream_pattern); + + /* Set the destination port. */ + if (s_rem.ss_family == AF_INET6) + ( (struct sockaddr_in6 *)&s_rem)-> + sin6_port = + htons(as[assoc_i].rem_port); + else + ( (struct sockaddr_in *)&s_rem)-> + sin_port = + htons(as[assoc_i].rem_port); + + /* Send a message thru the association. */ + if (send_r(poll_sks[i].sk, n_stream, n_order, + n_msg_size, assoc_i) < 0) { + /* Don't increment counter if there + * is a problem of sending. + */ + continue; + } + + /* Increment counters. */ + if (++as[assoc_i].msg_cnt >= MSG_CNT) { + as[assoc_i].msg_cnt = 0; + } + if (++as[assoc_i].msg_sent >= + repeat_count) { + fprintf(stderr, "Association #%d in ", + assoc_i); + fprintf(stderr, "sk=%d has ", + poll_sks[i].sk); + fprintf(stderr, "completed %d msg as ", + as[assoc_i].msg_sent); + fprintf(stderr, "cycle %d.\n", + ++as[assoc_i].cycle); + + /* In the mixed mode, -x not only + * specify the longer repeat cycle, + * but it also mean to run the test + * forever. + */ + if (xflag) { + as[assoc_i].msg_sent = 0; + } + + } + + } + } + } + +clean_up: + for (i = 0; i < sks; i++) { + close(poll_sks[i].sk); + if (poll_sks[i].assoc_state) { + free(poll_sks[i].assoc_state); + } + } + + if (ibitsp) free(ibitsp); + if (obitsp) free(obitsp); + if (xbitsp) free(xbitsp); + + if (iov.iov_base) free(iov.iov_base); + +} /* mixed_mode_test() */ + +void start_test(int role) +{ + int sk; + int i = 0; + + DEBUG_PRINT(DEBUG_NONE, "\nStarting tests...\n"); + + repeat_count = repeat; + + + if (MIXED == role) { + repeat_count = repeat_count * msg_cnt; /* Repeat per assoc. */ + mixed_mode_test(); + return; + } + + sk = socket_r(); + bind_r(sk, &s_loc); + + if (role == SERVER) { + listen_r(sk, 100); + } else if (socket_type == SOCK_STREAM) { + connect_r(sk, (struct sockaddr *)&s_rem, r_len); + } + + if (!debug_level) { + printf(" "); + } + + for(i = 0; i < repeat_count; i++) { + + if (role == SERVER) { + DEBUG_PRINT(DEBUG_NONE, + "Server: Receiving packets.\n"); + server(sk); + } else { + DEBUG_PRINT(DEBUG_NONE, + "Client: Sending packets.(%d/%d)\n", + i+1, repeat_count); + client(sk); + } + + fflush(stdout); + } + + close_r(sk); + +} /* start_test() */ + +int +main(int argc, char *argv[]) +{ + int c; + char *interface = NULL; + struct sockaddr_in *t_addr; + struct sockaddr_in6 *t_addr6; + + /* Parse the arguments. */ + while ((c = getopt(argc, argv, ":H:L:P:S:a:h:p:c:d:lm:sx:X:o:t:M:r:w:Di:T")) >= 0 ) { + + switch (c) { + case 'H': + local_host = optarg; + break; + case 'L': + role = MIXED; + listeners = atoi(optarg); + if (listeners > MAX_POLL_SKS) { + usage(argv[0]); + exit(1); + } + break; + case 'P': + local_port = atoi(optarg); + break; + case 'S': + role = MIXED; + tosend = atoi(optarg); + if (tosend > MAX_POLL_SKS) { + usage(argv[0]); + exit(1); + } + break; + case 'a': + assoc_pattern = atoi(optarg); + if (assoc_pattern < ASSOC_PATTERN_SEQUENTIAL + || assoc_pattern > ASSOC_PATTERN_RANDOM ) { + usage(argv[0]); + exit(1); + } + break; + case 'h': + remote_host = optarg; + break; + case 'D': + drain = 1; + do_exit = 0; + break; + case 'p': + remote_port = atoi(optarg); + break; + case 's': + if (role != NOT_DEFINED) { + printf("%s: only -s or -l\n", argv[0]); + usage(argv[0]); + exit(1); + } + role = CLIENT; + break; + case 'l': + if (role != NOT_DEFINED) { + printf("%s: only -s or -l\n", argv[0]); + usage(argv[0]); + exit(1); + } + role = SERVER; + break; + case 'd': + debug_level = atoi(optarg); + if (debug_level < DEBUG_NONE + || debug_level > DEBUG_MAX) { + usage(argv[0]); + exit(1); + } + break; + case 'x': + repeat = atoi(optarg); + if (!repeat) { + xflag = 1; + repeat = BIG_REPEAT; + } + break; + case 'X': + msg_cnt = atoi(optarg); + if ((msg_cnt <= 0) || (msg_cnt > MSG_CNT)) { + usage(argv[0]); + exit(1); + } + break; + case 'c': + test_case = atoi(optarg); + if (test_case > NCASES) { + usage(argv[0]); + exit(1); + } + if (test_case < 0) { + size_arg = -test_case; + } + + break; + case 'o': + order_pattern = atoi(optarg); + if (order_pattern < ORDER_PATTERN_UNORDERED + || order_pattern > ORDER_PATTERN_RANDOM ) { + usage(argv[0]); + exit(1); + } + break; + case 't': + stream_pattern = atoi(optarg); + if (stream_pattern < STREAM_PATTERN_SEQUENTIAL + || stream_pattern > STREAM_PATTERN_RANDOM ) { + usage(argv[0]); + exit(1); + } + break; + case 'M': + max_stream = atoi(optarg); + if (max_stream < 0 + || max_stream >= (1<<16)) { + usage(argv[0]); + exit(1); + } + break; + case 'r': + seed = atoi(optarg); + break; + case 'm': + max_msgsize = atoi(optarg); +#if 0 + if ((max_msgsize < DEFAULT_MIN_WINDOW) || + (max_msgsize > 65515)) { + usage(argv[0]); + exit(1); + } +#endif + break; + case 'i': + interface = optarg; + break; + case 'T': + socket_type = SOCK_STREAM; + break; + case '?': + default: + usage(argv[0]); + exit(0); + } + } /* while() */ + + if (NOT_DEFINED == role) { + usage(argv[0]); + exit(1); + } + + + if (SERVER == role && NULL == local_host && remote_host != NULL) { + fprintf (stderr, "%s: Server needs local address, " + "not remote address\n", argv[0]); + usage(argv[0]); + exit(1); + } + if (CLIENT == role && NULL == remote_host) { + fprintf (stderr, "%s: Client needs at least remote address " + "& port\n", argv[0]); + usage(argv[0]); + exit(1); + } + if (MIXED == role) { + if (listeners && NULL == local_host) { + fprintf (stderr, "%s: Servers need local address\n", + argv[0]); + usage(argv[0]); + exit(1); + } + if (tosend && NULL == remote_host) { + fprintf (stderr, "%s: Clients need remote address ", + argv[0]); + fprintf (stderr, "& port\n"); + usage(argv[0]); + exit(1); + } + } + + if (optind < argc) { + fprintf(stderr, "%s: non-option arguments are illegal: ", + argv[0]); + while (optind < argc) + fprintf(stderr, "%s ", argv[optind++]); + fprintf (stderr, "\n"); + usage(argv[0]); + exit(1); + } + + if (remote_host != NULL && remote_port != 0) { + struct addrinfo *res; + int error; + char *host_s, *serv_s; + + if ((host_s = malloc(NI_MAXHOST)) == NULL) { + fprintf(stderr, "\n*** host_s malloc failed!!! ***\n"); + exit(1); + } + if ((serv_s = malloc(NI_MAXSERV)) == NULL) { + fprintf(stderr, "\n*** serv_s malloc failed!!! ***\n"); + exit(1); + } + + error = getaddrinfo(remote_host, 0, NULL, &res); + if (error) { + printf("%s.\n", gai_strerror(error)); + usage(argv[0]); + exit(1); + } + + switch (res->ai_family) { + case AF_INET: + t_addr = (struct sockaddr_in *)&s_rem; + + t_addr->sin_family = AF_INET; + t_addr->sin_port = htons(remote_port); + inet_pton(AF_INET, remote_host, + &t_addr->sin_addr); + + r_len = sizeof (struct sockaddr_in); +#ifdef __FreeBSD__ + t_addr->sin_len = r_len; +#endif + break; + case AF_INET6: + + t_addr6 = (struct sockaddr_in6 *)&s_rem; + + if (interface) + t_addr6->sin6_scope_id = + if_nametoindex(interface); + t_addr6->sin6_family = AF_INET6; + t_addr6->sin6_port = htons(remote_port); + inet_pton(AF_INET6, remote_host, + &t_addr6->sin6_addr); + + r_len = sizeof (struct sockaddr_in6); + +#ifdef __FreeBSD__ + t_addr6->sin6_len = r_len; +#endif + break; + } + + getnameinfo((struct sockaddr *)&s_rem, r_len, host_s, + NI_MAXHOST, serv_s, NI_MAXSERV, NI_NUMERICHOST); + + + DEBUG_PRINT(DEBUG_MAX, "remote:addr=%s, port=%s, family=%d\n", + host_s, serv_s, res->ai_family); + } + + if (local_host != NULL) { + struct addrinfo *res; + int error; + char *host_s, *serv_s; + struct sockaddr_in *t_addr; + struct sockaddr_in6 *t_addr6; + + if ((host_s = malloc(NI_MAXHOST)) == NULL) { + fprintf(stderr, "\n*** host_s malloc failed!!! ***\n"); + exit(1); + } + if ((serv_s = malloc(NI_MAXSERV)) == NULL) { + fprintf(stderr, "\n*** serv_s malloc failed!!! ***\n"); + exit(1); + } + + if (strcmp(local_host, "0") == 0) + local_host = "0.0.0.0"; + + error = getaddrinfo(local_host, 0, NULL, &res); + if (error) { + printf("%s.\n", gai_strerror(error)); + usage(argv[0]); + exit(1); + } + + + switch (res->ai_family) { + case AF_INET: + t_addr = (struct sockaddr_in *)&s_loc; + t_addr->sin_family = AF_INET; + t_addr->sin_port = htons(local_port); + inet_pton(AF_INET, local_host, + &t_addr->sin_addr); + + l_len = sizeof (struct sockaddr_in); +#ifdef __FreeBSD__ + t_addr->sin_len = l_len; +#endif + break; + case AF_INET6: + t_addr6 = (struct sockaddr_in6 *)&s_loc; + + if (interface) + t_addr6->sin6_scope_id = + if_nametoindex(interface); + t_addr6->sin6_family = AF_INET6; + t_addr6->sin6_port = htons(local_port); + + inet_pton(AF_INET6, local_host, + &t_addr6->sin6_addr); + + l_len = sizeof (struct sockaddr_in6); + +#ifdef __FreeBSD__ + t_addr6->sin6_len = l_len; +#endif + break; + } + + error = getnameinfo((struct sockaddr *)&s_loc, l_len, host_s, + NI_MAXHOST, serv_s, NI_MAXSERV, NI_NUMERICHOST); + + if (error) + printf("%s..\n", gai_strerror(error)); + + DEBUG_PRINT(DEBUG_MAX, "local:addr=%s, port=%s, family=%d\n", + host_s, serv_s, res->ai_family); + } + + + /* A half-hearted attempt to seed rand() */ + if (seed == 0 ) { + seed = time(0); + DEBUG_PRINT(DEBUG_NONE, "seed = %d\n", seed); + } + + srand(seed); + + /* Let the testing begin. */ + start_test(role); + + return 0; + +} /* main() */ diff --git a/src/apps/sctp_xconnect.c b/src/apps/sctp_xconnect.c new file mode 100644 index 0000000..5874c33 --- /dev/null +++ b/src/apps/sctp_xconnect.c @@ -0,0 +1,589 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2003 + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Ryan Layer + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 1; +int TST_CNT = 0; + +#define MAXHOSTNAME 64 + +#define MAXCLIENTNUM 10000 + +#define TRUE 1 + +#define SERVER 1 +#define CLIENT 0 +#define NOT_DEFINED -1 + +int mode = NOT_DEFINED; + +int assoc_num, + remote_port, + local_port; +int active = 0; + +char *local_host = NULL; +char *remote_host = NULL; +sockaddr_storage_t client_loop, + server_loop; +struct hostent *hst; + +void usage(char *argv0); +void parse_arguments(int argc, char*argv[]); +void data_received(struct msghdr *inmessage, int len, int stream, + int server_socket); +int event_received(struct msghdr *inmessage, int assoc_num); +void process_ready_sockets(int client_socket[], int assoc_num, fd_set *rfds); +void server_mode(void); +void client_mode(void); + +/* Print the syntax/usage */ +void usage(char *argv0) +{ + printf("usage: %s -H localhost -P localport -l|c [-h remotehost]\n" + "\t\t[-p remoteport] [-a] [-n ]\n" + " -H\t\tspecify a local address.\n" + " -P\t\tspecify the local port number to be used\n" + " -l\t\trun in server mode.\n" + " -c\t\trun in client mode.\n" + " -h\t\tspecify the peer address.\n" + " -p\t\tspecify the port number for the peer address.\n" + " -a\t\tactively generate traffic with the server.\n" + " -n\t\tspecify the number of associations to create.\n", + argv0); +} + +/* Parse command line options */ +void parse_arguments(int argc, char*argv[]) { + int c; + + while ((c = getopt(argc, argv, ":H:P:ach:ln:p:")) >= 0) { + switch (c) { + case 'H': + local_host = optarg; + break; + case 'P': + local_port = atoi(optarg); + break; + case 'c': + if (mode == NOT_DEFINED) + mode = CLIENT; + else { + usage(argv[0]); + exit(0); + } + break; + case 'a': + active = 1; + break; + case 'h': + remote_host = optarg; + break; + case 'l': + if (mode == NOT_DEFINED) + mode = SERVER; + else { + usage(argv[0]); + exit(0); + } + break; + case 'n': + assoc_num = atoi(optarg); + break; + case 'p': + remote_port = atoi(optarg); + break; + default: + usage(argv[0]); + exit(0); + } + } /* while() */ + + if (mode == CLIENT) { + if (assoc_num) { + if (assoc_num > MAXCLIENTNUM) { + printf("The number of associations indicated " + "is greater than the"); + printf("max number of associations " + "allowed(%d).", MAXCLIENTNUM); + usage(argv[0]); + exit(0); + } + } else + assoc_num = 1; + + if (remote_host && remote_port) { + hst = gethostbyname(remote_host); + + memcpy(&server_loop.v4.sin_addr, hst->h_addr_list[0], + sizeof(server_loop.v4.sin_addr)); + + server_loop.v4.sin_family = AF_INET; +server_loop.v4.sin_port = htons(remote_port); + } else { + printf("Remote host and remote port must be defined " + "in client mode\n"); + usage(argv[0]); + exit(0); + } + + if (local_host) { + hst = gethostbyname(local_host); + + memcpy(&client_loop.v4.sin_addr, hst->h_addr_list[0], + sizeof(client_loop.v4.sin_addr)); + } else + client_loop.v4.sin_addr.s_addr = INADDR_ANY; + + if (local_port) + client_loop.v4.sin_port = htons(local_port); + else + client_loop.v4.sin_port = 0; + + client_loop.v4.sin_family = AF_INET; + } else if (mode == SERVER) { + if (active) { + printf("This option if for client use only"); + usage(argv[0]); + exit(0); + } + + if (remote_host || remote_port) { + printf("Remote values not needed in server mode.\n"); + usage(argv[0]); + exit(0); + } + + if (local_host) { + hst = gethostbyname(local_host); + + memcpy(&server_loop.v4.sin_addr, hst->h_addr_list[0], + sizeof(server_loop.v4.sin_addr)); + } else + server_loop.v4.sin_addr.s_addr = INADDR_ANY; + + if (local_port) + server_loop.v4.sin_port = htons(local_port); + else { + printf("Specify a local port in server mode.\n"); + usage(argv[0]); + exit(0); + } + + server_loop.v4.sin_family = AF_INET; + } else { + printf("Must assisgn a client or server mode.\n"); + usage(argv[0]); + exit(0); + } +} /* parse_arguments() */ + +/* Handle data recieved */ +void data_received(struct msghdr *inmessage, int len, int stream, int socket) { + + int ppid, error; + char *ping = "PING"; + + if (mode == SERVER) { + ppid = rand(); + + error = sctp_sendmsg(socket, + inmessage->msg_iov->iov_base, + len, + (struct sockaddr *)inmessage->msg_name, + inmessage->msg_namelen, + ppid, + 0, + stream, + 0, 0); + + if (error < 0) { + printf("Send Failure: %s.\n", strerror(errno)); + DUMP_CORE; + } + } else { + ppid = rand(); + + printf("Data Received by socket #: %d.\n", socket); + printf("\tMessage = %s\n", + (char *)inmessage->msg_iov->iov_base); + + if (active) { + sctp_sendmsg(socket, + ping, + strlen(ping) + 1, + (struct sockaddr *)&server_loop, + sizeof (server_loop), + ppid, + 0, + stream, + 0, 0); + } + } +} + +/* This will print what type of SCTP_ASSOC_CHANGE state that was recieved */ +void print_sctp_sac_state(struct msghdr *msg) { + + char *data; + union sctp_notification *sn; + + if (msg->msg_flags & MSG_NOTIFICATION) { + data = (char *)msg->msg_iov[0].iov_base; + + sn = (union sctp_notification *)data; + + switch (sn->sn_assoc_change.sac_state) { + case SCTP_COMM_UP: + printf("SCTP_COMM_UP\n"); + break; + case SCTP_COMM_LOST: + printf("SCTP_COMM_LOST\n"); + break; + case SCTP_RESTART: + printf("SCTP_RESTART"); + break; + case SCTP_SHUTDOWN_COMP: + printf("SCTP_SHUTDOWN_COMP\n"); + break; + case SCTP_CANT_STR_ASSOC: + printf("SCTP_CANT_STR_ASSOC\n"); + break; + default: + break; + } + } +} /* void print_sctp_sac_state() */ + +/* Tests what type of MSG_NOTIFICATION has been received. +* For now this fucntion only works with SCTP_ASSOC_CHANGE +* types, but can be easily expanded. +* +* Will return... +* -1 if the msg_flags is not MSG_NOTIFICATION +* 0 if the MSG_NOTIFICATION type differs from the type +* passed into the additional variable +* 1 if the MSG_NOTIFICATION type matches the type +* passed into the additional variable +*/ +int test_check_notification_type(struct msghdr *msg, + uint16_t sn_type, + uint32_t additional) { + + char *data; + union sctp_notification *sn; + + if (!(msg->msg_flags & MSG_NOTIFICATION)) { + return -1; + } else { + + /* Fixup for testframe. */ + data = (char *)msg->msg_iov[0].iov_base; + + sn = (union sctp_notification *)data; + + if (sn->sn_header.sn_type != sn_type) + return 0; + else if (sn->sn_header.sn_type == SCTP_ASSOC_CHANGE) + if (sn->sn_assoc_change.sac_state == additional) + return 1; + return 0; + } +} + +/* Determine the type of event and make correct adjustments to the +* association count +*/ +int event_received(struct msghdr *inmessage, int assoc_num) { + + int error; + + printf("Event Received\n"); + + print_sctp_sac_state(inmessage); + + if (mode == SERVER) { + /* Test type of Event */ + error = test_check_notification_type(inmessage, + SCTP_ASSOC_CHANGE, + SCTP_COMM_UP); + if (error > 0) { + assoc_num++; + printf("Assosiation Established: count = %d.\n", + assoc_num); + } else { + error = test_check_notification_type(inmessage, + SCTP_ASSOC_CHANGE, + SCTP_SHUTDOWN_COMP); + + if (error > 0) { + assoc_num--; + printf("Assosiation Shutdown: count = %d.\n", + assoc_num); + } + } + } + return assoc_num; +} + +void server_mode() { + sockaddr_storage_t msgname; + int server_socket, + error, + stream; + int assoc_num =0; + struct msghdr inmessage; + struct iovec iov; + char *big_buffer; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + + if ((big_buffer = malloc(REALLY_BIG)) == NULL) { + printf("malloc failure: %s\n", strerror(errno)); + DUMP_CORE; + } + + printf("Running in Server Mode...\n"); + + memset(&inmessage, 0, sizeof(inmessage)); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen =1; + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + inmessage.msg_name = &msgname; + inmessage.msg_namelen = sizeof (msgname); + + stream = 1; + + server_socket = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + if (server_socket < 0) { + printf("Socket Failure: %s.\n", strerror(errno)); + DUMP_CORE; + } + + error = bind(server_socket, &server_loop.sa, sizeof(server_loop)); + if (error != 0 ) { + printf("Bind Failure: %s.\n", strerror(errno)); + DUMP_CORE; + } + + error = listen(server_socket, 1); + if (error != 0) { + printf("Listen Failure: %s.\n", strerror(errno)); + DUMP_CORE; + } + while (TRUE) { + error = recvmsg(server_socket, &inmessage, MSG_WAITALL); + if (error < 0) { + printf("Receive Failure: %s\n", + strerror(errno)); + } else { + if (inmessage.msg_flags & MSG_NOTIFICATION) + assoc_num = event_received(&inmessage, assoc_num); + else + data_received(&inmessage, error, stream, server_socket); + } + } +} + +void client_mode() { + + int i, error, stream, max_socket = 0; + uint32_t ppid = 0; + int client_socket[assoc_num]; + char *message = "Awake"; + fd_set rfds; + struct timeval tv; + + stream = 1; + + printf("Running in Client Mode...\n"); + + /* Create the sockets */ + for (i = 0; i < assoc_num; i++) { + client_socket[i] = socket(PF_INET, SOCK_SEQPACKET, + IPPROTO_SCTP); + if (client_socket[i] < 0 ){ + printf("Socket Failure: %s.\n", strerror(errno)); + DUMP_CORE; + } + + if (local_port) { + error = bind(client_socket[i], &client_loop.sa, + sizeof(client_loop)); + if (error < 0) { + printf("Bind Failure: %s\n", strerror(errno)); + DUMP_CORE; + } + } + + printf("Create Socket #: %d\n", client_socket[i]); + + /* Connect to server and send initial message */ + error = connect(client_socket[i], &server_loop.sa, + sizeof(server_loop)); + if (error < 0){ + printf("Connect Failure: %s.\n", strerror(errno)); + DUMP_CORE; + } + + max_socket = client_socket[i]; + + ppid++; + + /* Send initial message */ + error = sctp_sendmsg(client_socket[i], + message, + strlen(message) + 1, + (struct sockaddr *)&server_loop, + sizeof(server_loop), + ppid, + 0, + stream, + 0, 0); + if (error < 0 ) { + printf("Send Failure: %s.\n", strerror(errno)); + DUMP_CORE; + } + } + + while (TRUE){ + + /* Clear the set for select() */ + FD_ZERO(&rfds); + + /* Set time out values for select() */ + tv.tv_sec = 5; + tv.tv_usec = 0; + + /* Add the sockets select() will examine */ + for (i = 0; i < assoc_num; i++) { + FD_SET(client_socket[i], &rfds); + } + + /* Wait until there is data to be read from one of the + * sockets, or until the timer expires + */ + error = select(max_socket + 1, &rfds, NULL, NULL, &tv); + + if (error < 0) { + printf("Select Failure: %s.\n", strerror(errno)); + DUMP_CORE; + } else if (error) { + /* Loop through the array of sockets to find the ones + *that have information to be read + */ + process_ready_sockets(client_socket, assoc_num, &rfds); + } + } +} + +void process_ready_sockets(int client_socket[], int assoc_num, fd_set *rfds) { + + int i, stream, error; + struct msghdr inmessage; + struct iovec iov; + char *big_buffer; + char incmsg[CMSG_SPACE(sizeof (sctp_cmsg_data_t))]; + sockaddr_storage_t msgname; + + if ((big_buffer = malloc(REALLY_BIG)) == NULL) { + printf("malloc failure: %s\n", strerror(errno)); + DUMP_CORE; + } + + /* Setup inmessage to be able to receive in incomming message */ + memset(&inmessage, 0, sizeof (inmessage)); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen =1; + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof (incmsg); + inmessage.msg_name = &msgname; + inmessage.msg_namelen = sizeof (msgname); + + stream = 1; + + for( i = 0; i < assoc_num; i++) { + if (FD_ISSET(client_socket[i], rfds)) { + error = recvmsg(client_socket[i], &inmessage, + MSG_WAITALL); + if (error < 0) + printf("Receive Failure: %s\n", + strerror(errno)); + else { + /* Test to find the type of message that was read(event/data) */ + if (inmessage.msg_flags & + MSG_NOTIFICATION) + event_received(&inmessage, + 0); + + else + data_received(&inmessage, error, + stream, + client_socket[i]); + } + } + } +} + +int main(int argc, char *argv[]) { + + parse_arguments(argc, argv); + + if (mode == SERVER) { + server_mode(); + } else if (mode == CLIENT){ + client_mode(); + } + exit(1); +} + diff --git a/src/func_tests/Makefile.am b/src/func_tests/Makefile.am new file mode 100644 index 0000000..44f0e94 --- /dev/null +++ b/src/func_tests/Makefile.am @@ -0,0 +1,167 @@ +# Include these two in all the Makefile.am's!!! +include $(top_srcdir)/Makefile.vars +include $(top_srcdir)/Makefile.rules + +include $(top_srcdir)/Makefile.dirs + +# General compilation flags +INCLUDES = -I. -I$(top_srcdir)/src/include -I$(top_srcdir)/src/testlib +AM_CFLAGS = -g -Wall -Wstrict-prototypes -Wimplicit-function-declaration +AM_LDFLAGS = -lpthread +LDADD = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la + +V6FLAGS = -DCONFIG_IPV6=1 -DTEST_V6=1 ${DEFS} ${INCLUDES} ${CFLAGS} + +# Test programs and libraries to build +PASSING_KERN_TESTS = \ + test_assoc_abort \ + test_assoc_shutdown \ + test_autoclose \ + test_basic \ + test_fragments \ + test_inaddr_any \ + test_peeloff \ + test_sockopt \ + test_connect \ + test_connectx \ + test_recvmsg \ + test_timetolive \ + test_sctp_sendrecvmsg \ + test_getname \ + test_tcp_style\ + test_1_to_1_socket_bind_listen \ + test_1_to_1_accept_close \ + test_1_to_1_connect \ + test_1_to_1_connectx \ + test_1_to_1_send \ + test_1_to_1_sendto \ + test_1_to_1_sendmsg \ + test_1_to_1_recvfrom \ + test_1_to_1_recvmsg \ + test_1_to_1_shutdown \ + test_1_to_1_sockopt \ + test_1_to_1_addrs \ + test_1_to_1_nonblock \ + test_1_to_1_rtoinfo \ + test_1_to_1_events \ + test_1_to_1_threads \ + test_1_to_1_initmsg_connect + +PASSING_V6_KERN_TESTS = \ + test_basic_v6 \ + test_sockopt_v6 \ + test_fragments_v6 \ + test_inaddr_any_v6 \ + test_peeloff_v6 \ + test_timetolive_v6 \ + test_sctp_sendrecvmsg_v6 \ + test_getname_v6 \ + test_tcp_style_v6 + +noinst_PROGRAMS = ${PASSING_KERN_TESTS} ${PASSING_V6_KERN_TESTS} + +$(top_builddir)/src/lib/libsctp.la: + make -C $(top_builddir)/src/lib libsctp.la + +$(top_builddir)/src/testlib/libsctputil.la: + make -C $(top_builddir)/src/testlib libsctputil.la + +# These are tests for live kernels which pass. +v4test: ${PASSING_KERN_TESTS} + @for a in $^; \ + do \ + echo "./$$a"; \ + if ./$$a; \ + then \ + echo "$$a passes"; \ + echo ""; \ + else \ + echo "$$a fails"; \ + exit 1; \ + fi; \ + sleep 1; \ + done + @echo "Hoody hoo!" + +# These are tests for live kernels which pass. +v6test: ${PASSING_V6_KERN_TESTS} + @for a in $^; \ + do \ + echo "./$$a"; \ + if ./$$a; \ + then \ + echo "$$a passes"; \ + echo ""; \ + else \ + echo "$$a fails"; \ + exit 1; \ + fi; \ + sleep 1; \ + done + @echo "Hoody hoo!" + +# Specifying the sources +test_assoc_abort_SOURCES = test_assoc_abort.c +test_assoc_shutdown_SOURCES = test_assoc_shutdown.c +test_autoclose_SOURCES = test_autoclose.c +test_basic_SOURCES = test_basic.c +test_fragments_SOURCES = test_fragments.c +test_inaddr_any_SOURCES = test_inaddr_any.c +test_peeloff_SOURCES = test_peeloff.c +test_sockopt_SOURCES = test_sockopt.c +test_connect_SOURCES = test_connect.c +test_connectx_SOURCES = test_connectx.c +test_recvmsg_SOURCES = test_recvmsg.c +test_timetolive_SOURCES = test_timetolive.c +test_sctp_sendrecvmsg_SOURCES = test_sctp_sendrecvmsg.c +test_getname_SOURCES = test_getname.c +test_tcp_style_SOURCES = test_tcp_style.c + +test_1_to_1_socket_bind_listen_SOURCES = test_1_to_1_socket_bind_listen.c +test_1_to_1_accept_close_SOURCES = test_1_to_1_accept_close.c +test_1_to_1_connect_SOURCES = test_1_to_1_connect.c +test_1_to_1_connectx_SOURCES = test_1_to_1_connectx.c +test_1_to_1_send_SOURCES = test_1_to_1_send.c +test_1_to_1_sendto_SOURCES = test_1_to_1_sendto.c +test_1_to_1_sendmsg_SOURCES = test_1_to_1_sendmsg.c +test_1_to_1_recvfrom_SOURCES = test_1_to_1_recvfrom.c +test_1_to_1_recvmsg_SOURCES = test_1_to_1_recvmsg.c +test_1_to_1_shutdown_SOURCES = test_1_to_1_shutdown.c +test_1_to_1_sockopt_SOURCES = test_1_to_1_sockopt.c +test_1_to_1_addrs_SOURCES = test_1_to_1_addrs.c +test_1_to_1_nonblock_SOURCES = test_1_to_1_nonblock.c +test_1_to_1_rtoinfo_SOURCES = test_1_to_1_rtoinfo.c +test_1_to_1_events_SOURCES = test_1_to_1_events.c +test_1_to_1_threads_SOURCES = test_1_to_1_threads.c +test_1_to_1_initmsg_connect_SOURCES = test_1_to_1_initmsg_connect.c + +# +# Specifying objects rules for "v6test" +# +test_basic_v6_SOURCES = test_basic.c +test_basic_v6_CFLAGS = ${V6FLAGS} + +test_sockopt_v6_SOURCES = test_sockopt.c +test_sockopt_v6_CFLAGS = ${V6FLAGS} + +test_fragments_v6_SOURCES = test_fragments.c +test_fragments_v6_CFLAGS = ${V6FLAGS} + +test_inaddr_any_v6_SOURCES = test_inaddr_any.c +test_inaddr_any_v6_CFLAGS = ${V6FLAGS} + +test_peeloff_v6_SOURCES = test_peeloff.c +test_peeloff_v6_CFLAGS = ${V6FLAGS} + +test_timetolive_v6_SOURCES = test_timetolive.c +test_timetolive_v6_CFLAGS = ${V6FLAGS} + +test_sctp_sendrecvmsg_v6_SOURCES = test_sctp_sendrecvmsg.c +test_sctp_sendrecvmsg_v6_CFLAGS = ${V6FLAGS} + +test_getname_v6_SOURCES = test_getname.c +test_getname_v6_CFLAGS = ${V6FLAGS} + +test_tcp_style_v6_SOURCES = test_tcp_style.c +test_tcp_style_v6_CFLAGS = ${V6FLAGS} diff --git a/src/func_tests/Makefile.in b/src/func_tests/Makefile.in new file mode 100644 index 0000000..5cfa0d3 --- /dev/null +++ b/src/func_tests/Makefile.in @@ -0,0 +1,1276 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*-makefile-*- +# +# type: deep, strictness: gnu + +# -*-makefile-*- +# +# Define here directories you want + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.dirs $(top_srcdir)/Makefile.rules \ + $(top_srcdir)/Makefile.vars +noinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) +subdir = src/func_tests +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__EXEEXT_1 = test_assoc_abort$(EXEEXT) test_assoc_shutdown$(EXEEXT) \ + test_autoclose$(EXEEXT) test_basic$(EXEEXT) \ + test_fragments$(EXEEXT) test_inaddr_any$(EXEEXT) \ + test_peeloff$(EXEEXT) test_sockopt$(EXEEXT) \ + test_connect$(EXEEXT) test_connectx$(EXEEXT) \ + test_recvmsg$(EXEEXT) test_timetolive$(EXEEXT) \ + test_sctp_sendrecvmsg$(EXEEXT) test_getname$(EXEEXT) \ + test_tcp_style$(EXEEXT) \ + test_1_to_1_socket_bind_listen$(EXEEXT) \ + test_1_to_1_accept_close$(EXEEXT) test_1_to_1_connect$(EXEEXT) \ + test_1_to_1_connectx$(EXEEXT) test_1_to_1_send$(EXEEXT) \ + test_1_to_1_sendto$(EXEEXT) test_1_to_1_sendmsg$(EXEEXT) \ + test_1_to_1_recvfrom$(EXEEXT) test_1_to_1_recvmsg$(EXEEXT) \ + test_1_to_1_shutdown$(EXEEXT) test_1_to_1_sockopt$(EXEEXT) \ + test_1_to_1_addrs$(EXEEXT) test_1_to_1_nonblock$(EXEEXT) \ + test_1_to_1_rtoinfo$(EXEEXT) test_1_to_1_events$(EXEEXT) \ + test_1_to_1_threads$(EXEEXT) \ + test_1_to_1_initmsg_connect$(EXEEXT) +am__EXEEXT_2 = test_basic_v6$(EXEEXT) test_sockopt_v6$(EXEEXT) \ + test_fragments_v6$(EXEEXT) test_inaddr_any_v6$(EXEEXT) \ + test_peeloff_v6$(EXEEXT) test_timetolive_v6$(EXEEXT) \ + test_sctp_sendrecvmsg_v6$(EXEEXT) test_getname_v6$(EXEEXT) \ + test_tcp_style_v6$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) +am_test_1_to_1_accept_close_OBJECTS = \ + test_1_to_1_accept_close.$(OBJEXT) +test_1_to_1_accept_close_OBJECTS = \ + $(am_test_1_to_1_accept_close_OBJECTS) +test_1_to_1_accept_close_LDADD = $(LDADD) +test_1_to_1_accept_close_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_addrs_OBJECTS = test_1_to_1_addrs.$(OBJEXT) +test_1_to_1_addrs_OBJECTS = $(am_test_1_to_1_addrs_OBJECTS) +test_1_to_1_addrs_LDADD = $(LDADD) +test_1_to_1_addrs_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_connect_OBJECTS = test_1_to_1_connect.$(OBJEXT) +test_1_to_1_connect_OBJECTS = $(am_test_1_to_1_connect_OBJECTS) +test_1_to_1_connect_LDADD = $(LDADD) +test_1_to_1_connect_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_connectx_OBJECTS = test_1_to_1_connectx.$(OBJEXT) +test_1_to_1_connectx_OBJECTS = $(am_test_1_to_1_connectx_OBJECTS) +test_1_to_1_connectx_LDADD = $(LDADD) +test_1_to_1_connectx_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_events_OBJECTS = test_1_to_1_events.$(OBJEXT) +test_1_to_1_events_OBJECTS = $(am_test_1_to_1_events_OBJECTS) +test_1_to_1_events_LDADD = $(LDADD) +test_1_to_1_events_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_initmsg_connect_OBJECTS = \ + test_1_to_1_initmsg_connect.$(OBJEXT) +test_1_to_1_initmsg_connect_OBJECTS = \ + $(am_test_1_to_1_initmsg_connect_OBJECTS) +test_1_to_1_initmsg_connect_LDADD = $(LDADD) +test_1_to_1_initmsg_connect_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_nonblock_OBJECTS = test_1_to_1_nonblock.$(OBJEXT) +test_1_to_1_nonblock_OBJECTS = $(am_test_1_to_1_nonblock_OBJECTS) +test_1_to_1_nonblock_LDADD = $(LDADD) +test_1_to_1_nonblock_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_recvfrom_OBJECTS = test_1_to_1_recvfrom.$(OBJEXT) +test_1_to_1_recvfrom_OBJECTS = $(am_test_1_to_1_recvfrom_OBJECTS) +test_1_to_1_recvfrom_LDADD = $(LDADD) +test_1_to_1_recvfrom_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_recvmsg_OBJECTS = test_1_to_1_recvmsg.$(OBJEXT) +test_1_to_1_recvmsg_OBJECTS = $(am_test_1_to_1_recvmsg_OBJECTS) +test_1_to_1_recvmsg_LDADD = $(LDADD) +test_1_to_1_recvmsg_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_rtoinfo_OBJECTS = test_1_to_1_rtoinfo.$(OBJEXT) +test_1_to_1_rtoinfo_OBJECTS = $(am_test_1_to_1_rtoinfo_OBJECTS) +test_1_to_1_rtoinfo_LDADD = $(LDADD) +test_1_to_1_rtoinfo_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_send_OBJECTS = test_1_to_1_send.$(OBJEXT) +test_1_to_1_send_OBJECTS = $(am_test_1_to_1_send_OBJECTS) +test_1_to_1_send_LDADD = $(LDADD) +test_1_to_1_send_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_sendmsg_OBJECTS = test_1_to_1_sendmsg.$(OBJEXT) +test_1_to_1_sendmsg_OBJECTS = $(am_test_1_to_1_sendmsg_OBJECTS) +test_1_to_1_sendmsg_LDADD = $(LDADD) +test_1_to_1_sendmsg_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_sendto_OBJECTS = test_1_to_1_sendto.$(OBJEXT) +test_1_to_1_sendto_OBJECTS = $(am_test_1_to_1_sendto_OBJECTS) +test_1_to_1_sendto_LDADD = $(LDADD) +test_1_to_1_sendto_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_shutdown_OBJECTS = test_1_to_1_shutdown.$(OBJEXT) +test_1_to_1_shutdown_OBJECTS = $(am_test_1_to_1_shutdown_OBJECTS) +test_1_to_1_shutdown_LDADD = $(LDADD) +test_1_to_1_shutdown_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_socket_bind_listen_OBJECTS = \ + test_1_to_1_socket_bind_listen.$(OBJEXT) +test_1_to_1_socket_bind_listen_OBJECTS = \ + $(am_test_1_to_1_socket_bind_listen_OBJECTS) +test_1_to_1_socket_bind_listen_LDADD = $(LDADD) +test_1_to_1_socket_bind_listen_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_sockopt_OBJECTS = test_1_to_1_sockopt.$(OBJEXT) +test_1_to_1_sockopt_OBJECTS = $(am_test_1_to_1_sockopt_OBJECTS) +test_1_to_1_sockopt_LDADD = $(LDADD) +test_1_to_1_sockopt_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_1_to_1_threads_OBJECTS = test_1_to_1_threads.$(OBJEXT) +test_1_to_1_threads_OBJECTS = $(am_test_1_to_1_threads_OBJECTS) +test_1_to_1_threads_LDADD = $(LDADD) +test_1_to_1_threads_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_assoc_abort_OBJECTS = test_assoc_abort.$(OBJEXT) +test_assoc_abort_OBJECTS = $(am_test_assoc_abort_OBJECTS) +test_assoc_abort_LDADD = $(LDADD) +test_assoc_abort_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_assoc_shutdown_OBJECTS = test_assoc_shutdown.$(OBJEXT) +test_assoc_shutdown_OBJECTS = $(am_test_assoc_shutdown_OBJECTS) +test_assoc_shutdown_LDADD = $(LDADD) +test_assoc_shutdown_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_autoclose_OBJECTS = test_autoclose.$(OBJEXT) +test_autoclose_OBJECTS = $(am_test_autoclose_OBJECTS) +test_autoclose_LDADD = $(LDADD) +test_autoclose_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_basic_OBJECTS = test_basic.$(OBJEXT) +test_basic_OBJECTS = $(am_test_basic_OBJECTS) +test_basic_LDADD = $(LDADD) +test_basic_DEPENDENCIES = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_basic_v6_OBJECTS = test_basic_v6-test_basic.$(OBJEXT) +test_basic_v6_OBJECTS = $(am_test_basic_v6_OBJECTS) +test_basic_v6_LDADD = $(LDADD) +test_basic_v6_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_connect_OBJECTS = test_connect.$(OBJEXT) +test_connect_OBJECTS = $(am_test_connect_OBJECTS) +test_connect_LDADD = $(LDADD) +test_connect_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_connectx_OBJECTS = test_connectx.$(OBJEXT) +test_connectx_OBJECTS = $(am_test_connectx_OBJECTS) +test_connectx_LDADD = $(LDADD) +test_connectx_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_fragments_OBJECTS = test_fragments.$(OBJEXT) +test_fragments_OBJECTS = $(am_test_fragments_OBJECTS) +test_fragments_LDADD = $(LDADD) +test_fragments_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_fragments_v6_OBJECTS = \ + test_fragments_v6-test_fragments.$(OBJEXT) +test_fragments_v6_OBJECTS = $(am_test_fragments_v6_OBJECTS) +test_fragments_v6_LDADD = $(LDADD) +test_fragments_v6_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_getname_OBJECTS = test_getname.$(OBJEXT) +test_getname_OBJECTS = $(am_test_getname_OBJECTS) +test_getname_LDADD = $(LDADD) +test_getname_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_getname_v6_OBJECTS = test_getname_v6-test_getname.$(OBJEXT) +test_getname_v6_OBJECTS = $(am_test_getname_v6_OBJECTS) +test_getname_v6_LDADD = $(LDADD) +test_getname_v6_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_inaddr_any_OBJECTS = test_inaddr_any.$(OBJEXT) +test_inaddr_any_OBJECTS = $(am_test_inaddr_any_OBJECTS) +test_inaddr_any_LDADD = $(LDADD) +test_inaddr_any_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_inaddr_any_v6_OBJECTS = \ + test_inaddr_any_v6-test_inaddr_any.$(OBJEXT) +test_inaddr_any_v6_OBJECTS = $(am_test_inaddr_any_v6_OBJECTS) +test_inaddr_any_v6_LDADD = $(LDADD) +test_inaddr_any_v6_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_peeloff_OBJECTS = test_peeloff.$(OBJEXT) +test_peeloff_OBJECTS = $(am_test_peeloff_OBJECTS) +test_peeloff_LDADD = $(LDADD) +test_peeloff_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_peeloff_v6_OBJECTS = test_peeloff_v6-test_peeloff.$(OBJEXT) +test_peeloff_v6_OBJECTS = $(am_test_peeloff_v6_OBJECTS) +test_peeloff_v6_LDADD = $(LDADD) +test_peeloff_v6_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_recvmsg_OBJECTS = test_recvmsg.$(OBJEXT) +test_recvmsg_OBJECTS = $(am_test_recvmsg_OBJECTS) +test_recvmsg_LDADD = $(LDADD) +test_recvmsg_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_sctp_sendrecvmsg_OBJECTS = test_sctp_sendrecvmsg.$(OBJEXT) +test_sctp_sendrecvmsg_OBJECTS = $(am_test_sctp_sendrecvmsg_OBJECTS) +test_sctp_sendrecvmsg_LDADD = $(LDADD) +test_sctp_sendrecvmsg_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_sctp_sendrecvmsg_v6_OBJECTS = \ + test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.$(OBJEXT) +test_sctp_sendrecvmsg_v6_OBJECTS = \ + $(am_test_sctp_sendrecvmsg_v6_OBJECTS) +test_sctp_sendrecvmsg_v6_LDADD = $(LDADD) +test_sctp_sendrecvmsg_v6_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_sockopt_OBJECTS = test_sockopt.$(OBJEXT) +test_sockopt_OBJECTS = $(am_test_sockopt_OBJECTS) +test_sockopt_LDADD = $(LDADD) +test_sockopt_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_sockopt_v6_OBJECTS = test_sockopt_v6-test_sockopt.$(OBJEXT) +test_sockopt_v6_OBJECTS = $(am_test_sockopt_v6_OBJECTS) +test_sockopt_v6_LDADD = $(LDADD) +test_sockopt_v6_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_tcp_style_OBJECTS = test_tcp_style.$(OBJEXT) +test_tcp_style_OBJECTS = $(am_test_tcp_style_OBJECTS) +test_tcp_style_LDADD = $(LDADD) +test_tcp_style_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_tcp_style_v6_OBJECTS = \ + test_tcp_style_v6-test_tcp_style.$(OBJEXT) +test_tcp_style_v6_OBJECTS = $(am_test_tcp_style_v6_OBJECTS) +test_tcp_style_v6_LDADD = $(LDADD) +test_tcp_style_v6_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_timetolive_OBJECTS = test_timetolive.$(OBJEXT) +test_timetolive_OBJECTS = $(am_test_timetolive_OBJECTS) +test_timetolive_LDADD = $(LDADD) +test_timetolive_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +am_test_timetolive_v6_OBJECTS = \ + test_timetolive_v6-test_timetolive.$(OBJEXT) +test_timetolive_v6_OBJECTS = $(am_test_timetolive_v6_OBJECTS) +test_timetolive_v6_LDADD = $(LDADD) +test_timetolive_v6_DEPENDENCIES = \ + $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/bin/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(test_1_to_1_accept_close_SOURCES) \ + $(test_1_to_1_addrs_SOURCES) $(test_1_to_1_connect_SOURCES) \ + $(test_1_to_1_connectx_SOURCES) $(test_1_to_1_events_SOURCES) \ + $(test_1_to_1_initmsg_connect_SOURCES) \ + $(test_1_to_1_nonblock_SOURCES) \ + $(test_1_to_1_recvfrom_SOURCES) $(test_1_to_1_recvmsg_SOURCES) \ + $(test_1_to_1_rtoinfo_SOURCES) $(test_1_to_1_send_SOURCES) \ + $(test_1_to_1_sendmsg_SOURCES) $(test_1_to_1_sendto_SOURCES) \ + $(test_1_to_1_shutdown_SOURCES) \ + $(test_1_to_1_socket_bind_listen_SOURCES) \ + $(test_1_to_1_sockopt_SOURCES) $(test_1_to_1_threads_SOURCES) \ + $(test_assoc_abort_SOURCES) $(test_assoc_shutdown_SOURCES) \ + $(test_autoclose_SOURCES) $(test_basic_SOURCES) \ + $(test_basic_v6_SOURCES) $(test_connect_SOURCES) \ + $(test_connectx_SOURCES) $(test_fragments_SOURCES) \ + $(test_fragments_v6_SOURCES) $(test_getname_SOURCES) \ + $(test_getname_v6_SOURCES) $(test_inaddr_any_SOURCES) \ + $(test_inaddr_any_v6_SOURCES) $(test_peeloff_SOURCES) \ + $(test_peeloff_v6_SOURCES) $(test_recvmsg_SOURCES) \ + $(test_sctp_sendrecvmsg_SOURCES) \ + $(test_sctp_sendrecvmsg_v6_SOURCES) $(test_sockopt_SOURCES) \ + $(test_sockopt_v6_SOURCES) $(test_tcp_style_SOURCES) \ + $(test_tcp_style_v6_SOURCES) $(test_timetolive_SOURCES) \ + $(test_timetolive_v6_SOURCES) +DIST_SOURCES = $(test_1_to_1_accept_close_SOURCES) \ + $(test_1_to_1_addrs_SOURCES) $(test_1_to_1_connect_SOURCES) \ + $(test_1_to_1_connectx_SOURCES) $(test_1_to_1_events_SOURCES) \ + $(test_1_to_1_initmsg_connect_SOURCES) \ + $(test_1_to_1_nonblock_SOURCES) \ + $(test_1_to_1_recvfrom_SOURCES) $(test_1_to_1_recvmsg_SOURCES) \ + $(test_1_to_1_rtoinfo_SOURCES) $(test_1_to_1_send_SOURCES) \ + $(test_1_to_1_sendmsg_SOURCES) $(test_1_to_1_sendto_SOURCES) \ + $(test_1_to_1_shutdown_SOURCES) \ + $(test_1_to_1_socket_bind_listen_SOURCES) \ + $(test_1_to_1_sockopt_SOURCES) $(test_1_to_1_threads_SOURCES) \ + $(test_assoc_abort_SOURCES) $(test_assoc_shutdown_SOURCES) \ + $(test_autoclose_SOURCES) $(test_basic_SOURCES) \ + $(test_basic_v6_SOURCES) $(test_connect_SOURCES) \ + $(test_connectx_SOURCES) $(test_fragments_SOURCES) \ + $(test_fragments_v6_SOURCES) $(test_getname_SOURCES) \ + $(test_getname_v6_SOURCES) $(test_inaddr_any_SOURCES) \ + $(test_inaddr_any_v6_SOURCES) $(test_peeloff_SOURCES) \ + $(test_peeloff_v6_SOURCES) $(test_recvmsg_SOURCES) \ + $(test_sctp_sendrecvmsg_SOURCES) \ + $(test_sctp_sendrecvmsg_v6_SOURCES) $(test_sockopt_SOURCES) \ + $(test_sockopt_v6_SOURCES) $(test_tcp_style_SOURCES) \ + $(test_tcp_style_v6_SOURCES) $(test_timetolive_SOURCES) \ + $(test_timetolive_v6_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = $(datadir)/locale +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +MAINTAINERCLEANFILES = Makefile.in directories.h +DISTCLEANFILES = \\\ directories.h +CLEANFILES = +MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io +EXTRA_DIST = +LATEX = @LATEX@ +DVIPS = @DVIPS@ +DVIPDFM = @DVIPDFM@ +ENSCRIPTBIN = @ENSCRIPTBIN@ +PS2PDF = @PS2PDF@ +edit = @sed \ + -e "s|\@bindir\@|$(bindir)|" \ + -e "s|\@libdir\@|$(libdir)|" \ + -e "s|\@PACKAGE\@|$(PACKAGE)|" + +rootbindir = /bin +rootsbindir = /sbin +rootlibdir = /lib +pkgsysconfdir = $(sysconfdir)/@PACKAGE@ +pkgdocdir = $(datadir)/@PACKAGE@ +vpkgsysconfdir = $(pkgsysconfdir)/v@VERSION@ +vpkgdatadir = $(pkgdatadir)/v@VERSION@ +vpkglibdir = $(pkglibdir)/v@VERSION@ +vpkgdocdir = $(docdir)/v@VERSION@ + +# List here all the directories you want listed in the file to be used +# in your programs: +directories := \ + localedir \ + pkgsysconfdir \ + rootbindir \ + rootlibdir \ + rootsbindir \ + vpkgdatadir \ + vpkgdocdir \ + vpkglibdir \ + vpkgsysconfdir \ + \ + bindir \ + datadir \ + libdir \ + pkgdatadir \ + pkgdocdir \ + pkglibdir \ + sbindir + + +# Include these two in all the Makefile.am's!!! + +# General compilation flags +INCLUDES = -I. -I$(top_srcdir)/src/include -I$(top_srcdir)/src/testlib +AM_CFLAGS = -g -Wall -Wstrict-prototypes -Wimplicit-function-declaration +AM_LDFLAGS = -lpthread +LDADD = $(top_builddir)/src/testlib/libsctputil.la \ + $(top_builddir)/src/lib/libsctp.la + +V6FLAGS = -DCONFIG_IPV6=1 -DTEST_V6=1 ${DEFS} ${INCLUDES} ${CFLAGS} + +# Test programs and libraries to build +PASSING_KERN_TESTS = \ + test_assoc_abort \ + test_assoc_shutdown \ + test_autoclose \ + test_basic \ + test_fragments \ + test_inaddr_any \ + test_peeloff \ + test_sockopt \ + test_connect \ + test_connectx \ + test_recvmsg \ + test_timetolive \ + test_sctp_sendrecvmsg \ + test_getname \ + test_tcp_style\ + test_1_to_1_socket_bind_listen \ + test_1_to_1_accept_close \ + test_1_to_1_connect \ + test_1_to_1_connectx \ + test_1_to_1_send \ + test_1_to_1_sendto \ + test_1_to_1_sendmsg \ + test_1_to_1_recvfrom \ + test_1_to_1_recvmsg \ + test_1_to_1_shutdown \ + test_1_to_1_sockopt \ + test_1_to_1_addrs \ + test_1_to_1_nonblock \ + test_1_to_1_rtoinfo \ + test_1_to_1_events \ + test_1_to_1_threads \ + test_1_to_1_initmsg_connect + +PASSING_V6_KERN_TESTS = \ + test_basic_v6 \ + test_sockopt_v6 \ + test_fragments_v6 \ + test_inaddr_any_v6 \ + test_peeloff_v6 \ + test_timetolive_v6 \ + test_sctp_sendrecvmsg_v6 \ + test_getname_v6 \ + test_tcp_style_v6 + + +# Specifying the sources +test_assoc_abort_SOURCES = test_assoc_abort.c +test_assoc_shutdown_SOURCES = test_assoc_shutdown.c +test_autoclose_SOURCES = test_autoclose.c +test_basic_SOURCES = test_basic.c +test_fragments_SOURCES = test_fragments.c +test_inaddr_any_SOURCES = test_inaddr_any.c +test_peeloff_SOURCES = test_peeloff.c +test_sockopt_SOURCES = test_sockopt.c +test_connect_SOURCES = test_connect.c +test_connectx_SOURCES = test_connectx.c +test_recvmsg_SOURCES = test_recvmsg.c +test_timetolive_SOURCES = test_timetolive.c +test_sctp_sendrecvmsg_SOURCES = test_sctp_sendrecvmsg.c +test_getname_SOURCES = test_getname.c +test_tcp_style_SOURCES = test_tcp_style.c +test_1_to_1_socket_bind_listen_SOURCES = test_1_to_1_socket_bind_listen.c +test_1_to_1_accept_close_SOURCES = test_1_to_1_accept_close.c +test_1_to_1_connect_SOURCES = test_1_to_1_connect.c +test_1_to_1_connectx_SOURCES = test_1_to_1_connectx.c +test_1_to_1_send_SOURCES = test_1_to_1_send.c +test_1_to_1_sendto_SOURCES = test_1_to_1_sendto.c +test_1_to_1_sendmsg_SOURCES = test_1_to_1_sendmsg.c +test_1_to_1_recvfrom_SOURCES = test_1_to_1_recvfrom.c +test_1_to_1_recvmsg_SOURCES = test_1_to_1_recvmsg.c +test_1_to_1_shutdown_SOURCES = test_1_to_1_shutdown.c +test_1_to_1_sockopt_SOURCES = test_1_to_1_sockopt.c +test_1_to_1_addrs_SOURCES = test_1_to_1_addrs.c +test_1_to_1_nonblock_SOURCES = test_1_to_1_nonblock.c +test_1_to_1_rtoinfo_SOURCES = test_1_to_1_rtoinfo.c +test_1_to_1_events_SOURCES = test_1_to_1_events.c +test_1_to_1_threads_SOURCES = test_1_to_1_threads.c +test_1_to_1_initmsg_connect_SOURCES = test_1_to_1_initmsg_connect.c + +# +# Specifying objects rules for "v6test" +# +test_basic_v6_SOURCES = test_basic.c +test_basic_v6_CFLAGS = ${V6FLAGS} +test_sockopt_v6_SOURCES = test_sockopt.c +test_sockopt_v6_CFLAGS = ${V6FLAGS} +test_fragments_v6_SOURCES = test_fragments.c +test_fragments_v6_CFLAGS = ${V6FLAGS} +test_inaddr_any_v6_SOURCES = test_inaddr_any.c +test_inaddr_any_v6_CFLAGS = ${V6FLAGS} +test_peeloff_v6_SOURCES = test_peeloff.c +test_peeloff_v6_CFLAGS = ${V6FLAGS} +test_timetolive_v6_SOURCES = test_timetolive.c +test_timetolive_v6_CFLAGS = ${V6FLAGS} +test_sctp_sendrecvmsg_v6_SOURCES = test_sctp_sendrecvmsg.c +test_sctp_sendrecvmsg_v6_CFLAGS = ${V6FLAGS} +test_getname_v6_SOURCES = test_getname.c +test_getname_v6_CFLAGS = ${V6FLAGS} +test_tcp_style_v6_SOURCES = test_tcp_style.c +test_tcp_style_v6_CFLAGS = ${V6FLAGS} +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.vars $(top_srcdir)/Makefile.rules $(top_srcdir)/Makefile.dirs $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/func_tests/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/func_tests/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test_1_to_1_accept_close$(EXEEXT): $(test_1_to_1_accept_close_OBJECTS) $(test_1_to_1_accept_close_DEPENDENCIES) + @rm -f test_1_to_1_accept_close$(EXEEXT) + $(LINK) $(test_1_to_1_accept_close_LDFLAGS) $(test_1_to_1_accept_close_OBJECTS) $(test_1_to_1_accept_close_LDADD) $(LIBS) +test_1_to_1_addrs$(EXEEXT): $(test_1_to_1_addrs_OBJECTS) $(test_1_to_1_addrs_DEPENDENCIES) + @rm -f test_1_to_1_addrs$(EXEEXT) + $(LINK) $(test_1_to_1_addrs_LDFLAGS) $(test_1_to_1_addrs_OBJECTS) $(test_1_to_1_addrs_LDADD) $(LIBS) +test_1_to_1_connect$(EXEEXT): $(test_1_to_1_connect_OBJECTS) $(test_1_to_1_connect_DEPENDENCIES) + @rm -f test_1_to_1_connect$(EXEEXT) + $(LINK) $(test_1_to_1_connect_LDFLAGS) $(test_1_to_1_connect_OBJECTS) $(test_1_to_1_connect_LDADD) $(LIBS) +test_1_to_1_connectx$(EXEEXT): $(test_1_to_1_connectx_OBJECTS) $(test_1_to_1_connectx_DEPENDENCIES) + @rm -f test_1_to_1_connectx$(EXEEXT) + $(LINK) $(test_1_to_1_connectx_LDFLAGS) $(test_1_to_1_connectx_OBJECTS) $(test_1_to_1_connectx_LDADD) $(LIBS) +test_1_to_1_events$(EXEEXT): $(test_1_to_1_events_OBJECTS) $(test_1_to_1_events_DEPENDENCIES) + @rm -f test_1_to_1_events$(EXEEXT) + $(LINK) $(test_1_to_1_events_LDFLAGS) $(test_1_to_1_events_OBJECTS) $(test_1_to_1_events_LDADD) $(LIBS) +test_1_to_1_initmsg_connect$(EXEEXT): $(test_1_to_1_initmsg_connect_OBJECTS) $(test_1_to_1_initmsg_connect_DEPENDENCIES) + @rm -f test_1_to_1_initmsg_connect$(EXEEXT) + $(LINK) $(test_1_to_1_initmsg_connect_LDFLAGS) $(test_1_to_1_initmsg_connect_OBJECTS) $(test_1_to_1_initmsg_connect_LDADD) $(LIBS) +test_1_to_1_nonblock$(EXEEXT): $(test_1_to_1_nonblock_OBJECTS) $(test_1_to_1_nonblock_DEPENDENCIES) + @rm -f test_1_to_1_nonblock$(EXEEXT) + $(LINK) $(test_1_to_1_nonblock_LDFLAGS) $(test_1_to_1_nonblock_OBJECTS) $(test_1_to_1_nonblock_LDADD) $(LIBS) +test_1_to_1_recvfrom$(EXEEXT): $(test_1_to_1_recvfrom_OBJECTS) $(test_1_to_1_recvfrom_DEPENDENCIES) + @rm -f test_1_to_1_recvfrom$(EXEEXT) + $(LINK) $(test_1_to_1_recvfrom_LDFLAGS) $(test_1_to_1_recvfrom_OBJECTS) $(test_1_to_1_recvfrom_LDADD) $(LIBS) +test_1_to_1_recvmsg$(EXEEXT): $(test_1_to_1_recvmsg_OBJECTS) $(test_1_to_1_recvmsg_DEPENDENCIES) + @rm -f test_1_to_1_recvmsg$(EXEEXT) + $(LINK) $(test_1_to_1_recvmsg_LDFLAGS) $(test_1_to_1_recvmsg_OBJECTS) $(test_1_to_1_recvmsg_LDADD) $(LIBS) +test_1_to_1_rtoinfo$(EXEEXT): $(test_1_to_1_rtoinfo_OBJECTS) $(test_1_to_1_rtoinfo_DEPENDENCIES) + @rm -f test_1_to_1_rtoinfo$(EXEEXT) + $(LINK) $(test_1_to_1_rtoinfo_LDFLAGS) $(test_1_to_1_rtoinfo_OBJECTS) $(test_1_to_1_rtoinfo_LDADD) $(LIBS) +test_1_to_1_send$(EXEEXT): $(test_1_to_1_send_OBJECTS) $(test_1_to_1_send_DEPENDENCIES) + @rm -f test_1_to_1_send$(EXEEXT) + $(LINK) $(test_1_to_1_send_LDFLAGS) $(test_1_to_1_send_OBJECTS) $(test_1_to_1_send_LDADD) $(LIBS) +test_1_to_1_sendmsg$(EXEEXT): $(test_1_to_1_sendmsg_OBJECTS) $(test_1_to_1_sendmsg_DEPENDENCIES) + @rm -f test_1_to_1_sendmsg$(EXEEXT) + $(LINK) $(test_1_to_1_sendmsg_LDFLAGS) $(test_1_to_1_sendmsg_OBJECTS) $(test_1_to_1_sendmsg_LDADD) $(LIBS) +test_1_to_1_sendto$(EXEEXT): $(test_1_to_1_sendto_OBJECTS) $(test_1_to_1_sendto_DEPENDENCIES) + @rm -f test_1_to_1_sendto$(EXEEXT) + $(LINK) $(test_1_to_1_sendto_LDFLAGS) $(test_1_to_1_sendto_OBJECTS) $(test_1_to_1_sendto_LDADD) $(LIBS) +test_1_to_1_shutdown$(EXEEXT): $(test_1_to_1_shutdown_OBJECTS) $(test_1_to_1_shutdown_DEPENDENCIES) + @rm -f test_1_to_1_shutdown$(EXEEXT) + $(LINK) $(test_1_to_1_shutdown_LDFLAGS) $(test_1_to_1_shutdown_OBJECTS) $(test_1_to_1_shutdown_LDADD) $(LIBS) +test_1_to_1_socket_bind_listen$(EXEEXT): $(test_1_to_1_socket_bind_listen_OBJECTS) $(test_1_to_1_socket_bind_listen_DEPENDENCIES) + @rm -f test_1_to_1_socket_bind_listen$(EXEEXT) + $(LINK) $(test_1_to_1_socket_bind_listen_LDFLAGS) $(test_1_to_1_socket_bind_listen_OBJECTS) $(test_1_to_1_socket_bind_listen_LDADD) $(LIBS) +test_1_to_1_sockopt$(EXEEXT): $(test_1_to_1_sockopt_OBJECTS) $(test_1_to_1_sockopt_DEPENDENCIES) + @rm -f test_1_to_1_sockopt$(EXEEXT) + $(LINK) $(test_1_to_1_sockopt_LDFLAGS) $(test_1_to_1_sockopt_OBJECTS) $(test_1_to_1_sockopt_LDADD) $(LIBS) +test_1_to_1_threads$(EXEEXT): $(test_1_to_1_threads_OBJECTS) $(test_1_to_1_threads_DEPENDENCIES) + @rm -f test_1_to_1_threads$(EXEEXT) + $(LINK) $(test_1_to_1_threads_LDFLAGS) $(test_1_to_1_threads_OBJECTS) $(test_1_to_1_threads_LDADD) $(LIBS) +test_assoc_abort$(EXEEXT): $(test_assoc_abort_OBJECTS) $(test_assoc_abort_DEPENDENCIES) + @rm -f test_assoc_abort$(EXEEXT) + $(LINK) $(test_assoc_abort_LDFLAGS) $(test_assoc_abort_OBJECTS) $(test_assoc_abort_LDADD) $(LIBS) +test_assoc_shutdown$(EXEEXT): $(test_assoc_shutdown_OBJECTS) $(test_assoc_shutdown_DEPENDENCIES) + @rm -f test_assoc_shutdown$(EXEEXT) + $(LINK) $(test_assoc_shutdown_LDFLAGS) $(test_assoc_shutdown_OBJECTS) $(test_assoc_shutdown_LDADD) $(LIBS) +test_autoclose$(EXEEXT): $(test_autoclose_OBJECTS) $(test_autoclose_DEPENDENCIES) + @rm -f test_autoclose$(EXEEXT) + $(LINK) $(test_autoclose_LDFLAGS) $(test_autoclose_OBJECTS) $(test_autoclose_LDADD) $(LIBS) +test_basic$(EXEEXT): $(test_basic_OBJECTS) $(test_basic_DEPENDENCIES) + @rm -f test_basic$(EXEEXT) + $(LINK) $(test_basic_LDFLAGS) $(test_basic_OBJECTS) $(test_basic_LDADD) $(LIBS) +test_basic_v6$(EXEEXT): $(test_basic_v6_OBJECTS) $(test_basic_v6_DEPENDENCIES) + @rm -f test_basic_v6$(EXEEXT) + $(LINK) $(test_basic_v6_LDFLAGS) $(test_basic_v6_OBJECTS) $(test_basic_v6_LDADD) $(LIBS) +test_connect$(EXEEXT): $(test_connect_OBJECTS) $(test_connect_DEPENDENCIES) + @rm -f test_connect$(EXEEXT) + $(LINK) $(test_connect_LDFLAGS) $(test_connect_OBJECTS) $(test_connect_LDADD) $(LIBS) +test_connectx$(EXEEXT): $(test_connectx_OBJECTS) $(test_connectx_DEPENDENCIES) + @rm -f test_connectx$(EXEEXT) + $(LINK) $(test_connectx_LDFLAGS) $(test_connectx_OBJECTS) $(test_connectx_LDADD) $(LIBS) +test_fragments$(EXEEXT): $(test_fragments_OBJECTS) $(test_fragments_DEPENDENCIES) + @rm -f test_fragments$(EXEEXT) + $(LINK) $(test_fragments_LDFLAGS) $(test_fragments_OBJECTS) $(test_fragments_LDADD) $(LIBS) +test_fragments_v6$(EXEEXT): $(test_fragments_v6_OBJECTS) $(test_fragments_v6_DEPENDENCIES) + @rm -f test_fragments_v6$(EXEEXT) + $(LINK) $(test_fragments_v6_LDFLAGS) $(test_fragments_v6_OBJECTS) $(test_fragments_v6_LDADD) $(LIBS) +test_getname$(EXEEXT): $(test_getname_OBJECTS) $(test_getname_DEPENDENCIES) + @rm -f test_getname$(EXEEXT) + $(LINK) $(test_getname_LDFLAGS) $(test_getname_OBJECTS) $(test_getname_LDADD) $(LIBS) +test_getname_v6$(EXEEXT): $(test_getname_v6_OBJECTS) $(test_getname_v6_DEPENDENCIES) + @rm -f test_getname_v6$(EXEEXT) + $(LINK) $(test_getname_v6_LDFLAGS) $(test_getname_v6_OBJECTS) $(test_getname_v6_LDADD) $(LIBS) +test_inaddr_any$(EXEEXT): $(test_inaddr_any_OBJECTS) $(test_inaddr_any_DEPENDENCIES) + @rm -f test_inaddr_any$(EXEEXT) + $(LINK) $(test_inaddr_any_LDFLAGS) $(test_inaddr_any_OBJECTS) $(test_inaddr_any_LDADD) $(LIBS) +test_inaddr_any_v6$(EXEEXT): $(test_inaddr_any_v6_OBJECTS) $(test_inaddr_any_v6_DEPENDENCIES) + @rm -f test_inaddr_any_v6$(EXEEXT) + $(LINK) $(test_inaddr_any_v6_LDFLAGS) $(test_inaddr_any_v6_OBJECTS) $(test_inaddr_any_v6_LDADD) $(LIBS) +test_peeloff$(EXEEXT): $(test_peeloff_OBJECTS) $(test_peeloff_DEPENDENCIES) + @rm -f test_peeloff$(EXEEXT) + $(LINK) $(test_peeloff_LDFLAGS) $(test_peeloff_OBJECTS) $(test_peeloff_LDADD) $(LIBS) +test_peeloff_v6$(EXEEXT): $(test_peeloff_v6_OBJECTS) $(test_peeloff_v6_DEPENDENCIES) + @rm -f test_peeloff_v6$(EXEEXT) + $(LINK) $(test_peeloff_v6_LDFLAGS) $(test_peeloff_v6_OBJECTS) $(test_peeloff_v6_LDADD) $(LIBS) +test_recvmsg$(EXEEXT): $(test_recvmsg_OBJECTS) $(test_recvmsg_DEPENDENCIES) + @rm -f test_recvmsg$(EXEEXT) + $(LINK) $(test_recvmsg_LDFLAGS) $(test_recvmsg_OBJECTS) $(test_recvmsg_LDADD) $(LIBS) +test_sctp_sendrecvmsg$(EXEEXT): $(test_sctp_sendrecvmsg_OBJECTS) $(test_sctp_sendrecvmsg_DEPENDENCIES) + @rm -f test_sctp_sendrecvmsg$(EXEEXT) + $(LINK) $(test_sctp_sendrecvmsg_LDFLAGS) $(test_sctp_sendrecvmsg_OBJECTS) $(test_sctp_sendrecvmsg_LDADD) $(LIBS) +test_sctp_sendrecvmsg_v6$(EXEEXT): $(test_sctp_sendrecvmsg_v6_OBJECTS) $(test_sctp_sendrecvmsg_v6_DEPENDENCIES) + @rm -f test_sctp_sendrecvmsg_v6$(EXEEXT) + $(LINK) $(test_sctp_sendrecvmsg_v6_LDFLAGS) $(test_sctp_sendrecvmsg_v6_OBJECTS) $(test_sctp_sendrecvmsg_v6_LDADD) $(LIBS) +test_sockopt$(EXEEXT): $(test_sockopt_OBJECTS) $(test_sockopt_DEPENDENCIES) + @rm -f test_sockopt$(EXEEXT) + $(LINK) $(test_sockopt_LDFLAGS) $(test_sockopt_OBJECTS) $(test_sockopt_LDADD) $(LIBS) +test_sockopt_v6$(EXEEXT): $(test_sockopt_v6_OBJECTS) $(test_sockopt_v6_DEPENDENCIES) + @rm -f test_sockopt_v6$(EXEEXT) + $(LINK) $(test_sockopt_v6_LDFLAGS) $(test_sockopt_v6_OBJECTS) $(test_sockopt_v6_LDADD) $(LIBS) +test_tcp_style$(EXEEXT): $(test_tcp_style_OBJECTS) $(test_tcp_style_DEPENDENCIES) + @rm -f test_tcp_style$(EXEEXT) + $(LINK) $(test_tcp_style_LDFLAGS) $(test_tcp_style_OBJECTS) $(test_tcp_style_LDADD) $(LIBS) +test_tcp_style_v6$(EXEEXT): $(test_tcp_style_v6_OBJECTS) $(test_tcp_style_v6_DEPENDENCIES) + @rm -f test_tcp_style_v6$(EXEEXT) + $(LINK) $(test_tcp_style_v6_LDFLAGS) $(test_tcp_style_v6_OBJECTS) $(test_tcp_style_v6_LDADD) $(LIBS) +test_timetolive$(EXEEXT): $(test_timetolive_OBJECTS) $(test_timetolive_DEPENDENCIES) + @rm -f test_timetolive$(EXEEXT) + $(LINK) $(test_timetolive_LDFLAGS) $(test_timetolive_OBJECTS) $(test_timetolive_LDADD) $(LIBS) +test_timetolive_v6$(EXEEXT): $(test_timetolive_v6_OBJECTS) $(test_timetolive_v6_DEPENDENCIES) + @rm -f test_timetolive_v6$(EXEEXT) + $(LINK) $(test_timetolive_v6_LDFLAGS) $(test_timetolive_v6_OBJECTS) $(test_timetolive_v6_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_accept_close.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_addrs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_connect.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_connectx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_events.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_initmsg_connect.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_nonblock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_recvfrom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_recvmsg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_rtoinfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_send.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_sendmsg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_sendto.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_shutdown.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_socket_bind_listen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_sockopt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_1_to_1_threads.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_assoc_abort.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_assoc_shutdown.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_autoclose.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_basic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_basic_v6-test_basic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_connect.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_connectx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fragments.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fragments_v6-test_fragments.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_getname.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_getname_v6-test_getname.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_inaddr_any.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_inaddr_any_v6-test_inaddr_any.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_peeloff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_peeloff_v6-test_peeloff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_recvmsg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_sctp_sendrecvmsg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_sockopt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_sockopt_v6-test_sockopt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_tcp_style.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_tcp_style_v6-test_tcp_style.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_timetolive.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_timetolive_v6-test_timetolive.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test_basic_v6-test_basic.o: test_basic.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_basic_v6_CFLAGS) $(CFLAGS) -MT test_basic_v6-test_basic.o -MD -MP -MF "$(DEPDIR)/test_basic_v6-test_basic.Tpo" -c -o test_basic_v6-test_basic.o `test -f 'test_basic.c' || echo '$(srcdir)/'`test_basic.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_basic_v6-test_basic.Tpo" "$(DEPDIR)/test_basic_v6-test_basic.Po"; else rm -f "$(DEPDIR)/test_basic_v6-test_basic.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_basic.c' object='test_basic_v6-test_basic.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_basic_v6_CFLAGS) $(CFLAGS) -c -o test_basic_v6-test_basic.o `test -f 'test_basic.c' || echo '$(srcdir)/'`test_basic.c + +test_basic_v6-test_basic.obj: test_basic.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_basic_v6_CFLAGS) $(CFLAGS) -MT test_basic_v6-test_basic.obj -MD -MP -MF "$(DEPDIR)/test_basic_v6-test_basic.Tpo" -c -o test_basic_v6-test_basic.obj `if test -f 'test_basic.c'; then $(CYGPATH_W) 'test_basic.c'; else $(CYGPATH_W) '$(srcdir)/test_basic.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_basic_v6-test_basic.Tpo" "$(DEPDIR)/test_basic_v6-test_basic.Po"; else rm -f "$(DEPDIR)/test_basic_v6-test_basic.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_basic.c' object='test_basic_v6-test_basic.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_basic_v6_CFLAGS) $(CFLAGS) -c -o test_basic_v6-test_basic.obj `if test -f 'test_basic.c'; then $(CYGPATH_W) 'test_basic.c'; else $(CYGPATH_W) '$(srcdir)/test_basic.c'; fi` + +test_fragments_v6-test_fragments.o: test_fragments.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fragments_v6_CFLAGS) $(CFLAGS) -MT test_fragments_v6-test_fragments.o -MD -MP -MF "$(DEPDIR)/test_fragments_v6-test_fragments.Tpo" -c -o test_fragments_v6-test_fragments.o `test -f 'test_fragments.c' || echo '$(srcdir)/'`test_fragments.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_fragments_v6-test_fragments.Tpo" "$(DEPDIR)/test_fragments_v6-test_fragments.Po"; else rm -f "$(DEPDIR)/test_fragments_v6-test_fragments.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_fragments.c' object='test_fragments_v6-test_fragments.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fragments_v6_CFLAGS) $(CFLAGS) -c -o test_fragments_v6-test_fragments.o `test -f 'test_fragments.c' || echo '$(srcdir)/'`test_fragments.c + +test_fragments_v6-test_fragments.obj: test_fragments.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fragments_v6_CFLAGS) $(CFLAGS) -MT test_fragments_v6-test_fragments.obj -MD -MP -MF "$(DEPDIR)/test_fragments_v6-test_fragments.Tpo" -c -o test_fragments_v6-test_fragments.obj `if test -f 'test_fragments.c'; then $(CYGPATH_W) 'test_fragments.c'; else $(CYGPATH_W) '$(srcdir)/test_fragments.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_fragments_v6-test_fragments.Tpo" "$(DEPDIR)/test_fragments_v6-test_fragments.Po"; else rm -f "$(DEPDIR)/test_fragments_v6-test_fragments.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_fragments.c' object='test_fragments_v6-test_fragments.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fragments_v6_CFLAGS) $(CFLAGS) -c -o test_fragments_v6-test_fragments.obj `if test -f 'test_fragments.c'; then $(CYGPATH_W) 'test_fragments.c'; else $(CYGPATH_W) '$(srcdir)/test_fragments.c'; fi` + +test_getname_v6-test_getname.o: test_getname.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_getname_v6_CFLAGS) $(CFLAGS) -MT test_getname_v6-test_getname.o -MD -MP -MF "$(DEPDIR)/test_getname_v6-test_getname.Tpo" -c -o test_getname_v6-test_getname.o `test -f 'test_getname.c' || echo '$(srcdir)/'`test_getname.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_getname_v6-test_getname.Tpo" "$(DEPDIR)/test_getname_v6-test_getname.Po"; else rm -f "$(DEPDIR)/test_getname_v6-test_getname.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_getname.c' object='test_getname_v6-test_getname.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_getname_v6_CFLAGS) $(CFLAGS) -c -o test_getname_v6-test_getname.o `test -f 'test_getname.c' || echo '$(srcdir)/'`test_getname.c + +test_getname_v6-test_getname.obj: test_getname.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_getname_v6_CFLAGS) $(CFLAGS) -MT test_getname_v6-test_getname.obj -MD -MP -MF "$(DEPDIR)/test_getname_v6-test_getname.Tpo" -c -o test_getname_v6-test_getname.obj `if test -f 'test_getname.c'; then $(CYGPATH_W) 'test_getname.c'; else $(CYGPATH_W) '$(srcdir)/test_getname.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_getname_v6-test_getname.Tpo" "$(DEPDIR)/test_getname_v6-test_getname.Po"; else rm -f "$(DEPDIR)/test_getname_v6-test_getname.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_getname.c' object='test_getname_v6-test_getname.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_getname_v6_CFLAGS) $(CFLAGS) -c -o test_getname_v6-test_getname.obj `if test -f 'test_getname.c'; then $(CYGPATH_W) 'test_getname.c'; else $(CYGPATH_W) '$(srcdir)/test_getname.c'; fi` + +test_inaddr_any_v6-test_inaddr_any.o: test_inaddr_any.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_inaddr_any_v6_CFLAGS) $(CFLAGS) -MT test_inaddr_any_v6-test_inaddr_any.o -MD -MP -MF "$(DEPDIR)/test_inaddr_any_v6-test_inaddr_any.Tpo" -c -o test_inaddr_any_v6-test_inaddr_any.o `test -f 'test_inaddr_any.c' || echo '$(srcdir)/'`test_inaddr_any.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_inaddr_any_v6-test_inaddr_any.Tpo" "$(DEPDIR)/test_inaddr_any_v6-test_inaddr_any.Po"; else rm -f "$(DEPDIR)/test_inaddr_any_v6-test_inaddr_any.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_inaddr_any.c' object='test_inaddr_any_v6-test_inaddr_any.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_inaddr_any_v6_CFLAGS) $(CFLAGS) -c -o test_inaddr_any_v6-test_inaddr_any.o `test -f 'test_inaddr_any.c' || echo '$(srcdir)/'`test_inaddr_any.c + +test_inaddr_any_v6-test_inaddr_any.obj: test_inaddr_any.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_inaddr_any_v6_CFLAGS) $(CFLAGS) -MT test_inaddr_any_v6-test_inaddr_any.obj -MD -MP -MF "$(DEPDIR)/test_inaddr_any_v6-test_inaddr_any.Tpo" -c -o test_inaddr_any_v6-test_inaddr_any.obj `if test -f 'test_inaddr_any.c'; then $(CYGPATH_W) 'test_inaddr_any.c'; else $(CYGPATH_W) '$(srcdir)/test_inaddr_any.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_inaddr_any_v6-test_inaddr_any.Tpo" "$(DEPDIR)/test_inaddr_any_v6-test_inaddr_any.Po"; else rm -f "$(DEPDIR)/test_inaddr_any_v6-test_inaddr_any.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_inaddr_any.c' object='test_inaddr_any_v6-test_inaddr_any.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_inaddr_any_v6_CFLAGS) $(CFLAGS) -c -o test_inaddr_any_v6-test_inaddr_any.obj `if test -f 'test_inaddr_any.c'; then $(CYGPATH_W) 'test_inaddr_any.c'; else $(CYGPATH_W) '$(srcdir)/test_inaddr_any.c'; fi` + +test_peeloff_v6-test_peeloff.o: test_peeloff.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_peeloff_v6_CFLAGS) $(CFLAGS) -MT test_peeloff_v6-test_peeloff.o -MD -MP -MF "$(DEPDIR)/test_peeloff_v6-test_peeloff.Tpo" -c -o test_peeloff_v6-test_peeloff.o `test -f 'test_peeloff.c' || echo '$(srcdir)/'`test_peeloff.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_peeloff_v6-test_peeloff.Tpo" "$(DEPDIR)/test_peeloff_v6-test_peeloff.Po"; else rm -f "$(DEPDIR)/test_peeloff_v6-test_peeloff.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_peeloff.c' object='test_peeloff_v6-test_peeloff.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_peeloff_v6_CFLAGS) $(CFLAGS) -c -o test_peeloff_v6-test_peeloff.o `test -f 'test_peeloff.c' || echo '$(srcdir)/'`test_peeloff.c + +test_peeloff_v6-test_peeloff.obj: test_peeloff.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_peeloff_v6_CFLAGS) $(CFLAGS) -MT test_peeloff_v6-test_peeloff.obj -MD -MP -MF "$(DEPDIR)/test_peeloff_v6-test_peeloff.Tpo" -c -o test_peeloff_v6-test_peeloff.obj `if test -f 'test_peeloff.c'; then $(CYGPATH_W) 'test_peeloff.c'; else $(CYGPATH_W) '$(srcdir)/test_peeloff.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_peeloff_v6-test_peeloff.Tpo" "$(DEPDIR)/test_peeloff_v6-test_peeloff.Po"; else rm -f "$(DEPDIR)/test_peeloff_v6-test_peeloff.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_peeloff.c' object='test_peeloff_v6-test_peeloff.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_peeloff_v6_CFLAGS) $(CFLAGS) -c -o test_peeloff_v6-test_peeloff.obj `if test -f 'test_peeloff.c'; then $(CYGPATH_W) 'test_peeloff.c'; else $(CYGPATH_W) '$(srcdir)/test_peeloff.c'; fi` + +test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.o: test_sctp_sendrecvmsg.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sctp_sendrecvmsg_v6_CFLAGS) $(CFLAGS) -MT test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.o -MD -MP -MF "$(DEPDIR)/test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.Tpo" -c -o test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.o `test -f 'test_sctp_sendrecvmsg.c' || echo '$(srcdir)/'`test_sctp_sendrecvmsg.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.Tpo" "$(DEPDIR)/test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.Po"; else rm -f "$(DEPDIR)/test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_sctp_sendrecvmsg.c' object='test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sctp_sendrecvmsg_v6_CFLAGS) $(CFLAGS) -c -o test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.o `test -f 'test_sctp_sendrecvmsg.c' || echo '$(srcdir)/'`test_sctp_sendrecvmsg.c + +test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.obj: test_sctp_sendrecvmsg.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sctp_sendrecvmsg_v6_CFLAGS) $(CFLAGS) -MT test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.obj -MD -MP -MF "$(DEPDIR)/test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.Tpo" -c -o test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.obj `if test -f 'test_sctp_sendrecvmsg.c'; then $(CYGPATH_W) 'test_sctp_sendrecvmsg.c'; else $(CYGPATH_W) '$(srcdir)/test_sctp_sendrecvmsg.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.Tpo" "$(DEPDIR)/test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.Po"; else rm -f "$(DEPDIR)/test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_sctp_sendrecvmsg.c' object='test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sctp_sendrecvmsg_v6_CFLAGS) $(CFLAGS) -c -o test_sctp_sendrecvmsg_v6-test_sctp_sendrecvmsg.obj `if test -f 'test_sctp_sendrecvmsg.c'; then $(CYGPATH_W) 'test_sctp_sendrecvmsg.c'; else $(CYGPATH_W) '$(srcdir)/test_sctp_sendrecvmsg.c'; fi` + +test_sockopt_v6-test_sockopt.o: test_sockopt.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sockopt_v6_CFLAGS) $(CFLAGS) -MT test_sockopt_v6-test_sockopt.o -MD -MP -MF "$(DEPDIR)/test_sockopt_v6-test_sockopt.Tpo" -c -o test_sockopt_v6-test_sockopt.o `test -f 'test_sockopt.c' || echo '$(srcdir)/'`test_sockopt.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_sockopt_v6-test_sockopt.Tpo" "$(DEPDIR)/test_sockopt_v6-test_sockopt.Po"; else rm -f "$(DEPDIR)/test_sockopt_v6-test_sockopt.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_sockopt.c' object='test_sockopt_v6-test_sockopt.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sockopt_v6_CFLAGS) $(CFLAGS) -c -o test_sockopt_v6-test_sockopt.o `test -f 'test_sockopt.c' || echo '$(srcdir)/'`test_sockopt.c + +test_sockopt_v6-test_sockopt.obj: test_sockopt.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sockopt_v6_CFLAGS) $(CFLAGS) -MT test_sockopt_v6-test_sockopt.obj -MD -MP -MF "$(DEPDIR)/test_sockopt_v6-test_sockopt.Tpo" -c -o test_sockopt_v6-test_sockopt.obj `if test -f 'test_sockopt.c'; then $(CYGPATH_W) 'test_sockopt.c'; else $(CYGPATH_W) '$(srcdir)/test_sockopt.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_sockopt_v6-test_sockopt.Tpo" "$(DEPDIR)/test_sockopt_v6-test_sockopt.Po"; else rm -f "$(DEPDIR)/test_sockopt_v6-test_sockopt.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_sockopt.c' object='test_sockopt_v6-test_sockopt.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sockopt_v6_CFLAGS) $(CFLAGS) -c -o test_sockopt_v6-test_sockopt.obj `if test -f 'test_sockopt.c'; then $(CYGPATH_W) 'test_sockopt.c'; else $(CYGPATH_W) '$(srcdir)/test_sockopt.c'; fi` + +test_tcp_style_v6-test_tcp_style.o: test_tcp_style.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_tcp_style_v6_CFLAGS) $(CFLAGS) -MT test_tcp_style_v6-test_tcp_style.o -MD -MP -MF "$(DEPDIR)/test_tcp_style_v6-test_tcp_style.Tpo" -c -o test_tcp_style_v6-test_tcp_style.o `test -f 'test_tcp_style.c' || echo '$(srcdir)/'`test_tcp_style.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_tcp_style_v6-test_tcp_style.Tpo" "$(DEPDIR)/test_tcp_style_v6-test_tcp_style.Po"; else rm -f "$(DEPDIR)/test_tcp_style_v6-test_tcp_style.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_tcp_style.c' object='test_tcp_style_v6-test_tcp_style.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_tcp_style_v6_CFLAGS) $(CFLAGS) -c -o test_tcp_style_v6-test_tcp_style.o `test -f 'test_tcp_style.c' || echo '$(srcdir)/'`test_tcp_style.c + +test_tcp_style_v6-test_tcp_style.obj: test_tcp_style.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_tcp_style_v6_CFLAGS) $(CFLAGS) -MT test_tcp_style_v6-test_tcp_style.obj -MD -MP -MF "$(DEPDIR)/test_tcp_style_v6-test_tcp_style.Tpo" -c -o test_tcp_style_v6-test_tcp_style.obj `if test -f 'test_tcp_style.c'; then $(CYGPATH_W) 'test_tcp_style.c'; else $(CYGPATH_W) '$(srcdir)/test_tcp_style.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_tcp_style_v6-test_tcp_style.Tpo" "$(DEPDIR)/test_tcp_style_v6-test_tcp_style.Po"; else rm -f "$(DEPDIR)/test_tcp_style_v6-test_tcp_style.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_tcp_style.c' object='test_tcp_style_v6-test_tcp_style.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_tcp_style_v6_CFLAGS) $(CFLAGS) -c -o test_tcp_style_v6-test_tcp_style.obj `if test -f 'test_tcp_style.c'; then $(CYGPATH_W) 'test_tcp_style.c'; else $(CYGPATH_W) '$(srcdir)/test_tcp_style.c'; fi` + +test_timetolive_v6-test_timetolive.o: test_timetolive.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timetolive_v6_CFLAGS) $(CFLAGS) -MT test_timetolive_v6-test_timetolive.o -MD -MP -MF "$(DEPDIR)/test_timetolive_v6-test_timetolive.Tpo" -c -o test_timetolive_v6-test_timetolive.o `test -f 'test_timetolive.c' || echo '$(srcdir)/'`test_timetolive.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_timetolive_v6-test_timetolive.Tpo" "$(DEPDIR)/test_timetolive_v6-test_timetolive.Po"; else rm -f "$(DEPDIR)/test_timetolive_v6-test_timetolive.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_timetolive.c' object='test_timetolive_v6-test_timetolive.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timetolive_v6_CFLAGS) $(CFLAGS) -c -o test_timetolive_v6-test_timetolive.o `test -f 'test_timetolive.c' || echo '$(srcdir)/'`test_timetolive.c + +test_timetolive_v6-test_timetolive.obj: test_timetolive.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timetolive_v6_CFLAGS) $(CFLAGS) -MT test_timetolive_v6-test_timetolive.obj -MD -MP -MF "$(DEPDIR)/test_timetolive_v6-test_timetolive.Tpo" -c -o test_timetolive_v6-test_timetolive.obj `if test -f 'test_timetolive.c'; then $(CYGPATH_W) 'test_timetolive.c'; else $(CYGPATH_W) '$(srcdir)/test_timetolive.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test_timetolive_v6-test_timetolive.Tpo" "$(DEPDIR)/test_timetolive_v6-test_timetolive.Po"; else rm -f "$(DEPDIR)/test_timetolive_v6-test_timetolive.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_timetolive.c' object='test_timetolive_v6-test_timetolive.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timetolive_v6_CFLAGS) $(CFLAGS) -c -o test_timetolive_v6-test_timetolive.obj `if test -f 'test_timetolive.c'; then $(CYGPATH_W) 'test_timetolive.c'; else $(CYGPATH_W) '$(srcdir)/test_timetolive.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/../.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-info-am + + +# -*-makefile-*- +# +# Generate pre-parsed C code. +%.i: %.c + $(COMPILE) -E -c $^ -o $@ + +.PRECIOUS: %.i +%.ci: %.i + -grep -v -e "^#" -e "^ *$$" $^ | indent > $@ + mv -f $@ $^ + +# To modify this target for another language, just copy, paste and +# modify the target to generate directories.h. We depend on +# config.status and Makefile.dirs, as anything changed is going to be +# reflected there. + +# This is for generating the list in C/C++ +directories.h: $(top_builddir)/config.status $(top_srcdir)/Makefile.dirs + @rm -f $@ + @echo -n "Creating $@ ..." + @echo "#ifndef __$(subst .,_,$@)__" > $@ + @echo "# define __$(subst .,_,$@)__" >> $@ + @echo "" >> $@ + @echo -e $(foreach v,$(directories),$(shell echo 'D_$(v) \"$($v)\"\\n')) \ + | sed 's/^ *D_/# define D_/' >> $@ + @echo "#endif" >> $@ + @echo " done" + +$(top_builddir)/src/lib/libsctp.la: + make -C $(top_builddir)/src/lib libsctp.la + +$(top_builddir)/src/testlib/libsctputil.la: + make -C $(top_builddir)/src/testlib libsctputil.la + +# These are tests for live kernels which pass. +v4test: ${PASSING_KERN_TESTS} + @for a in $^; \ + do \ + echo "./$$a"; \ + if ./$$a; \ + then \ + echo "$$a passes"; \ + echo ""; \ + else \ + echo "$$a fails"; \ + exit 1; \ + fi; \ + sleep 1; \ + done + @echo "Hoody hoo!" + +# These are tests for live kernels which pass. +v6test: ${PASSING_V6_KERN_TESTS} + @for a in $^; \ + do \ + echo "./$$a"; \ + if ./$$a; \ + then \ + echo "$$a passes"; \ + echo ""; \ + else \ + echo "$$a fails"; \ + exit 1; \ + fi; \ + sleep 1; \ + done + @echo "Hoody hoo!" +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/func_tests/test_1_to_1_accept_close.c b/src/func_tests/test_1_to_1_accept_close.c new file mode 100644 index 0000000..ea1c57a --- /dev/null +++ b/src/func_tests/test_1_to_1_accept_close.c @@ -0,0 +1,233 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test the accept () and close () call for + * 1-1 style sockets + * + * accept () Tests: + * --------------- + * TEST1: Bad socket descriptor + * TEST2: Invalid socket + * TEST3: Invalid address + * TEST4: On a non-listening socket + * TEST5: On a established socket + * TEST6: On a CLOSED association + * TEST7: Extracting the association on the listening socket + * + * close () Tests: + * -------------- + * TEST8: Bad socket descriptor + * TEST9: valid socket descriptor + * TEST10: Closed socket descriptor + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 10; +int TST_CNT = 0; + +#define SK_MAX 10 + +int +main(int argc, char *argv[]) +{ + socklen_t len; + int i; + int sk,lstn_sk,clnt_sk[SK_MAX],acpt_sk,pf_class; + int new_sk[SK_MAX],clnt2_sk[SK_MAX]; + int error; + + struct sockaddr_in conn_addr,lstn_addr,acpt_addr; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + pf_class = PF_INET; + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + for (i=0 ; i < SK_MAX ; i++) + new_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /* Creating a regular socket */ + for (i = 0 ; i < SK_MAX ; i++) + clnt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + for (i = 0 ; i < SK_MAX ; i++) + clnt2_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /* Creating a listen socket */ + lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + /* Binding the listen socket */ + test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + /* Listening many sockets as we are calling too many connect here */ + test_listen(lstn_sk, SK_MAX ); + + /* connect() is called just to make sure accept() doesn't block the + * program + */ + i = 0; + len = sizeof(struct sockaddr_in); + test_connect(clnt_sk[i++], (struct sockaddr *) &conn_addr, len); + + /* accept() TEST1: Bad socket descriptor EBADF, Expected error */ + error = accept(-1, (struct sockaddr *) &acpt_addr, &len); + if (error != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "accept with a bad socket descriptor" + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "accept() with a bad socket descriptor - EBADF"); + + /*accept() TEST2: Invalid socket ENOTSOCK, Expected error*/ + error = accept(0, (struct sockaddr *) &acpt_addr, &len); + if (error != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "accept with invalid socket" + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "accept() with invalid socket - ENOTSOCK"); + + /*accept() TEST3: Invalid address EFAULT, Expected error*/ + error = accept(lstn_sk, (struct sockaddr *) -1, &len); + if (error != -1 || errno != EFAULT) + tst_brkm(TBROK, tst_exit, "accept with invalid address" + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "accept() with invalid address - EFAULT"); + + test_connect(clnt_sk[i++], (struct sockaddr *) &conn_addr, len); + + /*accept() TEST4: on a non-listening socket EINVAL, Expected error*/ + error = accept(sk, (struct sockaddr *) &acpt_addr, &len); + if (error != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "accept on a non-listening socket" + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "accept() on a non-listening socket - EINVAL"); + + test_connect(clnt_sk[i++], (struct sockaddr *) &conn_addr, len); + + /*Calling accept to establish the connection*/ + acpt_sk = test_accept(lstn_sk, (struct sockaddr *) &acpt_addr, &len); + + /*accept() TEST5: On a established socket EINVAL, Expected error*/ + error = accept(acpt_sk, (struct sockaddr *) &acpt_addr, &len); + if (error != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "accept on an established socket" + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "accept() on an established socket - EINVAL"); + + /*Closing the previously established association*/ + close(acpt_sk); + + test_connect(clnt_sk[i], (struct sockaddr *) &conn_addr, len); + + /*accept() TEST6: On the CLOSED association should succeed*/ + acpt_sk = accept(lstn_sk, (struct sockaddr *) &acpt_addr, &len); + if (acpt_sk < 0) + tst_brkm(TBROK, tst_exit, "accept a closed association" + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "accept() a closed association - SUCCESS"); + + close(acpt_sk); + + /*accept() TEST7: Extracting the association on the listening socket + as new socket, new socket socket descriptor should return*/ + for (i = 0 ; i < (SK_MAX - 1); i++) + test_connect(clnt2_sk[i], (struct sockaddr *) &conn_addr, len); + + for (i = 0 ; i < (SK_MAX - 1); i++) + new_sk[i] = test_accept(lstn_sk, (struct sockaddr *)&acpt_addr, + &len); + + tst_resm(TPASS, "accept() on a listening socket - SUCCESS"); + + + /*close() TEST8: Bad socket descriptor, EBADF Expected error*/ + error = close(-1); + if (error != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "close with a bad socket descriptor " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "close() with a bad socket descriptor - EBADF"); + + /*close() TEST9: valid socket descriptor should succeed*/ + error = close(sk); + if (error < 0) + tst_brkm(TBROK, tst_exit, "close with a valid socket descriptor" + " error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "close() with a valid socket descriptor - SUCCESS"); + + /*close() TEST10: closed socket descriptor, EBADF Expected error*/ + error = close(sk); + if (error != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "close with a closed socket " + "descriptor error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "close() with a closed socket descriptor - EBADF"); + + for (i = 0 ; i < SK_MAX ; i++) { + close(clnt_sk[i]); + close(new_sk[i]); + close(clnt2_sk[i]); + } + + return 0; +} diff --git a/src/func_tests/test_1_to_1_addrs.c b/src/func_tests/test_1_to_1_addrs.c new file mode 100644 index 0000000..4a16e80 --- /dev/null +++ b/src/func_tests/test_1_to_1_addrs.c @@ -0,0 +1,277 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test the sctp_getladdrs (), sctp_freealddrs (), + * sctp_getpaddrs (), sctp_freeapaddrs () for 1-1 style sockets + * + * sctp_getladdrs () Tests: + * ----------------------- + * TEST1: Bad socket descriptor + * TEST2: Invalid socket + * TEST3: Socket of different protocol + * TEST4: Getting the local addresses + * + * sctp_freealddrs () Tests: + * ------------------------ + * TEST5: Freeing the local address + * + * sctp_getpaddrs () Tests: + * ----------------------- + * TEST6: Bad socket descriptor + * TEST7: Invalid socket + * TEST8: Socket of different protocol + * TEST9: Getting the peers addresses + * + * sctp_freeapddrs () Tests: + * ------------------------ + * TEST10: Freeing the peer's address + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 10; +int TST_CNT = 0; + +int +main(int argc, char *argv[]) +{ + int error; + socklen_t len; + int sk,lstn_sk,clnt_sk,acpt_sk,pf_class,sk1; + struct msghdr outmessage; + struct msghdr inmessage; + char *message = "hello, world!\n"; + struct iovec iov; + struct iovec iov_rcv; + struct sctp_sndrcvinfo *sinfo; + int msg_count; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct iovec out_iov; + char * buffer_snd; + char * buffer_rcv; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + struct sockaddr *laddrs, *paddrs; + + struct sockaddr_in conn_addr,lstn_addr,acpt_addr; + struct sockaddr_in *addr; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + pf_class = PF_INET; + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /*Creating a regular socket*/ + clnt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /*Creating a listen socket*/ + lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + /*Binding the listen socket*/ + test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + /*Listening many sockets as we are calling too many connect here*/ + test_listen(lstn_sk, 1); + + len = sizeof(struct sockaddr_in); + + test_connect(clnt_sk, (struct sockaddr *) &conn_addr, len); + + acpt_sk = test_accept(lstn_sk, (struct sockaddr *) &acpt_addr, &len); + + memset(&inmessage, 0, sizeof(inmessage)); + buffer_rcv = malloc(REALLY_BIG); + + iov_rcv.iov_base = buffer_rcv; + iov_rcv.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov_rcv; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + + msg_count = strlen(message) + 1; + + memset(&outmessage, 0, sizeof(outmessage)); + buffer_snd = malloc(REALLY_BIG); + + outmessage.msg_name = &lstn_addr; + outmessage.msg_namelen = sizeof(lstn_addr); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + + iov.iov_base = buffer_snd; + iov.iov_len = REALLY_BIG; + outmessage.msg_iov->iov_base = message; + + outmessage.msg_iov->iov_len = msg_count; + test_sendmsg(clnt_sk, &outmessage, MSG_NOSIGNAL, msg_count); + + test_recvmsg(acpt_sk, &inmessage, MSG_NOSIGNAL); + + /*sctp_getladdrs() TEST1: Bad socket descriptor, EBADF Expected error*/ + error = sctp_getladdrs(-1, 0, &laddrs); + if (error != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "sctp_getladdrs with a bad socket " + "descriptor error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_getladdrs() with a bad socket descriptor - " + "EBADF"); + + /*sctp_getladdrs() TEST2: Invalid socket, ENOTSOCK Expected error*/ + error = sctp_getladdrs(0, 0, &laddrs); + if (error != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "sctp_getladdrs with invalid socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_getladdrs() with invalid socket - ENOTSOCK"); + + /*sctp_getladdrs() TEST3: socket of different protocol + EOPNOTSUPP Expected error*/ + sk1 = socket(pf_class, SOCK_STREAM, IPPROTO_IP); + error = sctp_getladdrs(sk1, 0, &laddrs); + if (error != -1 || errno != EOPNOTSUPP) + tst_brkm(TBROK, tst_exit, "sctp_getladdrs with socket of " + "different protocol error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_getladdrs() with socket of different protocol - " + "EOPNOTSUPP"); + + /*sctp_getladdrs() TEST4: Getting the local addresses*/ + error = sctp_getladdrs(lstn_sk, 0, &laddrs); + if (error < 0) + tst_brkm(TBROK, tst_exit, "sctp_getladdrs with valid socket " + "error:%d, errno:%d", error, errno); + + addr = (struct sockaddr_in *)laddrs; + if (addr->sin_port != lstn_addr.sin_port || + addr->sin_family != lstn_addr.sin_family || + addr->sin_addr.s_addr != lstn_addr.sin_addr.s_addr) + tst_brkm(TBROK, tst_exit, "sctp_getladdrs comparision failed"); + + tst_resm(TPASS, "sctp_getladdrs() - SUCCESS"); + + /*sctp_freealddrs() TEST5: freeing the local address*/ + if ((sctp_freeladdrs(laddrs)) < 0) + tst_brkm(TBROK, tst_exit, "sctp_freeladdrs " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_freeladdrs() - SUCCESS"); + + /*sctp_getpaddrs() TEST6: Bad socket descriptor, EBADF Expected error*/ + error = sctp_getpaddrs(-1, 0, &paddrs); + if (error != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with a bad socket " + "descriptor error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_getpaddrs() with a bad socket descriptor - " + "EBADF"); + + /*sctp_getpaddrs() TEST7: Invalid socket, ENOTSOCK Expected error*/ + error = sctp_getpaddrs(0, 0, &paddrs); + if (error != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with invalid socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_getpaddrs() with invalid socket - ENOTSOCK"); + + /*sctp_getpaddrs() TEST8: socket of different protocol + EOPNOTSUPP Expected error*/ + error = sctp_getpaddrs(sk1, 0, &laddrs); + if (error != -1 || errno != EOPNOTSUPP) + tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with socket of " + "different protocol error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_getpaddrs() with socket of different protocol - " + "EOPNOTSUPP"); + + /*sctp_getpaddrs() TEST9: Getting the peer addresses*/ + error = sctp_getpaddrs(acpt_sk, 0, &paddrs); + if (error < 0) + tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with valid socket " + "error:%d, errno:%d", error, errno); + + addr = (struct sockaddr_in *)paddrs; + if (addr->sin_port != acpt_addr.sin_port || + addr->sin_family != acpt_addr.sin_family || + addr->sin_addr.s_addr != acpt_addr.sin_addr.s_addr) + tst_brkm(TBROK, tst_exit, "sctp_getpaddrs comparision failed"); + + tst_resm(TPASS, "sctp_getpaddrs() - SUCCESS"); + + /*sctp_freeapddrs() TEST10: freeing the peer address*/ + if ((sctp_freepaddrs(paddrs)) < 0) + tst_brkm(TBROK, tst_exit, "sctp_freepaddrs " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_freepaddrs() - SUCCESS"); + + close(clnt_sk); + + return 0; +} diff --git a/src/func_tests/test_1_to_1_connect.c b/src/func_tests/test_1_to_1_connect.c new file mode 100644 index 0000000..6670f72 --- /dev/null +++ b/src/func_tests/test_1_to_1_connect.c @@ -0,0 +1,223 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test the connect () call for 1-1 style sockets + * + * TEST1: Bad socket descriptor + * TEST2: Invalid socket + * TEST3: Invalid address + * TEST4: Invalid address length + * TEST5: Invalid address family + * TEST6: Valid blocking connect + * TEST7: Connect when accept queue is full + * TEST8: On a listening socket + * TEST9: On established socket + * TEST10: Connect to re-establish a closed association. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include +#include "sctputil.h" + +char *TCID = __FILE__; +int TST_TOTAL = 10; +int TST_CNT = 0; + +#define SK_MAX 10 + +int +main(int argc, char *argv[]) +{ + int error,i; + socklen_t len; + int sk,lstn_sk,clnt_sk[SK_MAX],acpt_sk[SK_MAX],pf_class; + int sk1,clnt2_sk; + + struct sockaddr_in conn_addr,lstn_addr,acpt_addr; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + pf_class = PF_INET; + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /*Creating a listen socket*/ + lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /*Creating a regular socket*/ + for (i = 0 ; i < SK_MAX ; i++) + clnt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + clnt2_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + /*Binding the listen socket*/ + test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + /*Listening the socket*/ + test_listen(lstn_sk, SK_MAX-1); + + + /*connect () TEST1: Bad socket descriptor, EBADF Expected error*/ + len = sizeof(struct sockaddr_in); + error = connect(-1, (const struct sockaddr *) &conn_addr, len); + if (error != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "connect with bad socket " + "descriptor error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "connect() with bad socket descriptor - EBADF"); + + /*connect () TEST2: Invalid socket, ENOTSOCK Expected error*/ + error = connect(0, (const struct sockaddr *) &conn_addr, len); + if (error != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "connect with invalid socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "connect() with invalid socket - ENOTSOCK"); + + /*connect () TEST3: Invalid address, EFAULT Expected error*/ + error = connect(sk, (const struct sockaddr *) -1, len); + if (error != -1 || errno != EFAULT) + tst_brkm(TBROK, tst_exit, "connect with invalid address " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "connect() with invalid address - EFAULT"); + + /*connect () TEST4: Invalid address length, EINVAL Expected error*/ + error = connect(sk, (const struct sockaddr *) &conn_addr, (len - 3)); + if (error != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "connect with invalid address length " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "connect() with invalid address length - EINVAL"); + + /*connect () TEST5: Invalid address family, EINVAL Expect error*/ + conn_addr.sin_family = 9090; /*Assigning invalid address family*/ + error = connect(sk, (const struct sockaddr *) &conn_addr, len); + if (error != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "connect with invalid address family " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "connect() with invalid address family - EINVAL"); + + conn_addr.sin_family = AF_INET; + + /*connect () TEST6: Blocking connect, should pass*/ + /*All the be below blocking connect should pass as socket will be + listening SK_MAX clients*/ + for (i = 0 ; i < SK_MAX ; i++) { + error = connect(clnt_sk[i], (const struct sockaddr *)&conn_addr, + len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "valid blocking connect " + "error:%d, errno:%d", error, errno); + } + + tst_resm(TPASS, "valid blocking connect() - SUCCESS"); + + /*connect () TEST7: connect when accept queue is full, ECONNREFUSED + Expect error*/ + /*Now that accept queue is full, the below connect should fail*/ + error = connect(clnt2_sk, (const struct sockaddr *) &conn_addr, len); + if (error != -1 || errno != ECONNREFUSED) + tst_brkm(TBROK, tst_exit, "connect when accept queue is full " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "connect() when accept queue is full - ECONNREFUSED"); + + /*Calling a accept first to estblish the pending connections*/ + for (i=0 ; i < SK_MAX ; i++) + acpt_sk[i] = test_accept(lstn_sk, + (struct sockaddr *) &acpt_addr, &len); + + /*connect () TEST8: from a listening socket, EISCONN Expect error*/ + error = connect(lstn_sk, (const struct sockaddr *) &lstn_addr, len); + if (error != -1 || errno != EISCONN) + tst_brkm(TBROK, tst_exit, "connect on a listening socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "connect() on a listening socket - EISCONN"); + + /*connect() TEST9: On established socket, EISCONN Expect error*/ + i=0; + error = connect(acpt_sk[i], (const struct sockaddr *) &lstn_addr, len); + if (error != -1 || errno != EISCONN) + tst_brkm(TBROK, tst_exit, "connect on an established socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "connect() on an established socket - EISCONN"); + + for (i = 0 ; i < 4 ; i++) { + close(clnt_sk[i]); + close(acpt_sk[i]); + } + + /* connect() TEST10: Re-establish an association that is closed. + * should succeed. + */ + error = connect(sk1, (const struct sockaddr *)&conn_addr, len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "Re-establish an association that " + "is closed error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "connect() to re-establish a closed association - " + "SUCCESS"); + + close(sk); + close(sk1); + close(lstn_sk); + + return 0; +} diff --git a/src/func_tests/test_1_to_1_connectx.c b/src/func_tests/test_1_to_1_connectx.c new file mode 100644 index 0000000..04e20bf --- /dev/null +++ b/src/func_tests/test_1_to_1_connectx.c @@ -0,0 +1,226 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test the sctp_connectx () call for 1-1 style sockets + * + * TEST1: Bad socket descriptor + * TEST2: Invalid socket + * TEST3: Invalid address + * TEST4: Invalid address length + * TEST5: Invalid address family + * TEST6: Valid blocking sctp_connectx + * TEST7: Connect when accept queue is full + * TEST8: On a listening socket + * TEST9: On established socket + * TEST10: Connect to re-establish a closed association. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include +#include "sctputil.h" + +char *TCID = __FILE__; +int TST_TOTAL = 10; +int TST_CNT = 0; + +#define SK_MAX 10 + +int +main(int argc, char *argv[]) +{ + int error,i; + socklen_t len; + int sk,lstn_sk,clnt_sk[SK_MAX],acpt_sk[SK_MAX],pf_class; + int sk1,clnt2_sk; + + struct sockaddr_in conn_addr,lstn_addr,acpt_addr; + struct sockaddr *tmp_addr; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + pf_class = PF_INET; + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /*Creating a listen socket*/ + lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /*Creating a regular socket*/ + for (i = 0 ; i < SK_MAX ; i++) + clnt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + clnt2_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + /*Binding the listen socket*/ + test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + /*Listening the socket*/ + test_listen(lstn_sk, SK_MAX-1); + + + /*sctp_connectx () TEST1: Bad socket descriptor, EBADF Expected error*/ + len = sizeof(struct sockaddr_in); + error = sctp_connectx(-1, (struct sockaddr *) &conn_addr, 1, NULL); + if (error != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "sctp_connectx with bad socket " + "descriptor error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_connectx() with bad socket descriptor - EBADF"); + + /*sctp_connectx () TEST2: Invalid socket, ENOTSOCK Expected error*/ + error = sctp_connectx(0, (struct sockaddr *) &conn_addr, 1, NULL); + if (error != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "sctp_connectx with invalid socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_connectx() with invalid socket - ENOTSOCK"); + + /*sctp_connectx () TEST3: Invalid address, EINVAL Expected error*/ + tmp_addr = (struct sockaddr *) malloc(sizeof(struct sockaddr) - 1); + tmp_addr->sa_family = AF_INET; + error = sctp_connectx(sk, tmp_addr, 1, NULL); + if (error != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "sctp_connectx with invalid address " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_connectx() with invalid address - EINVAL"); + + /*sctp_connectx () TEST4: Invalid address length, EINVAL Expected error*/ + error = sctp_connectx(sk, (struct sockaddr *) &conn_addr, 0, NULL); + if (error != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "sctp_connectx with invalid address length " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_connectx() with invalid address length - EINVAL"); + + /*sctp_connectx () TEST5: Invalid address family, EINVAL Expect error*/ + conn_addr.sin_family = 9090; /*Assigning invalid address family*/ + error = sctp_connectx(sk, (struct sockaddr *) &conn_addr, 1, NULL); + if (error != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "sctp_connectx with invalid address family " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_connectx() with invalid address family - EINVAL"); + + conn_addr.sin_family = AF_INET; + + /*sctp_connectx () TEST6: Blocking sctp_connectx, should pass*/ + /*All the be below blocking sctp_connectx should pass as socket will be + listening SK_MAX clients*/ + for (i = 0 ; i < SK_MAX ; i++) { + error = sctp_connectx(clnt_sk[i], (struct sockaddr *)&conn_addr, + 1, NULL); + if (error < 0) + tst_brkm(TBROK, tst_exit, "valid blocking sctp_connectx " + "error:%d, errno:%d", error, errno); + } + + tst_resm(TPASS, "valid blocking sctp_connectx() - SUCCESS"); + + /*sctp_connectx () TEST7: sctp_connectx when accept queue is full, ECONNREFUSED + Expect error*/ + /*Now that accept queue is full, the below sctp_connectx should fail*/ + error = sctp_connectx(clnt2_sk, (struct sockaddr *) &conn_addr, 1, NULL); + if (error != -1 || errno != ECONNREFUSED) + tst_brkm(TBROK, tst_exit, "sctp_connectx when accept queue is full " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_connectx() when accept queue is full - ECONNREFUSED"); + + /*Calling a accept first to estblish the pending sctp_connectxions*/ + for (i=0 ; i < SK_MAX ; i++) + acpt_sk[i] = test_accept(lstn_sk, + (struct sockaddr *) &acpt_addr, &len); + + /*sctp_connectx () TEST8: from a listening socket, EISCONN Expect error*/ + error = sctp_connectx(lstn_sk, (struct sockaddr *) &lstn_addr, 1, NULL); + if (error != -1 || errno != EISCONN) + tst_brkm(TBROK, tst_exit, "sctp_connectx on a listening socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_connectx() on a listening socket - EISCONN"); + + /*sctp_connectx() TEST9: On established socket, EISCONN Expect error*/ + i=0; + error = sctp_connectx(acpt_sk[i], (struct sockaddr *) &lstn_addr, 1, NULL); + if (error != -1 || errno != EISCONN) + tst_brkm(TBROK, tst_exit, "sctp_connectx on an established socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_connectx() on an established socket - EISCONN"); + + for (i = 0 ; i < 4 ; i++) { + close(clnt_sk[i]); + close(acpt_sk[i]); + } + + /* sctp_connectx() TEST10: Re-establish an association that is closed. + * should succeed. + */ + error = sctp_connectx(sk1, (struct sockaddr *)&conn_addr, 1, NULL); + if (error < 0) + tst_brkm(TBROK, tst_exit, "Re-establish an association that " + "is closed error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sctp_connectx() to re-establish a closed association - " + "SUCCESS"); + + close(sk); + close(sk1); + close(lstn_sk); + + return 0; +} diff --git a/src/func_tests/test_1_to_1_events.c b/src/func_tests/test_1_to_1_events.c new file mode 100644 index 0000000..3525346 --- /dev/null +++ b/src/func_tests/test_1_to_1_events.c @@ -0,0 +1,190 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This test tests the events for 1-1 style sockets. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + */ +#include +#include +#include +#include +#include /* needed by linux/sctp.h */ +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 4; +int TST_CNT = 0; + +int +main(int argc, char *argv[]) +{ + int svr_sk, clt_sk,acpt_sk; + struct sockaddr_in svr_loop, clt_loop,acpt_loop; + struct iovec iov, out_iov; + struct msghdr inmessage, outmessage; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + int error; + socklen_t len; + char *big_buffer; + struct sctp_event_subscribe event; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + char *message = "hello, world!\n"; + uint32_t ppid; + uint32_t stream; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Initialize the server and client addresses. */ + svr_loop.sin_family = AF_INET; + svr_loop.sin_addr.s_addr = SCTP_IP_LOOPBACK; + svr_loop.sin_port = htons(SCTP_TESTPORT_1); + + clt_loop.sin_family = AF_INET; + clt_loop.sin_addr.s_addr = SCTP_IP_LOOPBACK; + clt_loop.sin_port = htons(SCTP_TESTPORT_1); + + /* Create and bind the server socket. */ + svr_sk = test_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + test_bind(svr_sk, (struct sockaddr *) &svr_loop, sizeof(svr_loop)); + + /* Mark server socket as being able to accept new associations. */ + test_listen(svr_sk, 3); + + /* Create the client socket. */ + clt_sk = test_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + + event.sctp_data_io_event = 1; + event.sctp_association_event = 1; + event.sctp_shutdown_event = 1; + len = sizeof(struct sctp_event_subscribe); + test_setsockopt(svr_sk, SCTP_EVENTS, &event, len); + test_setsockopt(clt_sk, SCTP_EVENTS, &event, len); + + len = sizeof(struct sockaddr_in); + test_connect(clt_sk, (struct sockaddr *) &clt_loop, len); + + acpt_sk = test_accept(svr_sk, (struct sockaddr *) &acpt_loop, &len); + + /* Build up a msghdr structure we can use for all sending. */ + memset(&outmessage, 0, sizeof(outmessage)); + outmessage.msg_name = &svr_loop; + outmessage.msg_namelen = sizeof(svr_loop); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid = rand(); /* Choose an arbitrary value. */ + stream = 1; + + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + + outmessage.msg_iov->iov_base = message; + outmessage.msg_iov->iov_len = (strlen(message) + 1); + + /* Send . This will create the association*/ + test_sendmsg(clt_sk, &outmessage, 0, strlen(message)+1); + + memset(&inmessage, 0, sizeof(inmessage)); + /* NOW initialize inmessage with enough space for DATA... */ + big_buffer = malloc(REALLY_BIG); + if (!big_buffer) { DUMP_CORE; } + + /* Let's do a test to do a recvmsg when we are not listening and + * when we have no associations. + */ + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + + error = test_recvmsg(clt_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, + error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, + SCTP_COMM_UP); + + tst_resm(TPASS, "COMM_UP notification on client socket - SUCCESS"); + + error = test_recvmsg(acpt_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, + error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, + SCTP_COMM_UP); + + tst_resm(TPASS, "COMM_UP notification on server socket - SUCCESS"); + + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(acpt_sk, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(message) + 1, + MSG_EOR, stream, ppid); + + tst_resm(TPASS, "Data message on server socket - SUCCESS"); + + close(clt_sk); + error = test_recvmsg(acpt_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, + error, + sizeof(struct sctp_shutdown_event), + SCTP_SHUTDOWN_EVENT, + 0); + + tst_resm(TPASS, "SHUTDOWN notification on accepted socket - SUCCESS"); + close(svr_sk); + close(acpt_sk); + + return 0; +} diff --git a/src/func_tests/test_1_to_1_initmsg_connect.c b/src/func_tests/test_1_to_1_initmsg_connect.c new file mode 100644 index 0000000..8efb4f5 --- /dev/null +++ b/src/func_tests/test_1_to_1_initmsg_connect.c @@ -0,0 +1,120 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * When init timeout is set to zero, a connect () crashed the system. This case + * tests the fix for the same. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 1; +int TST_CNT = 0; + +int +main (int argc, char **argv) +{ + int sk1, sk2, sk3, pf_class; + socklen_t len; + struct sockaddr_in lstn_addr, acpt_addr; + struct sockaddr_in conn_addr; + char * buffer_rcv; + struct sctp_initmsg sinmsg; + char *message = "Hello World!\n"; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + /* Opening the socket*/ + + pf_class = PF_INET; + + sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + sk3 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + test_bind(sk3, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + len = sizeof(struct sctp_initmsg); + sinmsg.sinit_num_ostreams = 65535; + sinmsg.sinit_max_instreams = 10; + sinmsg.sinit_max_attempts = 1; + sinmsg.sinit_max_init_timeo = 0; + test_setsockopt(sk1, SCTP_INITMSG, &sinmsg, len); + sinmsg.sinit_num_ostreams = 10; + sinmsg.sinit_max_instreams = 65535; + test_setsockopt(sk3, SCTP_INITMSG, &sinmsg, len); + + test_listen(sk3, 1); + + len = sizeof(struct sockaddr_in); + test_connect(sk1, (struct sockaddr *) &conn_addr, len); + + sk2 = test_accept(sk3, (struct sockaddr *) &acpt_addr, &len); + + test_sctp_sendmsg(sk1, message, strlen(message) + 1, + (struct sockaddr *)&conn_addr, len, + 0, 0, 65534, 0, 0); + + buffer_rcv = malloc(100); + test_recv(sk2, buffer_rcv, (strlen(message) + 1), MSG_NOSIGNAL); + + tst_resm(TPASS, "connect() with init timeout set to 0 - SUCCESS"); + + close (sk1); + close (sk2); + close (sk3); + + return 0; +} diff --git a/src/func_tests/test_1_to_1_nonblock.c b/src/func_tests/test_1_to_1_nonblock.c new file mode 100644 index 0000000..bad3a99 --- /dev/null +++ b/src/func_tests/test_1_to_1_nonblock.c @@ -0,0 +1,217 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test the Non-Blocking mode of connect(), + * accept() and recvmsg() calls. + * + * TEST1: Non blocking accept return EAGAIN if connect is not called + * TEST2: Non blocking connect should return EINPROGRESS + * TEST3: accept() passes when connect called in Non-blocking mode + * TEST4: Non blocking recvmsg should return EAGAIN + * TEST5: recvmsg() should succeed if data present to receive in non blocking + * mode + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 5; +int TST_CNT = 0; + +int +main(int argc, char *argv[]) +{ + int error,msg_count; + socklen_t len; + int sk,pf_class,lstn_sk,acpt_sk,flag,cflag,sflag; + struct msghdr outmessage; + struct msghdr inmessage; + char *message = "hello, world!\n"; + struct iovec iov; + struct iovec iov_rcv; + struct sctp_sndrcvinfo *sinfo; + int count; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct iovec out_iov; + char * buffer_snd; + char * buffer_rcv; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + + struct sockaddr_in conn_addr,lstn_addr,svr_addr; + + /* Rather than fflush() throughout the code, set stdout to + * be unbufferd + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + pf_class = PF_INET; + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + /*Binding the listen socket*/ + test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + /*Listening the socket*/ + test_listen(lstn_sk, 10); + + len = sizeof(struct sockaddr_in); + flag = MSG_NOSIGNAL; + + /*Setting server socket non-blocking*/ + sflag = fcntl(lstn_sk, F_GETFL, 0); + if (sflag < 0) + tst_brkm(TBROK, tst_exit, "fcnt F_GETFL failed " + "sflag:%d, errno:%d", sflag, errno); + + error = fcntl(lstn_sk, F_SETFL, sflag | O_NONBLOCK); + if (error < 0) + tst_brkm(TBROK, tst_exit, "fcnt F_SETFL failed " + "error:%d, errno:%d", error, errno); + + /* TEST1: accept should return EAGAIN instead blocking. */ + error = accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); + if (error != -1 || errno != EAGAIN) + tst_brkm(TBROK, tst_exit, "non-blocking accept " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "non-blocking accept() - EAGAIN"); + + /* TEST2: Non Block connect should return EINPROGRESS */ + /*Set client socket as non-blocking*/ + cflag = fcntl(sk, F_GETFL, 0); + if (cflag < 0) + tst_brkm(TBROK, tst_exit, "fcnt F_GETFL failed " + "cflag:%d, errno:%d", cflag, errno); + + error = fcntl(sk, F_SETFL, sflag | O_NONBLOCK); + if (error < 0) + tst_brkm(TBROK, tst_exit, "fcnt F_SETFL failed " + "error:%d, errno:%d", error, errno); + + error = connect(sk, (const struct sockaddr *) &conn_addr, len); + if (error != -1 || errno != EINPROGRESS) + tst_brkm(TBROK, tst_exit, "non-blocking connect " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "non-blocking connect() - EINPROGRESS"); + + /* TEST3: Now that connect() called, accept will succeed */ + acpt_sk = accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); + if (acpt_sk < 0) + tst_brkm(TBROK, tst_exit, "accept after a non-blocking connect " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "accept() after a non-blocking connect - SUCCESS"); + + memset(&outmessage, 0, sizeof(outmessage)); + buffer_snd = malloc(REALLY_BIG); + + outmessage.msg_name = &svr_addr; + outmessage.msg_namelen = sizeof(svr_addr); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + + iov.iov_base = buffer_snd; + iov.iov_len = REALLY_BIG; + outmessage.msg_iov->iov_base = message; + + outmessage.msg_iov->iov_len = strlen(message) + 1; + + memset(&inmessage, 0, sizeof(inmessage)); + buffer_rcv = malloc(REALLY_BIG); + + iov_rcv.iov_base = buffer_rcv; + iov_rcv.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov_rcv; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + + msg_count = strlen(message) + 1; + + /* TEST4: recvmsg() should return EAGAIN instead blocking */ + error = recvmsg(sk, &inmessage, MSG_WAITALL); + if ( error != -1 || errno != EAGAIN) + tst_brkm(TBROK, tst_exit, "non-blocking recvmsg " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "non-blocking recvmsg() - EAGAIN"); + + count = test_sendmsg(acpt_sk, &outmessage, flag, msg_count); + + /* TEST5: recvmsg() should succeed now as data is available. */ + error = test_recvmsg(sk, &inmessage, flag); + test_check_msg_data(&inmessage, error, msg_count, MSG_EOR, 0, 0); + + tst_resm(TPASS, "non-blocking recvmsg() when data is available - " + "SUCCESS"); + + close(lstn_sk); + close(acpt_sk); + return 0; +} diff --git a/src/func_tests/test_1_to_1_recvfrom.c b/src/func_tests/test_1_to_1_recvfrom.c new file mode 100644 index 0000000..a45c228 --- /dev/null +++ b/src/func_tests/test_1_to_1_recvfrom.c @@ -0,0 +1,194 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test the recvfrom () call for 1-1 style sockets + * + * TEST1: Bad socket descriptor + * TEST2: Invalid socket + * TEST3: Invalid message pointer + * TEST4: On a listening socket + * TEST5: Reading on a socket that received SHUTDOWN + * TEST6: Reading the pending message on socket that received SHUTDOWN + * TEST7: No more message and association is shutdown + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 7; +int TST_CNT = 0; + +int +main(int argc, char *argv[]) +{ + int ret, msg_count; + socklen_t len; + int sk,pf_class,lstn_sk,acpt_sk, flag; + char *message = "hello, world!\n"; + char *message_rcv; + int count; + + struct sockaddr_in conn_addr,lstn_addr,svr_addr; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + message_rcv = malloc(512); + + pf_class = PF_INET; + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + /*Binding the listen socket*/ + test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + /*Listening the socket*/ + test_listen(lstn_sk, 10); + + len = sizeof(struct sockaddr_in); + + test_connect(sk, (struct sockaddr *) &conn_addr, len); + + acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); + + msg_count = (strlen(message) + 1); + + flag = MSG_NOSIGNAL; + /*Sending the message*/ + count = test_send(sk, message, msg_count, flag); + + /*recvfrom () TEST1: Bad socket descriptor, EBADF Expected error*/ + count = recvfrom(-1, message_rcv, msg_count, flag, + (struct sockaddr *)&svr_addr, &len); + if (count != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "recvfrom with a bad socket " + "descriptor count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "recvfrom() with a bad socket descriptor - EBADF"); + + /*recvfrom () TEST2: Invalid socket , ENOTSOCK Expected error*/ + count = recvfrom(0, message_rcv, msg_count, flag, + (struct sockaddr *)&svr_addr, &len); + if (count != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "recvfrom with invalid socket " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "recvfrom() with invalid socket - ENOTSOCK"); + + /*recvfrom () TEST3: Invalid message pointer EFAULT, Expected error*/ + count = recvfrom(acpt_sk, (char *)-1, msg_count, flag, + (struct sockaddr *)&svr_addr, &len); + if (count != -1 || errno != EFAULT) + tst_brkm(TBROK, tst_exit, "recvfrom with invalid message " + "pointer count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "recvfrom() with invalid message ptr - EFAULT"); + + /*TEST4: recvfrom on listening socket,ENOTCONN Expected error*/ + count = recvfrom(lstn_sk, message_rcv, msg_count, flag, + (struct sockaddr *)&svr_addr, &len); + if (count != -1 || errno != ENOTCONN) + tst_brkm(TBROK, tst_exit, "recvfrom on listening socket " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "recvfrom() on listening socket - ENOTCONN"); + + count = test_send(acpt_sk, message, msg_count, flag); + + ret = test_shutdown(sk, SHUT_WR); + + /*recvfrom () TEST5:reading on a socket that received SHUTDOWN*/ + count = recvfrom(acpt_sk, message_rcv, msg_count, flag, + (struct sockaddr *)&svr_addr, &len); + if (count < 0) + tst_brkm(TBROK, tst_exit, "recvfrom on a socket that has " + "received shutdown count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "recvfrom() on a socket that has received shutdown - " + "EOF"); + + /*recvfrom () TEST6:reading the pending message on socket that sent + SHUTDOWN*/ + count = recvfrom(sk, message_rcv, msg_count, flag, + (struct sockaddr *)&svr_addr, &len); + if (count < 0) + tst_brkm(TBROK, tst_exit, "recvfrom on a socket with pending " + "message that has sent shutdown count:%d, errno:%d", + count, errno); + + tst_resm(TPASS, "recvfrom() on a socket with pending message that has " + "sent shutdown - SUCCESS"); + + /*recvfrom () TEST7: No more message and association is shutdown, + ENOTCONN Expected error*/ + count = recvfrom(sk, message_rcv, msg_count, flag, + (struct sockaddr *)&svr_addr, &len); + if (count != -1 || errno != ENOTCONN) + tst_brkm(TBROK, tst_exit, "recvfrom on a socket with no " + "pending messages and has sent shutdown count:%d, " + "errno:%d", count, errno); + + tst_resm(TPASS, "recvfrom() on a socket with no pending messages and " + " has sent shutdown - ENOTCONN"); + + close(sk); + close(lstn_sk); + close(acpt_sk); + return 0; + +} diff --git a/src/func_tests/test_1_to_1_recvmsg.c b/src/func_tests/test_1_to_1_recvmsg.c new file mode 100644 index 0000000..f017728 --- /dev/null +++ b/src/func_tests/test_1_to_1_recvmsg.c @@ -0,0 +1,206 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test the recvmsg() call for 1-1 style sockets + * + * TEST1: Bad socket descriptor + * TEST2: Invalid socket + * TEST3: Invalid iovec pointer + * TEST4: Invalid msghdr pointer + * TEST5: On a listening socket + * TEST6: Reading on a socket that received SHUTDOWN + * TEST7: Reading the pending message socket that received SHUTDOWN + * TEST8: No more message and association is shutdown + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 8; +int TST_CNT = 0; + +int +main(int argc, char *argv[]) +{ + socklen_t len; + int ret; + int sk,pf_class,lstn_sk,acpt_sk; + int flag = 0; + struct msghdr inmessage; + char *message = "hello, world!\n"; + struct iovec iov_rcv; + int count; + char * buffer_rcv; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + char *message1 = "hello, world!\n"; + + struct sockaddr_in conn_addr,lstn_addr,svr_addr; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + pf_class = PF_INET; + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + /*Binding the listen socket*/ + test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + /*Listening the socket*/ + test_listen(lstn_sk, 10); + + len = sizeof(struct sockaddr_in); + + test_connect(sk, (struct sockaddr *) &conn_addr, len); + + acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); + + memset(&inmessage, 0, sizeof(inmessage)); + buffer_rcv = malloc(REALLY_BIG); + + iov_rcv.iov_base = buffer_rcv; + iov_rcv.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov_rcv; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + + /*recvmsg () TEST1: Bad socket descriptor, EBADF Expected error*/ + count = recvmsg(-1, &inmessage, flag); + if (count != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "recvmsg with a bad socket " + "descriptor count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "recvmsg() with a bad socket descriptor - EBADF"); + + /*recvmsg () TEST2: Invalid socket , ENOTSOCK Expected error*/ + count = recvmsg(0, &inmessage, flag); + if (count != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "recvmsg with invalid socket " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "recvmsg() with invalid socket - ENOTSOCK"); + + /*recvmsg () TEST3: Invalid iovec pointer EFAULT, Expected error*/ + inmessage.msg_iov = (struct iovec *)-1; + count = recvmsg(acpt_sk, &inmessage, flag); + if (count != -1 || errno != EFAULT) + tst_brkm(TBROK, tst_exit, "recvmsg with invalid iovec " + "pointer count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "recvmsg() with invalid iovec ptr - EFAULT"); + + inmessage.msg_iov = &iov_rcv; + + /*recvmsg () TEST4: Invalid msghdr pointer EFAULT, Expected error*/ + count = recvmsg(acpt_sk, (struct msghdr *)-1, flag); + if (count != -1 || errno != EFAULT) + tst_brkm(TBROK, tst_exit, "recvmsg with invalid msghdr " + "pointer count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "recvmsg() with invalid msghdr ptr - EFAULT"); + + /*recvmsg () TEST5:recvmsg on listening socket,ENOTCONN Expected error*/ + count = recvmsg(lstn_sk, &inmessage, flag); + if (count != -1 || errno != ENOTCONN) + tst_brkm(TBROK, tst_exit, "recvmsg on listening socket " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "recvmsg() on listening socket - ENOTCONN"); + + count = test_send(acpt_sk, message1, strlen(message), 0); + + ret = test_shutdown(sk, SHUT_WR); + + flag = MSG_NOSIGNAL; + /*recvmsg () TEST6:reading on a socket that received SHUTDOWN*/ + count = recvmsg(acpt_sk, &inmessage, flag); + if (count < 0) + tst_brkm(TBROK, tst_exit, "recvmsg on a socket that has " + "received shutdown count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "recvmsg() on a socket that has received shutdown - " + "EOF"); + + /*recvmsg () TEST7:reading the pending message socket that sent + SHUTDOWN*/ + count = recvmsg(sk, &inmessage, flag); + if (count < 0) + tst_brkm(TBROK, tst_exit, "recvmsg on a socket with pending " + "message that has sent shutdown count:%d, errno:%d", + count, errno); + + tst_resm(TPASS, "recvmsg() on a socket with pending message that has " + "sent shutdown - SUCCESS"); + + /*recvmsg () TEST8: No more message and association is shutdown, + ENOTCONN Expected error*/ + count = recvmsg(sk, &inmessage, flag); + if (count != -1 || errno != ENOTCONN) + tst_brkm(TBROK, tst_exit, "recvmsg on a socket with no " + "pending messages and has sent shutdown count:%d, " + "errno:%d", count, errno); + + tst_resm(TPASS, "recvmsg() on a socket with no pending messages and " + " has sent shutdown - ENOTCONN"); + + close(sk); + close(lstn_sk); + close(acpt_sk); + return 0; +} diff --git a/src/func_tests/test_1_to_1_rtoinfo.c b/src/func_tests/test_1_to_1_rtoinfo.c new file mode 100644 index 0000000..cb46e39 --- /dev/null +++ b/src/func_tests/test_1_to_1_rtoinfo.c @@ -0,0 +1,114 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test the getsockopt () and sectsockopt () with + * SCTP_RTOINFO option on 1-1 style socket + * + * This program first gets the default values using getsockopt(). It also sets + * the value using setsockopt() and gets the set value using getsockopt(). + * A comparison between set values and get values are performed. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include /* for sockaddr_in6 */ +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 3; +int TST_CNT = 0; + +int +main(void) +{ + + int sd, ret; + socklen_t len; + struct sctp_rtoinfo srtoinfo; /*setting the variables*/ + struct sctp_rtoinfo grtoinfo; /*Getting the variables*/ + + sd = test_socket (PF_INET, SOCK_STREAM, IPPROTO_SCTP); + + len = sizeof(struct sctp_rtoinfo); + + /*TEST1 Getting the default values using getsockopt()*/ + ret = getsockopt(sd, IPPROTO_SCTP, SCTP_RTOINFO, &grtoinfo, &len); + if (ret < 0) + tst_brkm(TBROK, tst_exit, "getsockopt SCTP_RTOINFO " + "ret:%d, errno:%d", ret, errno); + + tst_resm(TPASS, "getsockopt() SCTP_RTOINFO - SUCCESS"); + + /*Assigning the values to RTO initial and max and min bounds*/ + srtoinfo.srto_initial=60; + srtoinfo.srto_max=100; + srtoinfo.srto_min=40; + + /*TEST2 Setting the values using setsockopt()*/ + ret = setsockopt(sd, IPPROTO_SCTP, SCTP_RTOINFO, &srtoinfo, + sizeof(struct sctp_rtoinfo)); + if (ret < 0) + tst_brkm(TBROK, tst_exit, "setsockopt SCTP_RTOINFO " + "ret:%d, errno:%d", ret, errno); + + tst_resm(TPASS, "setsockopt() SCTP_RTOINFO - SUCCESS"); + + /*Getting the values which are set using setsockopt()*/ + ret = getsockopt(sd, IPPROTO_SCTP, SCTP_RTOINFO, &grtoinfo, &len); + if (ret < 0) + tst_brkm(TBROK, tst_exit, "getsockopt SCTP_RTOINFO " + "ret:%d, errno:%d", ret, errno); + + /* TEST3 Compare the get values with the set values. */ + if (srtoinfo.srto_initial != grtoinfo.srto_initial && + srtoinfo.srto_max != grtoinfo.srto_max && + srtoinfo.srto_min != grtoinfo.srto_min) + tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SCTP_RTOINFO " + "compare failed"); + + tst_resm(TPASS, "setsockopt()/getsockopt SCTP_RTOINFO compare - " + "SUCCESS"); + + close(sd); + + return 0; +} diff --git a/src/func_tests/test_1_to_1_send.c b/src/func_tests/test_1_to_1_send.c new file mode 100644 index 0000000..4966020 --- /dev/null +++ b/src/func_tests/test_1_to_1_send.c @@ -0,0 +1,230 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test the send() call for 1-1 style sockets + * + * TEST1: Bad socket descriptor + * TEST2: Invalid socket + * TEST3: On a listening socket + * TEST4: On a closed association + * TEST5: Invalid message address + * TEST6: send from client to server + * TEST7: send from server to client + * TEST8: sending partial data from a buffer + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 8; +int TST_CNT = 0; + +int +main(int argc, char *argv[]) +{ + socklen_t len,len_snd; + int msg_count; + int sk,sk1,pf_class,lstn_sk,acpt_sk,acpt1_sk, flag, count; + char *message = "hello, world!\n"; + char *message_rcv; + + struct sockaddr_in conn_addr,lstn_addr,svr_addr; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + pf_class = PF_INET; + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + /*Binding the listen socket*/ + test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + /*Listening the socket*/ + test_listen(lstn_sk, 10); + + len = sizeof(struct sockaddr_in); + + test_connect(sk, (struct sockaddr *) &conn_addr, len); + + acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); + + len_snd = (strlen(message) + 1); + + flag = MSG_NOSIGNAL; + /*send () TEST1: Bad socket descriptor, EBADF Expected error*/ + count = send(-1, message, len_snd, flag); + if (count != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "send with a bad socket " + "descriptor count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "send() with a bad socket descriptor - EBADF"); + + /*send () TEST2: Invalid socket, ENOTSOCK Expected error*/ + count = send(0, message, len_snd, flag); + if (count != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "send with invalid socket " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "send() with invalid socket - ENOTSOCK"); + + /*send () TEST3: send on listening socket, EPIPE Expected error*/ + count = send(lstn_sk, message, len_snd, flag); + if (count != -1 || errno != EPIPE) + tst_brkm(TBROK, tst_exit, "send on a listening socket " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "send() on a listening socket - EPIPE"); +#if 0 + /*send () TEST4: Invalid message address, EFAULT Expected error*/ + /* FIXME this test should pass. Don't catch why... */ + count = send(sk, (char *)0x1, len_snd, flag); + if (count != -1 || errno != EFAULT) + tst_brkm(TBROK, tst_exit, "send with invalid message " + "pointer count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "send() with invalid message ptr - EFAULT"); +#endif + + test_connect(sk1, (struct sockaddr *) &lstn_addr, len); + + count = test_send(sk1, message, len_snd, flag); + + close(sk1); + + acpt1_sk = test_accept(lstn_sk, (struct sockaddr *)&conn_addr, &len); + + /*send () TEST5: send on closed association, EPIPE Expected error*/ + count = send(acpt1_sk, message, len_snd, flag); + if (count != -1 || errno != EPIPE) + tst_brkm(TBROK, tst_exit, "send on a closed association " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "send() on a closed association - EPIPE"); + + close(acpt1_sk); + close(sk); + close(lstn_sk); + close(acpt_sk); + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + message_rcv = malloc(512); + + /*Binding the listen socket*/ + test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + /*Listening the socket*/ + test_listen(lstn_sk, 10); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + len = sizeof(struct sockaddr_in); + + test_connect(sk, (struct sockaddr *) &conn_addr, len); + + acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); + + msg_count = strlen(message) + 1; + + /*send() TEST6: Sending data from client socket to server socket*/ + count = send(sk, message, msg_count, flag); + if (count != msg_count) + tst_brkm(TBROK, tst_exit, "send from client to server " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "send() from client to server - SUCCESS"); + + test_recv(acpt_sk, message_rcv, msg_count, flag); + + strncpy(message_rcv,"\0",512); + + /*send() TEST7: Sending data from accept socket to client socket*/ + count = send(acpt_sk, message, msg_count, flag); + if (count != msg_count) + tst_brkm(TBROK, tst_exit, "send from accept socket to client " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "send() from accept socket to client - SUCCESS"); + + test_recv(sk, message_rcv, msg_count, flag); + + /*send() TEST8: Sending less number of data from the buffer*/ + /*Sending only 5 bytes so that only hello is received*/ + test_send(sk, message, 5 , flag); + test_recv(acpt_sk, message_rcv, 5, flag); + + tst_resm(TPASS, "send() partial data from a buffer - SUCCESS"); + + /* TEST9: sctp_send with no sinfo */ + test_sctp_send(sk, message, strlen(message) + 1 , NULL, flag); + test_recv(acpt_sk, message_rcv, strlen(message) + 1, flag); + tst_resm(TPASS, "sctp_send() with no sinfo - SUCCESS"); + + close(sk1); + close(lstn_sk); + close(acpt_sk); + + return 0; +} diff --git a/src/func_tests/test_1_to_1_sendmsg.c b/src/func_tests/test_1_to_1_sendmsg.c new file mode 100644 index 0000000..7840ef3 --- /dev/null +++ b/src/func_tests/test_1_to_1_sendmsg.c @@ -0,0 +1,379 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test the sendmsg() call for 1-1 style sockets + * + * TEST1: Bad socket descriptor + * TEST2: Invalid socket + * TEST3: On a listening socket + * TEST4: Invalid iovec pointer + * TEST5: Invalid iovec length + * TEST6: Invalid msghdr pointer + * TEST7: Invalid sinfo flags + * TEST8: SCTP_EOF flag set + * TEST9: SCTP_ABORT flag set + * TEST10: On a closed association + * + * TEST11: Sending data from server socket to client socket + * TEST12: Sending data from client socket to server socket + * TEST13: Sending data from unconnected client to server + * TEST14: Sending a message on SHUT_RD socket + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 14; +int TST_CNT = 0; + +int +main(int argc, char *argv[]) +{ + socklen_t len; + int msg_count; + int sk,sk1,pf_class,lstn_sk,acpt_sk,acpt1_sk, flag; + struct msghdr outmessage; + char *message = "hello, world!\n"; + struct iovec iov; + struct sctp_sndrcvinfo *sinfo; + int count; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct iovec out_iov; + char * buffer; + struct msghdr inmessage; + char * buffer_snd; + char * buffer_rcv; + struct sockaddr_in conn_addr,lstn_addr,svr_addr; + struct iovec iov_rcv; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + pf_class = PF_INET; + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + /*Binding the listen socket*/ + test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + /*Listening the socket*/ + test_listen(lstn_sk, 10); + + len = sizeof(struct sockaddr_in); + + test_connect(sk, (struct sockaddr *) &conn_addr, len); + + acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); + + memset(&outmessage, 0, sizeof(outmessage)); + buffer = malloc(REALLY_BIG); + + outmessage.msg_name = &conn_addr; + outmessage.msg_namelen = sizeof(conn_addr); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + + iov.iov_base = buffer; + iov.iov_len = REALLY_BIG; + outmessage.msg_iov->iov_base = message; + + outmessage.msg_iov->iov_len = strlen(message) + 1; + + flag = MSG_NOSIGNAL; + /*sendmsg () TEST1: Bad socket descriptor, EBADF Expected error*/ + count = sendmsg(-1, &outmessage, flag); + if (count != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "sendmsg with a bad socket " + "descriptor count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() with a bad socket descriptor - EBADF"); + + /*sendmsg () TEST2: Invalid socket, ENOTSOCK Expected error*/ + count = sendmsg(0, &outmessage, flag); + if (count != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "sendmsg with invalid socket " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() with invalid socket - ENOTSOCK"); + + /*sendmsg () TEST3: sendmsg on listening socket, EPIPE Expected error*/ + count = sendmsg(lstn_sk, &outmessage, flag); + if (count != -1 || errno != EPIPE) + tst_brkm(TBROK, tst_exit, "sendmsg on a listening socket " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() on a listening socket - EPIPE"); + + /*sendmsg () TEST4: Invalid iovec pointer EFAULT, Expected error*/ + outmessage.msg_iov = (struct iovec *)-1; + count = sendmsg(sk, &outmessage, flag); + if (count != -1 || errno != EFAULT) + tst_brkm(TBROK, tst_exit, "sendmsg with invalid iovec " + "pointer count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() with invalid iovec ptr - EFAULT"); + + outmessage.msg_iov = &out_iov; + + /*sendmsg () TEST5: Invalid iovec count EINVAL, Expected error*/ + outmessage.msg_iovlen = 0; + count = sendmsg(sk, &outmessage, flag); + if (count != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "sendmsg with invalid iovec " + "length count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() with invalid iovec length - EINVAL"); + + outmessage.msg_iovlen = 1; + + /*sendmsg () TEST6: Invalid msghdr pointer EFAULT, Expected error*/ + count = sendmsg(sk, (struct msghdr *)-1, flag); + if (count != -1 || errno != EFAULT) + tst_brkm(TBROK, tst_exit, "sendmsg with invalid msghdr " + "pointer count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() with invalid msghdr ptr - EFAULT"); + + /*sendmsg () TEST7: Invalid sinfo flag EINVAL, Expected error*/ + sinfo->sinfo_flags = 999; + count = sendmsg(sk, &outmessage, -1); + if (count != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "sendmsg with invalid sinfo " + "flags count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() with invalid sinfo flags - EINVAL"); + + /*sendmsg () TEST8: SCTP_EOF flag EINVAL, Expected error*/ + sinfo->sinfo_flags = SCTP_EOF; + count = sendmsg(sk, &outmessage, flag); + if (count != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_EOF flag " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() with SCTP_EOF flag - EINVAL"); + + /*sendmsg () TEST9: SCTP_ABORT flag EINVAL, Expected error*/ + sinfo->sinfo_flags = SCTP_ABORT; + count = sendmsg(sk, &outmessage, flag); + if (count != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_ABORT flag " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() with SCTP_ABORT flag - EINVAL"); + + sinfo->sinfo_flags = 0; + + test_connect(sk1, (struct sockaddr *) &lstn_addr, len); + + test_sendmsg(sk1, &outmessage, flag, strlen(message)+1); + + close(sk1); + acpt1_sk = test_accept(lstn_sk, (struct sockaddr *)&conn_addr, &len); + + /*sendmsg () TEST10:sendmsg on closed association, EPIPE Expected error*/ + count = sendmsg(acpt1_sk, &outmessage, flag); + if (count != -1 || errno != EPIPE) + tst_brkm(TBROK, tst_exit, "sendmsg on a closed association " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() on a closed association - EPIPE"); + + close(acpt1_sk); + close(sk); + close(lstn_sk); + close(acpt_sk); + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + /*Binding the listen socket*/ + test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + /*Listening the socket*/ + test_listen(lstn_sk, 10); + + len = sizeof(struct sockaddr_in); + flag = MSG_NOSIGNAL; + + test_connect(sk, (struct sockaddr *) &conn_addr, len); + + acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); + + memset(&outmessage, 0, sizeof(outmessage)); + buffer_snd = malloc(REALLY_BIG); + + outmessage.msg_name = &svr_addr; + outmessage.msg_namelen = sizeof(svr_addr); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + + iov.iov_base = buffer_snd; + iov.iov_len = REALLY_BIG; + outmessage.msg_iov->iov_base = message; + + outmessage.msg_iov->iov_len = strlen(message) + 1; + + memset(&inmessage, 0, sizeof(inmessage)); + buffer_rcv = malloc(REALLY_BIG); + + iov_rcv.iov_base = buffer_rcv; + iov_rcv.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov_rcv; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + + msg_count = strlen(message) + 1; + + /*sendmsg() TEST11: Sending data from server socket to client socket*/ + count = sendmsg(acpt_sk, &outmessage, flag); + if (count != msg_count) + tst_brkm(TBROK, tst_exit, "sendmsg from accept socket to " + "client count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() from accept socket to client - SUCCESS"); + + count = test_recvmsg(sk, &inmessage, flag); + test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0); + + outmessage.msg_name = &conn_addr; + outmessage.msg_namelen = sizeof(conn_addr); + /*sendmsg() TEST12: Sending data from client socket to server socket*/ + count = sendmsg(sk, &outmessage, flag); + if (count != msg_count) + tst_brkm(TBROK, tst_exit, "sendmsg from client to server " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() from client to server - SUCCESS"); + + count = test_recvmsg(acpt_sk, &inmessage, flag); + test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0); + + outmessage.msg_name = &conn_addr; + outmessage.msg_namelen = sizeof(conn_addr); + close(sk); + close(acpt_sk); + sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /*sendmsg() TEST13: Sending data from unconnected client socket to + server socket*/ + count = sendmsg(sk1, &outmessage, flag); + if (count != msg_count) + tst_brkm(TBROK, tst_exit, "sendmsg from unconnected client to " + "server count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() from unconnected clt to server - SUCCESS"); + + acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); + + count = test_recvmsg(acpt_sk, &inmessage, flag); + test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0); + + test_shutdown(sk1, SHUT_RD); + + /*sendmsg() TEST14: Sending a message on SHUT_RD socket*/ + count = sendmsg(sk1, &outmessage, flag); + if (count != msg_count) + tst_brkm(TBROK, tst_exit, "sendmsg on a SHUT_RD socket " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendmsg() on a SHUT_RD socket - SUCCESS"); + + count = test_recvmsg(acpt_sk, &inmessage, flag); + test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0); + + close(sk1); + close(lstn_sk); + close(acpt_sk); + return 0; +} diff --git a/src/func_tests/test_1_to_1_sendto.c b/src/func_tests/test_1_to_1_sendto.c new file mode 100644 index 0000000..8f5804c --- /dev/null +++ b/src/func_tests/test_1_to_1_sendto.c @@ -0,0 +1,164 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test the sendto () call + * for 1-1 style sockets + * + * TEST1: Sending data from client socket to server socket + * TEST2: Sending data from accept (server) socket to client socket + * TEST3: Sending data from unconnected client socket to server + * TEST4: sending partial data from a buffer + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release + */ + +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 4; +int TST_CNT = 0; + +int +main(int argc, char *argv[]) +{ + int msg_count; + socklen_t len; + int sk,sk1,pf_class,lstn_sk,acpt_sk,flag; + char *message = "hello, world!\n"; + char *message_rcv; + int count; + + struct sockaddr_in conn_addr,lstn_addr,svr_addr; + + /* Rather than fflush() throughout the code, set stdout to + * be unbufferd + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + pf_class = PF_INET; + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + message_rcv = malloc(512); + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + /*Binding the listen socket*/ + test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + /*Listening the socket*/ + test_listen(lstn_sk, 10); + + len = sizeof(struct sockaddr_in); + flag = MSG_NOSIGNAL; + + test_connect(sk, (struct sockaddr *) &conn_addr, len); + + acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); + + msg_count = strlen(message) + 1; + + /*sendto() TEST1: Sending data from client socket to server socket*/ + count = sendto(sk, message, msg_count, flag, + (const struct sockaddr *) &conn_addr, len); + if (count != msg_count) + tst_brkm(TBROK, tst_exit, "sendto from client to server " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendto() from client to server - SUCCESS"); + + test_recv(acpt_sk, message_rcv, msg_count, flag); + + strncpy(message_rcv,"\0",512); + + /*sendto() TEST2: Sending data from accept socket to client socket*/ + count = sendto(acpt_sk, message, msg_count, flag, + (const struct sockaddr *) &svr_addr, len); + if (count != msg_count) + tst_brkm(TBROK, tst_exit, "sendto from accept socket to client " + "count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendto() from accept socket to client - SUCCESS"); + + test_recv(sk, message_rcv, msg_count, flag); + + close(sk); + close(acpt_sk); + + sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /*sendto() TEST3: Sending data from unconnected client socket to + server socket*/ + count = sendto(sk1, message, msg_count, flag, + (const struct sockaddr *) &conn_addr, len); + if (count != msg_count) + tst_brkm(TBROK, tst_exit, "sendto from unconnected client to " + "server count:%d, errno:%d", count, errno); + + tst_resm(TPASS, "sendto() from unconnected client to server - SUCCESS"); + + acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); + + test_recv(acpt_sk, message_rcv, msg_count, flag); + + /*send() TEST4: Sending less number of data from the buffer*/ + /*Sending only 5 bytes so that only hello is received*/ + test_sendto(sk, message, 5 , flag, (const struct sockaddr *)&conn_addr, + len); + test_recv(acpt_sk, message_rcv, 5, flag); + + tst_resm(TPASS, "sendto() partial data from a buffer - SUCCESS"); + + close(sk1); + close(lstn_sk); + close(acpt_sk); + return 0; + +} diff --git a/src/func_tests/test_1_to_1_shutdown.c b/src/func_tests/test_1_to_1_shutdown.c new file mode 100644 index 0000000..de505f7 --- /dev/null +++ b/src/func_tests/test_1_to_1_shutdown.c @@ -0,0 +1,217 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test the shutdown() call for 1-1 style sockets + * + * TEST1: Bad socket descriptor + * TEST2: Invalid socket + * TEST3: shutdown with SHUT_WR flag to disable new send + * TEST4: shutdown with SHUT_RD flag to disable new receive + * TEST5: shutdown with SHUT_RDWR flag to disable new receive/send + * TEST6: Unconnected socket + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 6; +int TST_CNT = 0; + +#define MAX_CLIENTS 10 + +int +main(int argc, char *argv[]) +{ + int clnt_sk[MAX_CLIENTS], acpt_sk[MAX_CLIENTS],sk; + int lstn_sk; + struct sockaddr_in lstn_addr, acpt_addr; + socklen_t addrlen; + int error, i; + char *message = "hello, world!\n"; + char msgbuf[100]; + int pf_class; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + /* Initialize the server and client addresses. */ + pf_class = PF_INET; + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + + test_listen(lstn_sk, MAX_CLIENTS); + + for (i = 0; i < MAX_CLIENTS; i++) { + clnt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + test_connect(clnt_sk[i], (struct sockaddr *)&lstn_addr, + sizeof(lstn_addr)); + } + + for (i = 0; i < MAX_CLIENTS; i++) { + addrlen = sizeof(acpt_addr); + acpt_sk[i] = test_accept(lstn_sk, (struct sockaddr *)&acpt_addr, + &addrlen); + } + + /*shutdown() TEST1: Bad socket descriptor, EBADF Expected error*/ + error = shutdown(-1, SHUT_WR); + if (error != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "shutdown with a bad socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "shutdown() with a bad socket descriptor - EBADF"); + + /*shutdown() TEST2: Invalid socket, ENOTSOCK Expected error*/ + error = shutdown(0, SHUT_WR); + if (error != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "shutdown with an invalid socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "shutdown() with an invalid socket - ENOTSOCK"); + + errno = 0; + /*Do a send first before doing shutdown*/ + test_send(acpt_sk[0], message, strlen(message), 0); + + /*shutdown() TEST3: shutdown with SHUT_WR flag to disable new send*/ + error = shutdown(clnt_sk[0], SHUT_WR); + if (error < 0) + tst_brkm(TBROK, tst_exit, "shutdown with SHUT_WR flag " + "error:%d, errno:%d", error, errno); + + /* Reading on a socket that has received SHUTDOWN should return 0 + * indicating EOF. + */ + error = recv(acpt_sk[0], msgbuf, 100, 0); + if ((error != 0) || (errno != 0)) + tst_brkm(TBROK, tst_exit, "recv on a SHUTDOWN received socket " + "error:%d, errno:%d", error, errno); + + /* Read the pending message on clnt_sk[0] that was received before + * SHUTDOWN call. + */ + test_recv(clnt_sk[0], msgbuf, 100, 0); + + /* No more messages and the association is SHUTDOWN, should fail. */ + error = recv(clnt_sk[0], msgbuf, 100, 0); + if ((error != -1) || (errno != ENOTCONN)) + tst_brkm(TBROK, tst_exit, "recv on a SHUT_WR socket with no " + "messages error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "shutdown() with SHUT_WR flag - SUCCESS"); + + errno = 0; + + /*shutdown() TEST4: shutdown with SHUT_RD flag to disable new receive*/ + test_shutdown(clnt_sk[1], SHUT_RD); + + error = recv(clnt_sk[1], msgbuf, 100, 0); + if ((error != 0) || (errno != 0)) + tst_brkm(TBROK, tst_exit, "recv on a SHUT_RD socket " + "error:%d, errno:%d", error, errno); + + /* Sending a message on SHUT_RD socket. */ + error = test_send(clnt_sk[1], message, strlen(message), 0); + if (error < 0) + tst_brkm(TBROK, tst_exit, "send on a SHUT_RD socket " + "error:%d, errno:%d", error, errno); + + /* Receive the message sent on SHUT_RD socket. */ + test_recv(acpt_sk[1], msgbuf, 100, 0); + + /* Send a message to the SHUT_RD socket. */ + test_send(acpt_sk[1], message, strlen(message), 0); + + /* We should not receive the message as the socket is SHUT_RD */ + error = recv(clnt_sk[1], msgbuf, 100, 0); + if ((error != 0) || (errno != 0)) + tst_brkm(TBROK, tst_exit, "recv on a SHUT_RD socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "shutdown() with SHUT_RD flag - SUCCESS"); + + /*shutdown() TEST5: shutdown with SHUT_RDWR flag to disable new + receive/send*/ + test_shutdown(clnt_sk[2], SHUT_RDWR); + + error = recv(acpt_sk[2], msgbuf, 100, 0); + if ((error != 0) || (errno != 0)) + tst_brkm(TBROK, tst_exit, "recv on a SHUTDOWN received socket " + "error:%d, errno:%d", error, errno); + + error = recv(clnt_sk[2], msgbuf, 100, 0); + if ((error != 0) || (errno != 0)) + tst_brkm(TBROK, tst_exit, "recv on a SHUT_RDWR socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "shutdown() with SHUT_RDWR flag - SUCCESS"); + + /*shutdown() TEST6: Unconnected socket, ENOTCONN Expected error*/ + error = shutdown(sk, SHUT_RD); + if ((error != -1) || (errno != ENOTCONN)) + tst_brkm(TBROK, tst_exit, "shutdown on an unconnected socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "shutdown() on an unconnected socket - SUCCESS"); + + for (i = 0; i < MAX_CLIENTS; i++) + close(clnt_sk[i]); + for (i = 0; i < MAX_CLIENTS; i++) + close(acpt_sk[i]); + + + close(lstn_sk); + close(sk); + + return 0; +} diff --git a/src/func_tests/test_1_to_1_socket_bind_listen.c b/src/func_tests/test_1_to_1_socket_bind_listen.c new file mode 100644 index 0000000..6ba9c98 --- /dev/null +++ b/src/func_tests/test_1_to_1_socket_bind_listen.c @@ -0,0 +1,268 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test the socket (), bind () and listen () for + * 1-1 style sockets + * + * socket () Tests: + * --------------- + * TEST1: Invalid domain + * TEST2: Invalid type + * TEST3: Opening a TCP style socket + * + * bind () Tests: + * ------------- + * TEST4: Invalid address + * TEST5: Invalid address length + * TEST6: Invalid socket descriptor + * TEST7: Invalid host name + * TEST8: On a socket that is already bound + * TEST9: On reserved ports + * TEST10: INADDR_ANY address and non-zero port + * TEST11: INADDR_ANY address and zero port + * TEST12: Local address and zero port + * + * listen () Tests: + * --------------- + * TEST13: Bad socket descriptor + * TEST14: Invalid socket + * TEST15: Listening a bound socket + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include +#include + +#define SCTP_RESERVED_PORT 7 +#define SCTP_INV_LOOPBACK "172.31.43.112" + +char *TCID = __FILE__; +int TST_TOTAL = 15; +int TST_CNT = 0; + +int +main(int argc, char *argv[]) +{ + int sk,pf_class; + int error = 0; + int uid; + + struct sockaddr_in bind_addr; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + pf_class = PF_INET; + + /* socket() TEST1: Invalid domain, EAFNOSUPPORT Expected error */ + sk = socket(-1, SOCK_STREAM, IPPROTO_SCTP); + if (sk != -1 || errno != EAFNOSUPPORT) + tst_brkm(TBROK, tst_exit, "socket() with invalid domain " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "socket() with invalid domain - EAFNOSUPPORT"); + + /*socket() TEST2 : Invalid type, EINVAL Expected error*/ + sk = socket(pf_class, -1, IPPROTO_SCTP); + if (sk != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "socket() with invalid type " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "socket() with invalid type - EINVAL"); + + /*socket() TEST3: opening a socket*/ + sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + if (sk < 0) + tst_brkm(TBROK, tst_exit, "valid socket() call " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "socket() - SUCCESS"); + + /*bind() TEST4: Invalid structure, EFAULT Expected error */ + error = bind(sk, (struct sockaddr *)-1, sizeof(struct sockaddr_in)); + if (error != -1 || errno != EFAULT) + tst_brkm(TBROK, tst_exit, "bind() with invalid address ptr " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "bind() with invalid address ptr - EFAULT"); + + /*bind() TEST5: Invalid address length, EINVAL Expect error*/ + bind_addr.sin_family = AF_INET; + bind_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + bind_addr.sin_port = htons(SCTP_TESTPORT_1); + + error = bind(sk, (struct sockaddr *) &bind_addr, sizeof(bind_addr)-2); + if (error != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "bind() with invalid address length " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "bind() with invalid address length - EINVAL"); + + /*bind() TEST6: Invalid socket descriptor, ENOTSOCK Expect Error*/ + error = bind(0, (struct sockaddr *) &bind_addr, sizeof(bind_addr)); + if (error != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "bind() with invalid socket " + "descriptor error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "bind() with invalid socket descriptor - ENOTSOCK"); + + /*bind() TEST7: Invalid host name, EADDRNOTAVAIL Expect Error*/ + /*Assigning invalid host name*/ + bind_addr.sin_addr.s_addr = inet_addr(SCTP_INV_LOOPBACK); + error = bind(sk, (struct sockaddr *) &bind_addr, sizeof(bind_addr)); + if (error != -1 || errno != EADDRNOTAVAIL) + tst_brkm(TBROK, tst_exit, "bind() with invalid local " + "address error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "bind() with invalid local address - EADDRNOTAVAIL"); + + /*bind() TEST8: Bind on a socket that has already called bind + EINAVL, Expected error*/ + bind_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + /*Calling bind first time, it should pass*/ + test_bind(sk, (struct sockaddr *) &bind_addr, sizeof(bind_addr)); + + error = bind(sk, (struct sockaddr *) &bind_addr, sizeof(bind_addr)); + if (error != -1 || errno != EINVAL) + tst_brkm(TBROK, tst_exit, "bind() on an already bound socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "bind() on an already bound socket - EINVAL"); + + /*Closing the socket which succeed in bind() */ + close(sk); + + /*Opening the socket again for further test*/ + sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /*bind() TEST9: Bind on reserved ports EACCES, Expected error*/ + /*Assigning a reserved port*/ + uid = getuid(); + if (uid != 0) { + bind_addr.sin_port = htons(SCTP_RESERVED_PORT); + error = bind(sk, (struct sockaddr *) &bind_addr, + sizeof(bind_addr)); + if (error != -1 || errno != EACCES) + tst_brkm(TBROK, tst_exit, "bind() on reserverd port " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "bind() on reserved port - EACCESS"); + } + + /*bind() TEST10: INADDR_ANY address and non-zero port, bind() should + succeed*/ + bind_addr.sin_addr.s_addr = INADDR_ANY; + bind_addr.sin_port = htons(SCTP_TESTPORT_1); + error = bind(sk, (struct sockaddr *) &bind_addr,sizeof(bind_addr)); + if ( error < 0 ) + tst_brkm(TBROK, tst_exit, "bind() with INADDR_ANY address and " + "non-zero port error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "bind() with INADDR_ANY address and non-zero port - " + "SUCCESS"); + + /*Closing the socket which succeed in bind() */ + close(sk); + + /*Opening the socket again for further test*/ + sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /*bind() TEST11: INADDR_ANY address and zero port, bind() should + succeed*/ + bind_addr.sin_port = 0; + error = bind(sk, (struct sockaddr *) &bind_addr,sizeof(bind_addr)); + if ( error < 0 ) + tst_brkm(TBROK, tst_exit, "bind() with INADDR_ANY address and " + "zero port error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "bind() with INADDR_ANY address and zero port - " + "SUCCESS"); + + /*Closing the socket which succeed in bind() */ + close(sk); + + /*Opening the socket again for further test*/ + sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /*bind() TEST12: local address and zero port, bind() should + succeed*/ + bind_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + bind_addr.sin_port = 0; + error = bind(sk, (struct sockaddr *) &bind_addr,sizeof(bind_addr)); + if ( error < 0 ) + tst_brkm(TBROK, tst_exit, "bind() with local address and " + "zero port error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "bind() with local address and zero port - " + "SUCCESS"); + + /*listen() TEST13: Bad socket descriptor EBADF, Expected error*/ + error = listen(-1, 3); + if (error != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "listen() with bad socket descriptor " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "listen() with bad socket descriptor - EBADF"); + + /*listen() TEST14: Invalid socket ENOTSOCK, Expected error*/ + error = listen(0, 3); + if (error != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "listen() with invalid socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "listen() with invalid socket - ENOTSOCK"); + + /*listen() TEST15:listen on a bound socket, should succeed*/ + error = listen(sk, 3); + if ( error < 0 ) + tst_brkm(TBROK, tst_exit, "listen() on a bound socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "listen() on a bound socket - SUCCESS"); + + close(sk); + + return 0; +} diff --git a/src/func_tests/test_1_to_1_sockopt.c b/src/func_tests/test_1_to_1_sockopt.c new file mode 100644 index 0000000..c3a4833 --- /dev/null +++ b/src/func_tests/test_1_to_1_sockopt.c @@ -0,0 +1,414 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file has test cases to test negative scenarios for getsockopt () + * setsockopt () call for 1-1 style sockets + * + * setsockopt () Tests: + * ------------------- + * TEST1: setsockopt: Bad socket descriptor + * TEST2: setsockopt: Invalid socket + * TEST3: setsockopt: Invalid level + * TEST4: setsockopt: Invalid option buffer + * TEST5: setsockopt: Invalid option name + * TEST6: getsockopt: Bad socket descriptor + * TEST7: getsockopt: Invalid socket + * TEST8: getsockopt: Invalid option buffer + * TEST9: getsockopt: Invalid option name + * + * TEST10: getsockopt: SCTP_INITMSG + * TEST11: setsockopt: SCTP_INITMSG + * TEST12: setsockopt: SO_LINGER + * TEST13: getsockopt: SO_LINGER + * TEST14: getsockopt: SO_RCVBUF + * TEST15: getsockopt: SCTP_STATUS + * TEST16: setsockopt: SO_RCVBUF + * TEST17: setsockopt: SO_SNDBUF + * TEST18: getsockopt: SO_SNDBUF + * TEST19: getsockopt: SCTP_PRIMARY_ADDR + * TEST20: setsockopt: SCTP_PRIMARY_ADDR + * TEST21: getsockopt: SCTP_ASSOCINFO + * TEST22: setsockopt: SCTP_ASSOCINFO + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 22; +int TST_CNT = 0; + +int +main(void) +{ + int error; + socklen_t len; + int sk, sk1, sk2, acpt_sk, pf_class; + struct sctp_rtoinfo grtinfo; + struct sockaddr_in lstn_addr, conn_addr; + struct sctp_initmsg ginmsg; /*get the value for SCTP_INITMSG*/ + struct sctp_initmsg sinmsg; /*set the value for SCTP_INITMSG*/ + struct linger slinger; /*SO_LINGER structure*/ + struct linger glinger; /*SO_LINGER structure*/ + struct sockaddr_in addr; + struct sockaddr_in *gaddr; + struct sctp_status gstatus; /*SCTP_STATUS option*/ + int rcvbuf_val_get, rcvbuf_val_set; /*get and set var for SO_RCVBUF*/ + int sndbuf_val_get, sndbuf_val_set;/*get and set var for SO_SNDBUF*/ + struct sctp_prim gprimaddr;/*SCTP_PRIMARY_ADDR get*/ + struct sctp_prim sprimaddr;/*SCTP_PRIMARY_ADDR set*/ + struct sctp_assocparams sassocparams; /* SCTP_ASSOCPARAMS set */ + struct sctp_assocparams gassocparams; /* SCTP_ASSOCPARAMS get */ + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + pf_class = PF_INET; + + sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /*setsockopt() TEST1: Bad socket descriptor EBADF, Expected error*/ + error = setsockopt(-1, IPPROTO_SCTP, 0, 0, 0); + if (error != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "setsockopt with a bad socket " + "descriptor error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "setsockopt() with a bad socket descriptor - EBADF"); + + /*setsockopt() TEST2: Invalid socket ENOTSOCK, Expected error*/ + error = setsockopt(0, IPPROTO_SCTP, 0, 0, 0); + if (error != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "setsockopt with an invalid socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "setsockopt() with an invalid socket - ENOTSOCK"); + + /*setsockopt() TEST3: Invalid level ENOPROTOOPT, Expected error*/ + error = setsockopt(sk, -1, SCTP_RTOINFO, 0, 0); + if (error != -1 || errno != ENOPROTOOPT) + tst_brkm(TBROK, tst_exit, "setsockopt with invalid level " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "setsockopt() with an invalid level - ENOPROTOOPT"); + + /*setsockopt() TEST4: Invalid option buffer EFAULT, Expected error*/ + error = setsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO, + (const struct sctp_rtoinfo *)-1, sizeof(struct sctp_rtoinfo)); + if (error != -1 || errno != EFAULT) + tst_brkm(TBROK, tst_exit, "setsockopt with invalid option " + "buffer error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "setsockopt() with invalid option buffer - EFAULT"); + + /*setsockopt() TEST5: Invalid option Name EOPNOTSUPP, Expected error*/ + error = setsockopt(sk, IPPROTO_SCTP, SCTP_AUTOCLOSE, 0, 0); + if (error != -1 || errno != EOPNOTSUPP) + tst_brkm(TBROK, tst_exit, "setsockopt with invalid option " + "name error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "setsockopt() with invalid option name - EOPNOTSUPP"); + + /*getsockopt() TEST6: Bad socket descriptor EBADF, Expected error*/ + error = getsockopt(-1, IPPROTO_SCTP, 0, 0, 0); + if (error != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "getsockopt with a bad socket " + "descriptor error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "getsockopt() with a bad socket descriptor - EBADF"); + + /*getsockopt() TEST7: Invalid socket ENOTSOCK, Expected error*/ + error = getsockopt(0, IPPROTO_SCTP, 0, 0, 0); + if (error != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "getsockopt with an invalid socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "getsockopt() with an invalid socket - ENOTSOCK"); +#if 0 + /*getsockopt() TEST3: Invalid level ENOPROTOOPT, Expected error*/ + /*I have commented this test case because it is returning EOPNOTSUPP. + When I checked the code there also it is returning EOPNOTSUPP. As this + is not specific to TCP style, I do not want to do the code change*/ + + error = getsockopt(sk, -1, SCTP_RTOINFO, 0, 0); + if (error != -1 || errno != ENOPROTOOPT) + tst_brkm(TBROK, tst_exit, "getsockopt with invalid level " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "getsockopt() with an invalid level - ENOPROTOOPT"); +#endif + len = sizeof(struct sctp_rtoinfo); + + /*getsockopt() TEST8: Invalid option buffer EFAULT, Expected error*/ + error = getsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO, + (struct sctp_rtoinfo *)-1, &len); + if (error != -1 || errno != EFAULT) + tst_brkm(TBROK, tst_exit, "getsockopt with invalid option " + "buffer error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "getsockopt() with invalid option buffer - EFAULT"); + + /*getsockopt() TEST9: Invalid option Name EOPNOTSUPP, Expected error*/ + error = getsockopt(sk, IPPROTO_SCTP, SCTP_AUTOCLOSE, &grtinfo, &len); + if (error != -1 || errno != EOPNOTSUPP) + tst_brkm(TBROK, tst_exit, "getsockopt with invalid option " + "name error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "getsockopt() with invalid option name - EOPNOTSUPP"); + + close(sk); + + sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + sk2 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + len = sizeof(struct sctp_initmsg); + + /* TEST10: Test cases for getsockopt SCTP_INITMSG */ + test_getsockopt(sk1, SCTP_INITMSG, &ginmsg, &len); + + tst_resm(TPASS, "getsockopt() SCTP_INITMSG - SUCCESS"); + + sinmsg.sinit_num_ostreams = 5; + sinmsg.sinit_max_instreams = 5; + sinmsg.sinit_max_attempts = 3; + sinmsg.sinit_max_init_timeo = 30; + /* TEST11: Test case for setsockopt SCTP_INITMSG */ + test_setsockopt(sk1, SCTP_INITMSG, &sinmsg, sizeof(sinmsg)); + + test_getsockopt(sk1, SCTP_INITMSG, &ginmsg, &len); + + if (sinmsg.sinit_num_ostreams != ginmsg.sinit_num_ostreams && + sinmsg.sinit_max_instreams != ginmsg.sinit_max_instreams && + sinmsg.sinit_max_attempts != ginmsg.sinit_max_attempts && + sinmsg.sinit_max_init_timeo != ginmsg.sinit_max_init_timeo) + tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SCTP_INITMSG " + "compare failed"); + + tst_resm(TPASS, "setsockopt() SCTP_INITMSG - SUCCESS"); + + /*Now get the values on different endpoint*/ + test_getsockopt(sk2, SCTP_INITMSG, &ginmsg, &len); + + /*Comparison should not succeed here*/ + if (sinmsg.sinit_num_ostreams == ginmsg.sinit_num_ostreams && + sinmsg.sinit_max_instreams == ginmsg.sinit_max_instreams && + sinmsg.sinit_max_attempts == ginmsg.sinit_max_attempts && + sinmsg.sinit_max_init_timeo == ginmsg.sinit_max_init_timeo) + tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SCTP_INITMSG " + "unexpected compare success"); + + /* SO_LINGER Test with l_onff = 0 and l_linger = 0 */ + slinger.l_onoff = 0; + slinger.l_linger = 0; + test_bind(sk1, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); + test_listen(sk1, 10 ); + len = sizeof(struct sockaddr_in); + test_connect(sk2, (struct sockaddr *) &conn_addr, len); + + acpt_sk = test_accept(sk1, (struct sockaddr *)&addr, &len); + + len = sizeof(struct linger); + /* TEST12: Test case for setsockopt SO_LINGER */ + error = setsockopt(sk2, SOL_SOCKET, SO_LINGER, &slinger, len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "setsockopt SO_LINGER " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "setsockopt() SO_LINGER - SUCCESS"); + + /* TEST13: Test case for getsockopt SO_LINGER */ + error = getsockopt(sk2, SOL_SOCKET, SO_LINGER, &glinger, &len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "getsockopt SO_LINGER " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "getsockopt() SO_LINGER - SUCCESS"); + + if (slinger.l_onoff != glinger.l_onoff || + slinger.l_linger != glinger.l_linger) + tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SO_LINGER " + "compare failed"); + + /*First gets the default SO_RCVBUF value and comapres with the + value obtained from SCTP_STATUS*/ + len = sizeof(int); + /* TEST14: Test case for getsockopt SO_RCVBUF */ + error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &rcvbuf_val_get, &len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "getsockopt SO_RCVBUF " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "getsockopt() SO_RCVBUF - SUCCESS"); + + len = sizeof(struct sctp_status); + /* TEST15: Test case for getsockopt SCTP_STATUS */ + error = getsockopt(sk2, IPPROTO_SCTP, SCTP_STATUS, &gstatus, &len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "getsockopt SCTP_STATUS " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "getsockopt() SCTP_STATUS - SUCCESS"); + + /* Reducing the SO_RCVBUF value using setsockopt() */ + /*Minimum value is 128 and hence I am using it*/ + len = sizeof(int); + rcvbuf_val_set = 128; + /* TEST16: Test case for setsockopt SO_RCVBUF */ + error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &rcvbuf_val_set, len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "setsockopt SO_RCVBUF " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "setsockopt() SO_RCVBUF - SUCCESS"); + + error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &rcvbuf_val_get, &len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "getsockopt SO_RCVBUF " + "error:%d, errno:%d", error, errno); + + if ((2 * rcvbuf_val_set) != rcvbuf_val_get) + tst_brkm(TBROK, tst_exit, "Comparison failed:Set value and " + "got value differs Set Value=%d Get Value=%d", + (2*rcvbuf_val_set), rcvbuf_val_get); + + sndbuf_val_set=1024; + /* TEST17: Test case for setsockopt SO_SNDBUF */ + error = setsockopt(sk2, SOL_SOCKET, SO_SNDBUF, &sndbuf_val_set, len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "setsockopt SO_SNDBUF " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "setsockopt() SO_SNDBUF - SUCCESS"); + + /* TEST18: Test case for getsockopt SO_SNDBUF */ + error = getsockopt(sk2, SOL_SOCKET, SO_SNDBUF, &sndbuf_val_get, &len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "getsockopt SO_SNDBUF " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "getsockopt() SO_SNDBUF - SUCCESS"); + + if ((2 * sndbuf_val_set) != sndbuf_val_get) + tst_brkm(TBROK, tst_exit, "Comparison failed:Set value and " + "got value differs Set Value=%d Get Value=%d\n", + (2*sndbuf_val_set), sndbuf_val_get); + + + /* Getting the primary address using SCTP_PRIMARY_ADDR */ + len = sizeof(struct sctp_prim); + /* TEST19: Test case for getsockopt SCTP_PRIMARY_ADDR */ + error = getsockopt(sk2,IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &gprimaddr, + &len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "getsockopt SCTP_PRIMARY_ADDR " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "getsockopt() SCTP_PRIMARY_ADDR - SUCCESS"); + + gaddr = (struct sockaddr_in *) &gprimaddr.ssp_addr; + if(htons(gaddr->sin_port) != lstn_addr.sin_port && + gaddr->sin_family != lstn_addr.sin_family && + gaddr->sin_addr.s_addr != lstn_addr.sin_addr.s_addr) + tst_brkm(TBROK, tst_exit, "getsockopt SCTP_PRIMARY_ADDR value " + "mismatch"); + + memcpy(&sprimaddr, &gprimaddr, sizeof(struct sctp_prim)); + + /* TEST20: Test case for setsockopt SCTP_PRIMARY_ADDR */ + error = setsockopt(sk2,IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &sprimaddr, + len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "setsockopt SCTP_PRIMARY_ADDR " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "setsockopt() SCTP_PRIMARY_ADDR - SUCCESS"); + + /* TEST21: Test case for getsockopt SCTP_PRIMARY_ADDR */ + /* Getting the association info using SCTP_ASSOCINFO */ + len = sizeof(struct sctp_assocparams); + error = getsockopt(sk2, IPPROTO_SCTP, SCTP_ASSOCINFO, &gassocparams, + &len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "getsockopt SCTP_ASSOCINFO " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "getsockopt() SCTP_ASSOCINFO - SUCCESS"); + + /* TEST21: Test case for setsockopt SCTP_ASSOCINFO */ + memcpy(&sassocparams, &gassocparams, sizeof(struct sctp_assocparams)); + sassocparams.sasoc_asocmaxrxt += 5; + sassocparams.sasoc_cookie_life += 10; + + error = setsockopt(sk2, IPPROTO_SCTP, SCTP_ASSOCINFO, &sassocparams, + len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "setsockopt SCTP_ASSOCINFO " + "error:%d, errno:%d", error, errno); + + error = getsockopt(sk2, IPPROTO_SCTP, SCTP_ASSOCINFO, &gassocparams, + &len); + if (error < 0) + tst_brkm(TBROK, tst_exit, "getsockopt SCTP_ASSOCINFO " + "error:%d, errno:%d", error, errno); + + if (sassocparams.sasoc_asocmaxrxt != gassocparams.sasoc_asocmaxrxt || + sassocparams.sasoc_cookie_life != gassocparams.sasoc_cookie_life) + tst_brkm(TBROK, tst_exit, "getsockopt SCTP_ASSOCINFO value " + "mismatch"); + tst_resm(TPASS, "setsockopt() SCTP_ASSOCINFO - SUCCESS"); + + close(sk2); + close(sk1); + close(acpt_sk); + + return 0; +} diff --git a/src/func_tests/test_1_to_1_threads.c b/src/func_tests/test_1_to_1_threads.c new file mode 100644 index 0000000..84b9fb2 --- /dev/null +++ b/src/func_tests/test_1_to_1_threads.c @@ -0,0 +1,198 @@ +/* SCTP kernel Implementation + * Copyright (c) 2003 Hewlett-Packard Development Company, L.P + * (C) Copyright IBM Corp. 2004 + * + * This file does send and receive for 500 threads on a unique association for + * THREAD_SND_RCV_LOOPS = 10 many times. To change the number of threads + * change the THREADS valuen and loop change the THREAD_SND_RCV_LOOPS. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for sockaddr_in */ +#include +#include +#include +#include +#include +#include + +#define THREADS 10 /* FIXME should be 500 instead of 10 */ +#define THREAD_SND_RCV_LOOPS 10 + +char *TCID = __FILE__; +int TST_TOTAL = 1; +int TST_CNT = 0; + +int client_sk; +int server_sk; +int acpt_sk; +struct sockaddr_in conn_addr; +char *message = "hello, world!\n"; + +void +t_recv (int id) { + int cnt; + struct msghdr inmessage; + struct iovec iov; + char incmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + char * buffer; + + memset(&inmessage, 0, sizeof(inmessage)); + buffer = malloc(100); + + iov.iov_base = buffer; + iov.iov_len = 100; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + + cnt = test_recvmsg(acpt_sk,&inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, cnt, strlen(message) + 1, MSG_EOR, + 0, 0); +} + +void +t_send(int id) { + struct msghdr outmessage; + struct sctp_sndrcvinfo *sinfo; + char *buffer_snd; + struct cmsghdr *cmsg; + struct iovec out_iov; + char outcmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + + memset(&outmessage, 0, sizeof(outmessage)); + buffer_snd = malloc(100); + + outmessage.msg_name = &conn_addr; + outmessage.msg_namelen = sizeof(conn_addr); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_iov->iov_base = message; + outmessage.msg_iov->iov_len = (strlen(message) + 1); + + test_sendmsg(client_sk, &outmessage, 0, strlen(message)+1); +} + +void * relay (int id) { + if (id == 0) { + t_send(id); + } else if (id == THREADS -1) { + t_send(id); + } else { + t_recv (id); + t_send(id); + } + + return 0; +} + + +int +main(void) +{ + + int cnt,i; + pthread_t thread[THREADS]; + int status; + int exit_status; + void * result; + pthread_attr_t attr; + struct sockaddr_in lstn_addr; + socklen_t len = sizeof(struct sockaddr_in); + struct sockaddr_in svr_addr; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + server_sk = test_socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); + client_sk = test_socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); + + lstn_addr.sin_family = AF_INET; + lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + lstn_addr.sin_port = htons(SCTP_TESTPORT_1); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; + conn_addr.sin_port = htons(SCTP_TESTPORT_1); + + test_bind(server_sk, (struct sockaddr *)&lstn_addr, + sizeof(struct sockaddr_in)); + + test_listen(server_sk,10); + + test_connect(client_sk,(struct sockaddr *)&conn_addr,len); + + acpt_sk = test_accept(server_sk, (struct sockaddr *)&svr_addr, &len); + + for ( i = 0; i < THREAD_SND_RCV_LOOPS; i++ ) { + for (cnt = 1; cnt < THREADS; cnt++) { + status = pthread_create(&thread[cnt], &attr, + (void *)relay, (void*)cnt); + if (status) + tst_brkm(TBROK, tst_exit, "pthread_create " + "failed status:%d, errno:%d", status, + errno); + } + + pthread_attr_destroy(&attr); + for (cnt = 1; cnt < THREADS ; cnt++) { + exit_status = pthread_join (thread[cnt], &result); + if (exit_status == -1) + tst_brkm(TBROK, tst_exit, "pthread_join " + "Thread #%d exited with status:%d", + cnt, exit_status); + } + } + + tst_resm(TPASS, "send and receive data across multiple threads - " + "SUCCESS"); + + pthread_exit(NULL); +} diff --git a/src/func_tests/test_assoc_abort.c b/src/func_tests/test_assoc_abort.c new file mode 100644 index 0000000..7e9a0b5 --- /dev/null +++ b/src/func_tests/test_assoc_abort.c @@ -0,0 +1,244 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2001, 2003 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2001 Intel Corp. + * Copyright (c) 2001 Nokia, Inc. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Ardelle Fan + * Sridhar Samudrala + */ + +/* This is a functional test to verify the ungraceful abort of an + * association. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 1; +int TST_CNT = 0; + +#define MAX_CLIENTS 10 + +int +main(int argc, char *argv[]) +{ + int svr_sk, clt_sk[MAX_CLIENTS]; + sockaddr_storage_t svr_loop, clt_loop[MAX_CLIENTS]; + sctp_assoc_t svr_associd[MAX_CLIENTS]; + struct iovec iov; + struct msghdr inmessage; + struct msghdr outmessage; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + struct iovec out_iov; + int error; + uint32_t ppid; + uint32_t stream; + struct sctp_assoc_change *sac; + char *big_buffer; + int i; + char *message = "hello, world!\n"; + struct sctp_status status; + socklen_t status_len; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Create and bind the server socket. */ + svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + svr_loop.v4.sin_family = AF_INET; + svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1); + test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop)); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(svr_sk); + + /* Mark server socket as being able to accept new associations. */ + test_listen(svr_sk, 1); + + /* Create and bind all the client sockets. */ + for (i = 0; i < MAX_CLIENTS; i++) { + clt_sk[i] = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + + clt_loop[i].v4.sin_family = AF_INET; + clt_loop[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + clt_loop[i].v4.sin_port = htons(SCTP_TESTPORT_2 + i); + test_bind(clt_sk[i], &clt_loop[i].sa, sizeof(clt_loop[i])); + + test_enable_assoc_change(clt_sk[i]); + } + + /* Build up a msghdr structure we can use for all sending. */ + outmessage.msg_name = &svr_loop; + outmessage.msg_namelen = sizeof(svr_loop); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid = rand(); /* Choose an arbitrary value. */ + stream = 1; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + out_iov.iov_base = message; + out_iov.iov_len = strlen(message) + 1; + + /* Send the first message from all the clients to the server. This + * will create the associations. + */ + for (i = 0; i < MAX_CLIENTS; i++) + test_sendmsg(clt_sk[i], &outmessage, 0, strlen(message) + 1); + + /* Initialize inmessage for all receives. */ + big_buffer = test_malloc(REALLY_BIG); + memset(&inmessage, 0, sizeof(inmessage)); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + + /* Get the communication up message on all client sockets. */ + for (i = 0; i < MAX_CLIENTS; i++) { + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + } + + /* Get the communication up message and the data message on the + * server sockets for all the clients. + */ + for (i = 0; i < MAX_CLIENTS; i++) { + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(message) + 1, + MSG_EOR, stream, ppid); + sac = (struct sctp_assoc_change *)iov.iov_base; + svr_associd[i] = sac->sac_assoc_id; + } + + outmessage.msg_name = NULL; + outmessage.msg_namelen = 0; + outmessage.msg_iov = NULL; + outmessage.msg_iovlen = 0; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + sinfo->sinfo_flags |= SCTP_ABORT; + + /* Shutdown all the associations of the server socket in a loop. */ + for (i = 0; i < MAX_CLIENTS; i++) { + sinfo->sinfo_assoc_id = svr_associd[i]; + + /* Verify that the association is present. */ + memset(&status, 0, sizeof(struct sctp_status)); + status.sstat_assoc_id = sinfo->sinfo_assoc_id; + status_len = sizeof(struct sctp_status); + error = getsockopt(svr_sk, SOL_SCTP, SCTP_STATUS, + &status, &status_len); + if (error) + tst_brkm(TBROK, tst_exit, + "getsockopt(SCTP_STATUS): %s", + strerror(errno)); + + /* Call sendmsg() to abort the association. */ + test_sendmsg(svr_sk, &outmessage, 0, 0); + + /* Verify that the association is no longer present. */ + memset(&status, 0, sizeof(struct sctp_status)); + status.sstat_assoc_id = sinfo->sinfo_assoc_id; + status_len = sizeof(struct sctp_status); + error = getsockopt(svr_sk, SOL_SCTP, SCTP_STATUS, + &status, &status_len); + if ((error != -1) && (errno != EINVAL)) + tst_brkm(TBROK, tst_exit, + "getsockopt(SCTP_STATUS) " + "error:%d errno:%d", error, errno); + } + + close(svr_sk); + + /* Get the COMM_LOST notification. */ + for (i = 0; i < MAX_CLIENTS; i++) { + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change)+4, + SCTP_ASSOC_CHANGE, SCTP_COMM_LOST); + + close(clt_sk[i]); + } + + tst_resm(TPASS, "ABORT an association using SCTP_ABORT"); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_assoc_shutdown.c b/src/func_tests/test_assoc_shutdown.c new file mode 100644 index 0000000..dcdb377 --- /dev/null +++ b/src/func_tests/test_assoc_shutdown.c @@ -0,0 +1,246 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2001, 2003 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2001 Intel Corp. + * Copyright (c) 2001 Nokia, Inc. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Sridhar Samudrala + */ + +/* This is a functional test to verify the graceful shutdown of an + * association. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 1; +int TST_CNT = 0; + +#define MAX_CLIENTS 10 + +int +main(int argc, char *argv[]) +{ + int svr_sk, clt_sk[MAX_CLIENTS]; + sctp_assoc_t svr_associd[MAX_CLIENTS]; + sockaddr_storage_t svr_loop, clt_loop[MAX_CLIENTS]; + struct iovec iov; + struct msghdr inmessage; + struct msghdr outmessage; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + struct iovec out_iov; + int error; + uint32_t ppid; + uint32_t stream; + struct sctp_assoc_change *sac; + char *big_buffer; + int i; + char *message = "hello, world!\n"; + struct sctp_status status; + socklen_t status_len; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Create and bind the server socket. */ + svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + + svr_loop.v4.sin_family = AF_INET; + svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1); + test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop)); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(svr_sk); + + /* Mark server socket as being able to accept new associations. */ + test_listen(svr_sk, 1); + + /* Create and bind all the client sockets. */ + for (i = 0; i < MAX_CLIENTS; i++) { + clt_sk[i] = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + + clt_loop[i].v4.sin_family = AF_INET; + clt_loop[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + clt_loop[i].v4.sin_port = htons(SCTP_TESTPORT_2 + i); + test_bind(clt_sk[i], &clt_loop[i].sa, sizeof(clt_loop[i])); + + test_enable_assoc_change(clt_sk[i]); + } + + /* Build up a msghdr structure we can use for all sending. */ + outmessage.msg_name = &svr_loop; + outmessage.msg_namelen = sizeof(svr_loop); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid = rand(); /* Choose an arbitrary value. */ + stream = 1; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + out_iov.iov_base = message; + out_iov.iov_len = strlen(message) + 1; + + /* Send the first message from all the clients to the server. This + * will create the associations. + */ + for (i = 0; i < MAX_CLIENTS; i++) + test_sendmsg(clt_sk[i], &outmessage, 0, strlen(message)+1); + + /* Initialize inmessage for all receives. */ + big_buffer = test_malloc(REALLY_BIG); + memset(&inmessage, 0, sizeof(inmessage)); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + + /* Get the communication up message on all client sockets. */ + for (i = 0; i < MAX_CLIENTS; i++) { + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + } + + /* Get the communication up message and the data message on the + * server sockets for all the clients. + */ + for (i = 0; i < MAX_CLIENTS; i++) { + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(message)+1, + MSG_EOR, stream, ppid); + sac = (struct sctp_assoc_change *)iov.iov_base; + svr_associd[i] = sac->sac_assoc_id; + } + + /* Build up a msghdr structure we can use for all sending. */ + outmessage.msg_name = NULL; + outmessage.msg_namelen = 0; + outmessage.msg_iov = NULL; + outmessage.msg_iovlen = 0; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + sinfo->sinfo_flags |= SCTP_EOF; + + /* Shutdown all the associations of the server socket in a loop. */ + for (i = 0; i < MAX_CLIENTS; i++) { + sinfo->sinfo_assoc_id = svr_associd[i]; + + /* Verify that the association is present. */ + memset(&status, 0, sizeof(struct sctp_status)); + status.sstat_assoc_id = sinfo->sinfo_assoc_id; + status_len = sizeof(struct sctp_status); + error = getsockopt(svr_sk, SOL_SCTP, SCTP_STATUS, + &status, &status_len); + if (error) + tst_brkm(TBROK, tst_exit, + "getsockopt(SCTP_STATUS): %s", + strerror(errno)); + + /* Call sendmsg() to shutdown the association. */ + test_sendmsg(svr_sk, &outmessage, 0, 0); + + /* Verify that the association is no longer present. */ + memset(&status, 0, sizeof(struct sctp_status)); + status.sstat_assoc_id = sinfo->sinfo_assoc_id; + status_len = sizeof(struct sctp_status); + error = getsockopt(svr_sk, SOL_SCTP, SCTP_STATUS, + &status, &status_len); + if ((error != -1) && (errno != EINVAL)) + tst_brkm(TBROK, tst_exit, + "getsockopt(SCTP_STATUS) " + "error:%d errno:%d", error, errno); + } + + close(svr_sk); + + /* Get the shutdown complete notification. */ + for (i = 0; i < MAX_CLIENTS; i++) { + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, + SCTP_SHUTDOWN_COMP); + + close(clt_sk[i]); + } + + tst_resm(TPASS, "Graceful shutdown of associations using SCTP_EOF"); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_autoclose.c b/src/func_tests/test_autoclose.c new file mode 100644 index 0000000..902375c --- /dev/null +++ b/src/func_tests/test_autoclose.c @@ -0,0 +1,167 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2001, 2003 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2001 Intel Corp. + * Copyright (c) 2001 Nokia, Inc. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Sridhar Samudrala + */ + +/* This is a Functional Test to verify autoclose functionality and the + * socket option SCTP_AUTOCLOSE that can be used to specify the duration in + * which an idle association is automatically closed. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 1; +int TST_CNT = 0; + +int +main(int argc, char *argv[]) +{ + int sk1, sk2; + sockaddr_storage_t loop1, loop2; + struct msghdr inmessage, outmessage; + struct iovec iov, out_iov; + int error, bytes_sent; + char *big_buffer; + char *message = "hello, world!\n"; + uint32_t autoclose; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + loop1.v4.sin_family = AF_INET; + loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + loop1.v4.sin_port = htons(SCTP_TESTPORT_1); + + loop2.v4.sin_family = AF_INET; + loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + loop2.v4.sin_port = htons(SCTP_TESTPORT_2); + + /* Create the two endpoints which will talk to each other. */ + sk1 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + sk2 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(sk1); + test_enable_assoc_change(sk2); + + /* Bind these sockets to the test ports. */ + test_bind(sk1, &loop1.sa, sizeof(loop1)); + test_bind(sk2, &loop2.sa, sizeof(loop2)); + + /* Mark sk2 as being able to accept new associations. */ + test_listen(sk2, 1); + + /* Set the autoclose duration for the associations created on sk1 + * and sk2 to be 5 seconds. + */ + autoclose = 5; + test_setsockopt(sk1, SCTP_AUTOCLOSE, &autoclose, sizeof(autoclose)); + test_setsockopt(sk2, SCTP_AUTOCLOSE, &autoclose, sizeof(autoclose)); + + /* Send the first message. This will create the association. */ + memset(&outmessage, 0, sizeof(outmessage)); + outmessage.msg_name = &loop2; + outmessage.msg_namelen = sizeof(loop2); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_iov->iov_base = message; + outmessage.msg_iov->iov_len = strlen(message) + 1; + bytes_sent = test_sendmsg(sk1, &outmessage, 0, strlen(message)+1); + + /* Initialize inmessage for all receives. */ + big_buffer = test_malloc(REALLY_BIG); + memset(&inmessage, 0, sizeof(inmessage)); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = NULL; + + /* Get the communication up message on sk2. */ + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + + /* Get the communication up message on sk1. */ + error = test_recvmsg(sk1, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + + /* Get the first message which was sent. */ + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(message) + 1, + MSG_EOR|MSG_CTRUNC, 0, 0); + + tst_resm(TINFO, "Waiting for the associations to close automatically " + "in 5 secs"); + + /* Get the shutdown complete notification from sk1. */ + error = test_recvmsg(sk1, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP); + + /* Get the shutdown complete notification from sk2. */ + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP); + + tst_resm(TPASS, "Autoclose of associations"); + + /* Shut down the link. */ + close(sk1); + close(sk2); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_basic.c b/src/func_tests/test_basic.c new file mode 100644 index 0000000..b8d4eae --- /dev/null +++ b/src/func_tests/test_basic.c @@ -0,0 +1,456 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2001, 2003 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2001 Intel Corp. + * Copyright (c) 2001 Nokia, Inc. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * La Monte H.P. Yarroll + * Karl Knutson + * Hui Huang + * Jon Grimm + * Sridhar Samudrala + */ + +/* This is a basic functional test for the SCTP kernel + * implementation state machine. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 15; +int TST_CNT = 0; + +int main(void) +{ + int sk1, sk2; + sockaddr_storage_t loop1; + sockaddr_storage_t loop2; + sockaddr_storage_t msgname; + struct iovec iov; + struct msghdr inmessage; + struct msghdr outmessage; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + struct iovec out_iov; + char *message = "hello, world!\n"; + char *telephone = "Watson, come here! I need you!\n"; + char *telephone_resp = "I already brought your coffee...\n"; + int error, bytes_sent; + int pf_class; + uint32_t ppid; + uint32_t stream; + sctp_assoc_t associd1, associd2; + struct sctp_assoc_change *sac; + char *big_buffer; + struct sockaddr *laddrs, *paddrs; + int n_laddrs, n_paddrs, i; + struct sockaddr *sa_addr; + struct sockaddr_in *in_addr; + struct sockaddr_in6 *in6_addr; + void *addr_buf; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Set some basic values which depend on the address family. */ +#if TEST_V6 + pf_class = PF_INET6; + + loop1.v6.sin6_family = AF_INET6; + loop1.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_ANY_INIT; + loop1.v6.sin6_port = htons(SCTP_TESTPORT_1); + + loop2.v6.sin6_family = AF_INET6; + loop2.v6.sin6_addr = in6addr_loopback; + loop2.v6.sin6_port = htons(SCTP_TESTPORT_2); +#else + pf_class = PF_INET; + + loop1.v4.sin_family = AF_INET; + loop1.v4.sin_addr.s_addr = INADDR_ANY; + loop1.v4.sin_port = htons(SCTP_TESTPORT_1); + + loop2.v4.sin_family = AF_INET; + loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + loop2.v4.sin_port = htons(SCTP_TESTPORT_2); +#endif /* TEST_V6 */ + + /* Create the two endpoints which will talk to each other. */ + sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + + tst_resm(TPASS, "socket"); + + /* Bind these sockets to the test ports. */ + test_bind(sk1, &loop1.sa, sizeof(loop1)); + test_bind(sk2, &loop2.sa, sizeof(loop2)); + + tst_resm(TPASS, "bind"); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(sk1); + test_enable_assoc_change(sk2); + + /* Initialize inmessage for all receives. */ + big_buffer = test_malloc(REALLY_BIG); + memset(&inmessage, 0, sizeof(inmessage)); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + inmessage.msg_name = &msgname; + + /* Try to read on socket 2. This should fail since we are + * neither listening, nor established. + */ + inmessage.msg_controllen = sizeof(incmsg); + error = recvmsg(sk2, &inmessage, MSG_WAITALL); + if (error > 0) + tst_brkm(TBROK, tst_exit, "recvmsg on a socket neither" + "listening nor established error: %d", error); + + tst_resm(TPASS, "recvmsg on a socket neither listening nor " + "established"); + + /* Mark sk2 as being able to accept new associations. */ + error = test_listen(sk2, 1); + + tst_resm(TPASS, "listen"); + + /* Send the first message. This will create the association. */ + outmessage.msg_name = &loop2; + outmessage.msg_namelen = sizeof(loop2); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid = rand(); /* Choose an arbitrary value. */ + stream = 1; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + outmessage.msg_iov->iov_base = message; + outmessage.msg_iov->iov_len = strlen(message) + 1; + test_sendmsg(sk1, &outmessage, 0, strlen(message)+1); + + tst_resm(TPASS, "sendmsg with a valid msg_name"); + + /* Get the communication up message on sk2. */ + inmessage.msg_controllen = sizeof(incmsg); + inmessage.msg_namelen = sizeof(msgname); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); +#if TEST_V6 + + if (inmessage.msg_namelen != sizeof(struct sockaddr_in6)) { + DUMP_CORE; + } + if (msgname.v6.sin6_port != htons(SCTP_TESTPORT_1)) { + DUMP_CORE; + } + + if (msgname.v6.sin6_family != AF_INET6) { + DUMP_CORE; + } + + if (memcmp(&msgname.v6.sin6_addr, &in6addr_loopback, + sizeof(msgname.v6.sin6_addr))) { + DUMP_CORE; + } +#else + if (inmessage.msg_namelen != sizeof(struct sockaddr_in)) { + DUMP_CORE; + } + if (msgname.v4.sin_port != htons(SCTP_TESTPORT_1)) { + DUMP_CORE; + } + + if (msgname.v4.sin_family != AF_INET) { + DUMP_CORE; + } + if (msgname.v4.sin_addr.s_addr != SCTP_IP_LOOPBACK) { + DUMP_CORE; + } +#endif + sac = (struct sctp_assoc_change *)iov.iov_base; + associd2 = sac->sac_assoc_id; + + /* Get the communication up message on sk1. */ + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk1, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + associd1 = sac->sac_assoc_id; + + tst_resm(TPASS, "recvmsg COMM_UP notifications"); + + /* Get the first message which was sent. */ + inmessage.msg_controllen = sizeof(incmsg); + inmessage.msg_namelen = sizeof(msgname); + memset(&msgname, 0, sizeof(msgname)); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(message) + 1, + MSG_EOR, stream, ppid); +#if TEST_V6 + + if (inmessage.msg_namelen != sizeof(struct sockaddr_in6)) { + DUMP_CORE; + } + if (msgname.v6.sin6_port != htons(SCTP_TESTPORT_1)) { + DUMP_CORE; + } + + if (msgname.v6.sin6_family != AF_INET6) { + DUMP_CORE; + } + + if (memcmp(&msgname.v6.sin6_addr, &in6addr_loopback, + sizeof(msgname.v6.sin6_addr))) { + DUMP_CORE; + } +#else + if (inmessage.msg_namelen != sizeof(struct sockaddr_in)) { + DUMP_CORE; + } + if (msgname.v4.sin_port != htons(SCTP_TESTPORT_1)) { + DUMP_CORE; + } + if (msgname.v4.sin_family != AF_INET) { + DUMP_CORE; + } + if (msgname.v4.sin_addr.s_addr != SCTP_IP_LOOPBACK) { + DUMP_CORE; + } +#endif + + /* Try to send a message with NULL msg_name and associd, should fail */ + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid++; + stream++; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + outmessage.msg_iov->iov_base = telephone; + outmessage.msg_iov->iov_len = strlen(telephone) + 1; + outmessage.msg_name = NULL; + outmessage.msg_namelen = 0; + bytes_sent = sendmsg(sk1, &outmessage, MSG_NOSIGNAL); + if ((bytes_sent > 0) || (EPIPE != errno)) + tst_brkm(TBROK, tst_exit, "sendmsg with NULL associd and " + "NULL msg_name error:%d errno:%d", error, errno); + + tst_resm(TPASS, "sendmsg with NULL associd and NULL msg_name"); + + /* Fill in a incorrect assoc_id, which should cause an error. */ + sinfo->sinfo_assoc_id = associd2; + bytes_sent = sendmsg(sk1, &outmessage, MSG_NOSIGNAL); + if ((bytes_sent > 0) || (EPIPE != errno)) + tst_brkm(TBROK, tst_exit, "sendmsg with incorrect associd " + "error:%d errno:%d", error, errno); + + tst_resm(TPASS, "sendmsg with incorrect associd"); + + /* Fill in a correct assoc_id and get back to the normal testing. */ + sinfo->sinfo_assoc_id = associd1; + /* Send two more messages, to cause a second SACK. */ + test_sendmsg(sk1, &outmessage, 0, strlen(telephone)+1); + + outmessage.msg_name = &loop2; + outmessage.msg_namelen = sizeof(loop2); + outmessage.msg_iov->iov_base = telephone_resp; + outmessage.msg_iov->iov_len = strlen(telephone_resp) + 1; + test_sendmsg(sk1, &outmessage, 0, strlen(telephone_resp)+1); + + tst_resm(TPASS, "sendmsg with valid associd"); + + /* Get those two messages. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(telephone) + 1, + MSG_EOR, stream, ppid); + + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(telephone_resp) + 1, + MSG_EOR, stream, ppid); + + tst_resm(TPASS, "recvmsg"); + + n_laddrs = sctp_getladdrs(sk1, associd1, &laddrs); + if (n_laddrs <= 0) + tst_brkm(TBROK, tst_exit, "sctp_getladdrs: %s", + strerror(errno)); + + tst_resm(TPASS, "sctp_getladdrs"); + + addr_buf = (void *)laddrs; + for (i = 0; i < n_laddrs; i++) { + sa_addr = (struct sockaddr *)addr_buf; + if (AF_INET == sa_addr->sa_family) { + in_addr = (struct sockaddr_in *)sa_addr; + tst_resm(TINFO, "LOCAL ADDR %d.%d.%d.%d PORT %d", + NIPQUAD(in_addr->sin_addr), + ntohs(in_addr->sin_port)); + addr_buf += sizeof(struct sockaddr_in); + } else { + in6_addr = (struct sockaddr_in6 *)sa_addr; + tst_resm(TINFO, + "LOCAL ADDR %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x PORT %d", + NIP6(in6_addr->sin6_addr), + ntohs(in6_addr->sin6_port)); + addr_buf += sizeof(struct sockaddr_in6); + } + } + + sctp_freeladdrs(laddrs); + + tst_resm(TPASS, "sctp_freeladdrs"); + + n_paddrs = sctp_getpaddrs(sk1, associd1, &paddrs); + if (n_paddrs <= 0) + tst_brkm(TBROK, tst_exit, "sctp_getpaddrs: %s", + strerror(errno)); + + tst_resm(TPASS, "sctp_getpaddrs"); + + addr_buf = (void *)paddrs; + for (i = 0; i < n_paddrs; i++) { + sa_addr = (struct sockaddr *)addr_buf; + if (AF_INET == sa_addr->sa_family) { + in_addr = (struct sockaddr_in *)sa_addr; + tst_resm(TINFO, "PEER ADDR %d.%d.%d.%d PORT %d", + NIPQUAD(in_addr->sin_addr), + ntohs(in_addr->sin_port)); + addr_buf += sizeof(struct sockaddr_in); + } else { + in6_addr = (struct sockaddr_in6 *)sa_addr; + tst_resm(TINFO, + "PEER ADDR %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x PORT %d", + NIP6(in6_addr->sin6_addr), + ntohs(in6_addr->sin6_port)); + addr_buf += sizeof(struct sockaddr_in6); + } + } + + sctp_freepaddrs(paddrs); + + tst_resm(TPASS, "sctp_freepaddrs"); + + /* Shut down the link. */ + close(sk1); + + /* Get the shutdown complete notification. */ + inmessage.msg_controllen = sizeof(incmsg); + inmessage.msg_namelen = sizeof(msgname); + memset(&msgname, 0, sizeof(msgname)); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP); +#if TEST_V6 + + if (inmessage.msg_namelen != sizeof(struct sockaddr_in6)) { + DUMP_CORE; + } + if (msgname.v6.sin6_port != htons(SCTP_TESTPORT_1)) { + DUMP_CORE; + } + + if (msgname.v6.sin6_family != AF_INET6) { + DUMP_CORE; + } + + if (memcmp(&msgname.v6.sin6_addr, &in6addr_loopback, + sizeof(msgname.v6.sin6_addr))) { + DUMP_CORE; + } +#else + if (inmessage.msg_namelen != sizeof(struct sockaddr_in)) { + DUMP_CORE; + } + if (msgname.v4.sin_port != htons(SCTP_TESTPORT_1)) { + DUMP_CORE; + } + + if (msgname.v4.sin_family != AF_INET) { + DUMP_CORE; + } + if (msgname.v4.sin_addr.s_addr != SCTP_IP_LOOPBACK) { + DUMP_CORE; + } +#endif + + tst_resm(TPASS, "recvmsg SHUTDOWN_COMP notification"); + + close(sk2); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_connect.c b/src/func_tests/test_connect.c new file mode 100644 index 0000000..26e9d4d --- /dev/null +++ b/src/func_tests/test_connect.c @@ -0,0 +1,213 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2002, 2003 + * Copyright (c) 1999-2001 Motorola, Inc. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Sridhar Samudrala + */ + +/* This is a kernel test to verify the one-to-many style connect() in blocking + * and non-blocking modes. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 5; +int TST_CNT = 0; + +int +main(int argc, char *argv[]) +{ + int svr_sk, clt_sk1, clt_sk2, peeloff_sk; + sctp_assoc_t svr_associd1, svr_associd2, clt_associd1, clt_associd2; + sockaddr_storage_t svr_loop, clt_loop1, clt_loop2, clt_loop3; + struct iovec iov; + struct msghdr inmessage; + int error; + struct sctp_assoc_change *sac; + char *big_buffer; + int flags; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Initialize the server and client addresses. */ + svr_loop.v4.sin_family = AF_INET; + svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1); + clt_loop1.v4.sin_family = AF_INET; + clt_loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + clt_loop1.v4.sin_port = htons(SCTP_TESTPORT_2); + clt_loop2.v4.sin_family = AF_INET; + clt_loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + clt_loop2.v4.sin_port = htons(SCTP_TESTPORT_2+1); + clt_loop3.v4.sin_family = AF_INET; + clt_loop3.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + clt_loop3.v4.sin_port = htons(SCTP_TESTPORT_2+2); + + /* Create and bind the server socket. */ + svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop)); + + /* Mark server socket as being able to accept new associations. */ + test_listen(svr_sk, 1); + + /* Create and bind the client sockets. */ + clt_sk1 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + test_bind(clt_sk1, &clt_loop1.sa, sizeof(clt_loop1)); + clt_sk2 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + test_bind(clt_sk2, &clt_loop2.sa, sizeof(clt_loop2)); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(svr_sk); + test_enable_assoc_change(clt_sk1); + test_enable_assoc_change(clt_sk2); + + /* Set clt_sk1 as non-blocking. */ + flags = fcntl(clt_sk1, F_GETFL, 0); + if (flags < 0) + tst_brkm(TBROK, tst_exit, "fcntl F_GETFL: %s", strerror(errno)); + if (fcntl(clt_sk1, F_SETFL, flags | O_NONBLOCK) < 0) + tst_brkm(TBROK, tst_exit, "fcntl F_SETFL: %s", strerror(errno)); + + /* Do a non-blocking connect from clt_sk1 to svr_sk */ + error = connect(clt_sk1, &svr_loop.sa, sizeof(svr_loop)); + /* Non-blocking connect should return immediately with EINPROGRESS. */ + if ((error != -1) || (EINPROGRESS != errno)) + tst_brkm(TBROK, tst_exit, "non-blocking connect error: %d" + "errno:%d", error, errno); + + tst_resm(TPASS, "non-blocking connect"); + + /* Doing a connect on a socket to create an association that is + * is already established should return EISCONN. + */ + error = connect(clt_sk1, &svr_loop.sa, sizeof(svr_loop)); + if ((error != -1) || (EISCONN != errno)) + tst_brkm(TBROK, tst_exit, "connect on a socket to create an " + "assoc that is already established error:%d errno:%d", + error, errno); + + tst_resm(TPASS, "connect on a socket to create an assoc that is " + "already established"); + + /* Initialize inmessage for all receives. */ + memset(&inmessage, 0, sizeof(inmessage)); + big_buffer = test_malloc(REALLY_BIG); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = NULL; + + /* Get COMM_UP on clt_sk1 */ + error = test_recvmsg(clt_sk1, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + clt_associd1 = sac->sac_assoc_id; + + /* Get COMM_UP on svr_sk */ + error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + svr_associd1 = sac->sac_assoc_id; + + /* Do a blocking connect from clt_sk2 to svr_sk. + * Blocking connect should block until the association is established + * and return success. + */ + test_connect(clt_sk2, &svr_loop.sa, sizeof(svr_loop)); + + /* Get COMM_UP on clt_sk2 */ + error = test_recvmsg(clt_sk2, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + clt_associd2 = sac->sac_assoc_id; + + /* Get COMM_UP on svr_sk */ + error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + svr_associd2 = sac->sac_assoc_id; + + tst_resm(TPASS, "blocking connect"); + + peeloff_sk = test_sctp_peeloff(svr_sk, svr_associd1); + + /* Doing a connect on a peeled off socket should fail. */ + error = connect(peeloff_sk, &clt_loop3.sa, sizeof(clt_loop3)); + if ((error != -1) || (EISCONN != errno)) + tst_brkm(TBROK, tst_exit, "connect on a peeled off socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "connect on a peeled off socket"); + + /* Trying to create an association on a socket that matches an + * existing peeled-off association should fail. + */ + error = connect(svr_sk, &clt_loop1.sa, sizeof(clt_loop1)); + if ((error != -1) || (EADDRNOTAVAIL != errno)) + tst_brkm(TBROK, tst_exit, "connect to create an assoc that " + "matches a peeled off assoc error:%d errno:%d", + error, errno); + + tst_resm(TPASS, "connect to create an assoc that matches a peeled off " + "assoc"); + + close(svr_sk); + close(clt_sk1); + close(clt_sk2); + close(peeloff_sk); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_connectx.c b/src/func_tests/test_connectx.c new file mode 100644 index 0000000..2477241 --- /dev/null +++ b/src/func_tests/test_connectx.c @@ -0,0 +1,270 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2002, 2003 + * Copyright (c) 1999-2001 Motorola, Inc. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Sridhar Samudrala + */ + +/* This is a kernel test to verify the one-to-many style sctp_connectx() + * in blocking and non-blocking modes. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 9; +int TST_CNT = 0; + +#define NUMADDR 6 +#define SCTP_IP_LOOPBACK_I(I) htonl(0x7f000001 + I) + +#define NIPQUAD(addr) \ + ((unsigned char *)&addr)[0], \ + ((unsigned char *)&addr)[1], \ + ((unsigned char *)&addr)[2], \ + ((unsigned char *)&addr)[3] + +int +main(int argc, char *argv[]) +{ + int svr_sk, clt_sk1, clt_sk2, peeloff_sk; + sctp_assoc_t associd, svr_associd1, svr_associd2, clt_associd1, clt_associd2; + struct iovec iov; + struct msghdr inmessage; + int error, i; + struct sctp_assoc_change *sac; + char *big_buffer; + int flags; + struct sockaddr_in svr_loop[NUMADDR]; + struct sockaddr_in svr_try[NUMADDR]; + struct sockaddr_in clt_loop1[NUMADDR]; + struct sockaddr_in clt_loop2[NUMADDR]; + struct sockaddr_in clt_loop3[NUMADDR]; + sockaddr_storage_t svr_test[NUMADDR], clt_test1[NUMADDR], clt_test2[NUMADDR]; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + for (i = 0; i < NUMADDR; i++) { + /* Initialize the server and client addresses. */ + svr_loop[i].sin_family = AF_INET; + svr_loop[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i); + svr_loop[i].sin_port = htons(SCTP_TESTPORT_1); + svr_test[i].v4.sin_family = AF_INET; + svr_test[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i); + svr_test[i].v4.sin_port = htons(SCTP_TESTPORT_1); + svr_try[i].sin_family = AF_INET; + if (i < (NUMADDR-1)) { + svr_try[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i); + } else { + /* Make last address invalid. */ + svr_try[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x400); + } + svr_try[i].sin_port = htons(SCTP_TESTPORT_1); + clt_loop1[i].sin_family = AF_INET; + clt_loop1[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x100); + clt_loop1[i].sin_port = htons(SCTP_TESTPORT_2); + clt_test1[i].v4.sin_family = AF_INET; + clt_test1[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x100); + clt_test1[i].v4.sin_port = htons(SCTP_TESTPORT_2); + clt_loop2[i].sin_family = AF_INET; + clt_loop2[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x200); + clt_loop2[i].sin_port = htons(SCTP_TESTPORT_2+1); + clt_test2[i].v4.sin_family = AF_INET; + clt_test2[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x200); + clt_test2[i].v4.sin_port = htons(SCTP_TESTPORT_2+1); + clt_loop3[i].sin_family = AF_INET; + clt_loop3[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x300); + clt_loop3[i].sin_port = htons(SCTP_TESTPORT_2+2); + } + + /* Create and bind the server socket. */ + svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + test_bind(svr_sk, (struct sockaddr *)&svr_loop[0], sizeof(svr_loop[0])); + test_bindx_add(svr_sk, (struct sockaddr *)&svr_loop[1], NUMADDR-1); + + /* Mark server socket as being able to accept new associations. */ + test_listen(svr_sk, 1); + + /* Create and bind the client sockets. */ + clt_sk1 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + test_bind(clt_sk1, (struct sockaddr *)&clt_loop1[0], sizeof(clt_loop1)); + test_bindx_add(clt_sk1, (struct sockaddr *)&clt_loop1[1], NUMADDR-1); + clt_sk2 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + test_bind(clt_sk2, (struct sockaddr *)&clt_loop2[0], sizeof(clt_loop2)); + test_bindx_add(clt_sk2, (struct sockaddr *)&clt_loop2[1], NUMADDR-1); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(svr_sk); + test_enable_assoc_change(clt_sk1); + test_enable_assoc_change(clt_sk2); + + /* Set clt_sk1 as non-blocking. */ + flags = fcntl(clt_sk1, F_GETFL, 0); + if (flags < 0) + tst_brkm(TBROK, tst_exit, "fcntl F_GETFL: %s", strerror(errno)); + if (fcntl(clt_sk1, F_SETFL, flags | O_NONBLOCK) < 0) + tst_brkm(TBROK, tst_exit, "fcntl F_SETFL: %s", strerror(errno)); + + /* Do a non-blocking connectx from clt_sk1 to svr_sk */ + error = sctp_connectx(clt_sk1, (struct sockaddr *)svr_try, NUMADDR, + &associd); + /* Non-blocking connectx should return immediately with EINPROGRESS. */ + if ((error != -1) || (EINPROGRESS != errno)) + tst_brkm(TBROK, tst_exit, "non-blocking connectx error: %d" + "errno:%d", error, errno); + + tst_resm(TPASS, "non-blocking connectx"); + + /* Doing a connectx on a socket to create an association that is + * is already established should return EISCONN. + */ + error = sctp_connectx(clt_sk1, (struct sockaddr *)svr_try, NUMADDR, + NULL); + if ((error != -1) || (EISCONN != errno)) + tst_brkm(TBROK, tst_exit, "connectx on a socket to create an " + "assoc that is already established error:%d errno:%d", + error, errno); + + tst_resm(TPASS, "connectx on a socket to create an assoc that is " + "already established"); + + /* Initialize inmessage for all receives. */ + memset(&inmessage, 0, sizeof(inmessage)); + big_buffer = test_malloc(REALLY_BIG); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = NULL; + + /* Get COMM_UP on clt_sk1 */ + error = test_recvmsg(clt_sk1, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + clt_associd1 = sac->sac_assoc_id; + + if (associd) { + if (associd != clt_associd1) + tst_brkm(TBROK, tst_exit, "Association id mismatch: " + "connectx returned %d, notification returned:%d", + associd, clt_associd1); + tst_resm(TPASS, "Association id match between sctp_connectx()" + " and notification."); + } + + /* Get COMM_UP on svr_sk */ + error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + svr_associd1 = sac->sac_assoc_id; + + /* Do a blocking connectx from clt_sk2 to svr_sk. + * Blocking connectx should block until the association is established + * and return success. + */ + test_connectx(clt_sk2, (struct sockaddr *)svr_try, NUMADDR); + + /* Get COMM_UP on clt_sk2 */ + error = test_recvmsg(clt_sk2, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + clt_associd2 = sac->sac_assoc_id; + + /* Get COMM_UP on svr_sk */ + error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + svr_associd2 = sac->sac_assoc_id; + + tst_resm(TPASS, "blocking connectx"); + + peeloff_sk = test_sctp_peeloff(svr_sk, svr_associd1); + + /* Doing a connectx on a peeled off socket should fail. */ + error = sctp_connectx(peeloff_sk, (struct sockaddr *)clt_loop3, NUMADDR, + NULL); + if ((error != -1) || (EISCONN != errno)) + tst_brkm(TBROK, tst_exit, "connectx on a peeled off socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "connectx on a peeled off socket"); + + /* Trying to create an association on a socket that matches an + * existing peeled-off association should fail. + */ + error = sctp_connectx(svr_sk, (struct sockaddr *)clt_loop1, NUMADDR, + NULL); + if ((error != -1) || (EADDRNOTAVAIL != errno)) + tst_brkm(TBROK, tst_exit, "connectx to create an assoc that " + "matches a peeled off assoc error:%d errno:%d", + error, errno); + + tst_resm(TPASS, "connectx to create an assoc that matches a peeled off " + "assoc"); + + test_peer_addr(peeloff_sk, svr_associd1, clt_test1, NUMADDR); + tst_resm(TPASS, "server association 1 peers ok"); + test_peer_addr(svr_sk, svr_associd2, clt_test2, NUMADDR); + tst_resm(TPASS, "server association 2 peers ok"); + test_peer_addr(clt_sk1, clt_associd1, svr_test, NUMADDR); + tst_resm(TPASS, "client association 1 peers ok"); + test_peer_addr(clt_sk2, clt_associd2, svr_test, NUMADDR); + tst_resm(TPASS, "client association 2 peers ok"); + close(svr_sk); + close(clt_sk1); + close(clt_sk2); + close(peeloff_sk); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_fragments.c b/src/func_tests/test_fragments.c new file mode 100644 index 0000000..15aba6f --- /dev/null +++ b/src/func_tests/test_fragments.c @@ -0,0 +1,300 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2001, 2003 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2001 Intel Corp. + * Copyright (c) 2001 Nokia, Inc. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * La Monte H.P. Yarroll + * Karl Knutson + * Hui Huang + * Jon Grimm + * Sridhar Samudrala + */ + +/* This is a functional test to verify the data fragmentation, reassembly + * support and SCTP_DISABLE_FRAGMENTS socket option. + * The following tests are done in sequence. + * - Verify SCTP_DISABLE_FRAGMENTS socket option by doing a setsockopt() + * followed by a getsockopt(). + * - Verify that a message size exceeding the association fragmentation + * point cannot be sent when fragmentation is disabled. + * - Send and receive a set of messages that are bigger than the path mtu. + * The different message sizes to be tested are specified in the array + * msg_sizes[]. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 4; +int TST_CNT = 0; + +int msg_sizes[] = {1353, 2000, 5000, 10000, 20000, 32768}; + +int +main(int argc, char *argv[]) +{ + int sk1, sk2; + sockaddr_storage_t loop1; + sockaddr_storage_t loop2; + struct iovec iov; + struct msghdr inmessage; + struct msghdr outmessage; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + struct iovec out_iov; + int error, bytes_sent; + int pf_class, af_family; + uint32_t ppid; + uint32_t stream; + sctp_assoc_t associd1, associd2; + struct sctp_assoc_change *sac; + char *big_buffer; + int msg_len, msg_cnt, i; + void *msg_buf; + int disable_frag; + socklen_t optlen; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Set some basic values which depend on the address family. */ +#if TEST_V6 + pf_class = PF_INET6; + af_family = AF_INET6; + + loop1.v6.sin6_family = AF_INET6; + loop1.v6.sin6_addr = in6addr_loopback; + loop1.v6.sin6_port = htons(SCTP_TESTPORT_1); + + loop2.v6.sin6_family = AF_INET6; + loop2.v6.sin6_addr = in6addr_loopback; + loop2.v6.sin6_port = htons(SCTP_TESTPORT_2); +#else + pf_class = PF_INET; + af_family = AF_INET; + + loop1.v4.sin_family = AF_INET; + loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + loop1.v4.sin_port = htons(SCTP_TESTPORT_1); + + loop2.v4.sin_family = AF_INET; + loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + loop2.v4.sin_port = htons(SCTP_TESTPORT_2); +#endif /* TEST_V6 */ + + /* Create the two endpoints which will talk to each other. */ + sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(sk1); + test_enable_assoc_change(sk2); + + /* Bind these sockets to the test ports. */ + test_bind(sk1, &loop1.sa, sizeof(loop1)); + test_bind(sk2, &loop2.sa, sizeof(loop2)); + + /* Mark sk2 as being able to accept new associations. */ + test_listen(sk2, 1); + + /* Send the first message. This will create the association. */ + outmessage.msg_name = &loop2; + outmessage.msg_namelen = sizeof(loop2); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid = rand(); /* Choose an arbitrary value. */ + stream = 1; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + msg_len = 10; + msg_buf = test_build_msg(10); + outmessage.msg_iov->iov_base = msg_buf; + outmessage.msg_iov->iov_len = msg_len; + test_sendmsg(sk1, &outmessage, 0, msg_len); + + + /* Initialize inmessage for all receives. */ + big_buffer = test_malloc(REALLY_BIG); + memset(&inmessage, 0, sizeof(inmessage)); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + + /* Get the communication up message on sk2. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + associd2 = sac->sac_assoc_id; + + /* Get the communication up message on sk1. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk1, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + associd1 = sac->sac_assoc_id; + + /* Get the first message which was sent. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, msg_len, MSG_EOR, stream, ppid); + + free(msg_buf); + + /* Disable fragmentation. */ + disable_frag = 1; + test_setsockopt(sk1, SCTP_DISABLE_FRAGMENTS, &disable_frag, + sizeof(disable_frag)); + + tst_resm(TPASS, "setsockopt(SCTP_DISABLE_FRAGMENTS)"); + + /* Do a getsockopt() and verify that fragmentation is disabled. */ + disable_frag = 0; + optlen = sizeof(disable_frag); + error = test_getsockopt(sk1, SCTP_DISABLE_FRAGMENTS, &disable_frag, + &optlen); + if ((error != 0) && (disable_frag != 1)) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DISABLE_FRAGMENTS) " + "error:%d errno:%d disable_frag:%d", + error, errno, disable_frag); + + tst_resm(TPASS, "getsockopt(SCTP_DISABLE_FRAGMENTS)"); + + /* Try to send a messsage that exceeds association fragmentation point + * and verify that it fails. + */ + msg_len = 30000; + msg_buf = test_build_msg(msg_len); + outmessage.msg_iov->iov_base = msg_buf; + outmessage.msg_iov->iov_len = msg_len; + error = sendmsg(sk1, &outmessage, 0); + if ((error != -1) || (errno != EMSGSIZE)) + tst_brkm(TBROK, tst_exit, "Send a message that exceeds " + "assoc frag point error:%d errno:%d", error, errno); + + tst_resm(TPASS, "Send a message that exceeds assoc frag point"); + + /* Enable Fragmentation. */ + disable_frag = 0; + test_setsockopt(sk1, SCTP_DISABLE_FRAGMENTS, &disable_frag, + sizeof(disable_frag)); + + msg_cnt = sizeof(msg_sizes) / sizeof(int); + + /* Send and receive the messages of different sizes specified in the + * msg_sizes array in a loop. + */ + for (i = 0; i < msg_cnt; i++) { + + msg_len = msg_sizes[i]; + msg_buf = test_build_msg(msg_len); + outmessage.msg_iov->iov_base = msg_buf; + outmessage.msg_iov->iov_len = msg_len; + bytes_sent = test_sendmsg(sk1, &outmessage, 0, msg_len); + + tst_resm(TINFO, "Sent %d byte message", bytes_sent); + + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + /* Handle Partial Reads. */ + if (inmessage.msg_flags & MSG_EOR) { + test_check_msg_data(&inmessage, error, bytes_sent, + MSG_EOR, stream, ppid); + tst_resm(TINFO, "Received %d byte message", error); + } else { + int remain; + + test_check_msg_data(&inmessage, error, error, 0, + stream, ppid); + tst_resm(TINFO, "Received %d byte message", error); + + /* Read the remaining message. */ + inmessage.msg_controllen = sizeof(incmsg); + remain = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, remain, + bytes_sent - error, + MSG_EOR, stream, ppid); + tst_resm(TINFO, "Received %d byte message", error); + } + + free(msg_buf); + } + + tst_resm(TPASS, "Send/Receive fragmented messages"); + + /* Shut down the link. */ + close(sk1); + + /* Get the shutdown complete notification. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP); + + close(sk2); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_getname.c b/src/func_tests/test_getname.c new file mode 100644 index 0000000..d7011f6 --- /dev/null +++ b/src/func_tests/test_getname.c @@ -0,0 +1,258 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2004 + * Copyright (c) 1999-2001 Motorola, Inc. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Sridhar Samudrala + */ + +/* This is a kernel test to verify getsockname() and getpeername() interfaces + * for single-homed one-to-one style sockets. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 13; +int TST_CNT = 0; + +#define MAX_CLIENTS 10 + +int +main(int argc, char *argv[]) +{ + int clt_sk, svr_sk, accept_sk; + sockaddr_storage_t svr_loop, accept_loop; + sockaddr_storage_t svr_local_addr, svr_peer_addr; + sockaddr_storage_t clt_local_addr, clt_peer_addr; + socklen_t len; + int error; + int pf_class; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Initialize the server and client addresses. */ +#if TEST_V6 + pf_class = PF_INET6; + svr_loop.v6.sin6_family = AF_INET6; + svr_loop.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_ANY_INIT; + svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1); +#else + pf_class = PF_INET; + svr_loop.v4.sin_family = AF_INET; + svr_loop.v4.sin_addr.s_addr = INADDR_ANY; + svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1); +#endif + + /* Create and bind the listening server socket. */ + svr_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop)); + + bzero(&svr_local_addr, sizeof(svr_local_addr)); + len = sizeof(svr_local_addr); + /* Verify that getsockname() on an unconnected socket works fine. */ + error = getsockname(svr_sk, (struct sockaddr *)&svr_local_addr, &len); + if (0 != error) + tst_brkm(TBROK, tst_exit, "getsockname: %s", strerror(errno)); + + tst_resm(TPASS, "getsockname on an unconnected socket"); + + bzero(&svr_peer_addr, sizeof(svr_peer_addr)); + len = sizeof(svr_peer_addr); + /* Verify that getpeername() on an unconnected socket fails. */ + error = getpeername(svr_sk, (struct sockaddr *)&svr_peer_addr, &len); + if ((-1 != error) || (ENOTCONN != errno)) + tst_brkm(TBROK, tst_exit, "getpeername on an unconnected " + "socket error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "getpeername on an unconnected socket"); + + /* Mark svr_sk as being able to accept new associations. */ + test_listen(svr_sk, 5); + + /* Create the client socket. */ + clt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /* Do a blocking connect from clt_sk to svr_sk */ +#if TEST_V6 + svr_loop.v6.sin6_addr = in6addr_loopback; +#else + svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; +#endif + test_connect(clt_sk, &svr_loop.sa, sizeof(svr_loop)); + + bzero(&clt_local_addr, sizeof(clt_local_addr)); + len = sizeof(clt_local_addr); + /* Get the client's local address. */ + error = getsockname(clt_sk, (struct sockaddr *)&clt_local_addr, &len); + if (0 != error) + tst_brkm(TBROK, tst_exit, "getsockname on a connected client " + "socket: %s", strerror(errno)); + + tst_resm(TPASS, "getsockname on a connected client socket"); + + bzero(&clt_peer_addr, sizeof(clt_peer_addr)); + len = sizeof(clt_peer_addr); + /* Get the client's peer address. */ + error = getpeername(clt_sk, (struct sockaddr *)&clt_peer_addr, &len); + if (0 != error) + tst_brkm(TBROK, tst_exit, "getpeername on a connected client " + "socket: %s", strerror(errno)); + + tst_resm(TPASS, "getpeername on a connected client socket"); + + /* Extract the association on the listening socket as a new socket. */ + len = sizeof(accept_loop); + accept_sk = test_accept(svr_sk, &accept_loop.sa, &len); + + bzero(&svr_local_addr, sizeof(svr_local_addr)); + len = sizeof(svr_local_addr); + /* Get the server's local address. */ + error = getsockname(accept_sk, (struct sockaddr *)&svr_local_addr, + &len); + if (0 != error) + tst_brkm(TBROK, tst_exit, "getsockname on a connected server " + "socket: %s", strerror(errno)); + + tst_resm(TPASS, "getsockname on a connected server socket"); + + bzero(&svr_peer_addr, sizeof(svr_peer_addr)); + len = sizeof(svr_peer_addr); + /* Get the server's peer address. */ + error = getpeername(accept_sk, (struct sockaddr *)&svr_peer_addr, + &len); + if (0 != error) + tst_brkm(TBROK, tst_exit, "getpeername on a connected server " + "socket: %s", strerror(errno)); + + tst_resm(TPASS, "getpeername on a connected server socket"); + + if (svr_local_addr.v4.sin_port != clt_peer_addr.v4.sin_port) + tst_brkm(TBROK, tst_exit, "Server's local port(%d) doesn't " + "match Client's peer port(%d)\n", + svr_local_addr.v4.sin_port, clt_peer_addr.v4.sin_port); + + if (svr_peer_addr.v4.sin_port != clt_local_addr.v4.sin_port) + tst_brkm(TBROK, tst_exit, "Server's peer port(%d) doesn't " + "match Client's local port(%d)\n", + svr_peer_addr.v4.sin_port, clt_local_addr.v4.sin_port); +#if TEST_V6 + if (memcmp(&svr_local_addr, &clt_peer_addr, len) != 0) + tst_brkm(TBROK, tst_exit, "Server's local address and client's " + "peer addresses do not match\n"); + + if (memcmp(&svr_peer_addr, &clt_local_addr, len) != 0) + tst_brkm(TBROK, tst_exit, "Server's peer address and client's " + "local addresses do not match\n"); +#else + if (svr_local_addr.v4.sin_addr.s_addr != + clt_peer_addr.v4.sin_addr.s_addr) + tst_brkm(TBROK, tst_exit, "Server's local address and client's " + "peer addresses do not match\n"); + if (svr_peer_addr.v4.sin_addr.s_addr != + clt_local_addr.v4.sin_addr.s_addr) + tst_brkm(TBROK, tst_exit, "Server's peer address and client's " + "local addresses do not match\n"); +#endif + tst_resm(TPASS, "getsockname/getpeername server/client match"); + + bzero(&clt_local_addr, sizeof(clt_local_addr)); + len = sizeof(clt_local_addr); + /*getsockname(): Bad socket descriptor, EBADF expected error*/ + error = getsockname(-1, (struct sockaddr *)&clt_local_addr, &len); + if (error != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "getsockname on a bad socket " + "descriptor. error:%d errno:%d", error, errno); + + tst_resm(TPASS, "getsockname on a bad socket descriptor - EBADF"); + + /*getsockname(): Invalid socket, ENOTSOCK expected error*/ + error = getsockname(0, (struct sockaddr *)&clt_local_addr, &len); + if (error != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "getsockname on an invalid socket " + "error:%d errno:%d", error, errno); + + tst_resm(TPASS, "getsockname on an invalid socket - ENOTSOCK"); + + /*getsockname(): Invalid structure, EFAULT expected error*/ + error = getsockname(clt_sk, (struct sockaddr *)-1, &len); + if (error != -1 || errno != EFAULT) + tst_brkm(TBROK, tst_exit, "getsockname with invalid buffer " + "error:%d errno:%d", error, errno); + + tst_resm(TPASS, "getsockname with invalid buffer - EFAULT"); + + bzero(&clt_peer_addr, sizeof(clt_peer_addr)); + len = sizeof(clt_peer_addr); + /*getpeername(): Bad socket descriptor, EBADF expected error*/ + error = getpeername(-1, (struct sockaddr *)&clt_local_addr, &len); + if (error != -1 || errno != EBADF) + tst_brkm(TBROK, tst_exit, "getpeername on a bad socket " + "descriptor. error:%d errno:%d", error, errno); + + tst_resm(TPASS, "getpeername on a bad socket descriptor - EBADF"); + + /*getpeername(): Invalid socket, ENOTSOCK expected error*/ + error = getpeername(0, (struct sockaddr *)&clt_local_addr, &len); + if (error != -1 || errno != ENOTSOCK) + tst_brkm(TBROK, tst_exit, "getpeername on an invalid socket " + "error:%d errno:%d", error, errno); + + tst_resm(TPASS, "getpeername on an invalid socket - ENOTSOCK"); + + /*getpeername(): Invalid structure, EFAULT expected error*/ + error = getpeername(clt_sk, (struct sockaddr *)-1, &len); + if (error != -1 || errno != EFAULT) + tst_brkm(TBROK, tst_exit, "getpeername with invalid buffer " + "error:%d errno:%d", error, errno); + + tst_resm(TPASS, "getpeername with invalid buffer - EFAULT"); + + close(clt_sk); + close(svr_sk); + close(accept_sk); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_inaddr_any.c b/src/func_tests/test_inaddr_any.c new file mode 100644 index 0000000..29e8e6d --- /dev/null +++ b/src/func_tests/test_inaddr_any.c @@ -0,0 +1,253 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2002, 2003 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2001 Intel Corp. + * Copyright (c) 2001 Nokia, Inc. + * Copyright (c) 2001 La Monte H.P. Yarroll + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * La Monte H.P. Yarroll + * Karl Knutson + * Jon Grimm + * Sridhar Samudrala + * Daisy Chang + */ + +/* This is a functional test to verify binding a socket with INADDRY_ANY + * address and send messages. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 2; +int TST_CNT = 0; + +int +main(void) +{ + int sk1, sk2; + sockaddr_storage_t loop; + sockaddr_storage_t anyaddr; + struct msghdr outmessage; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + struct iovec out_iov; + struct iovec iov; + struct msghdr inmessage; + char *message = "hello, world!\n"; + char *telephone = "Watson, come here! I need you!\n"; + char *telephone_resp = "I already brought your coffee...\n"; + int error; + int pf_class, af_family; + uint32_t ppid; + uint32_t stream; + socklen_t namelen; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Set some basic values which depend on the address family. */ +#if TEST_V6 + pf_class = PF_INET6; + af_family = AF_INET6; + + loop.v6.sin6_family = AF_INET6; + loop.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_LOOPBACK_INIT; + loop.v6.sin6_port = 0; + + anyaddr.v6.sin6_family = AF_INET6; + anyaddr.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_ANY_INIT; + anyaddr.v6.sin6_port = 0; +#else + pf_class = PF_INET; + af_family = AF_INET; + + loop.v4.sin_family = AF_INET; + loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + loop.v4.sin_port = 0; + + anyaddr.v4.sin_family = AF_INET; + anyaddr.v4.sin_addr.s_addr = INADDR_ANY; + anyaddr.v4.sin_port = 0; +#endif /* TEST_V6 */ + + /* Create the two endpoints which will talk to each other. */ + sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(sk1); + test_enable_assoc_change(sk2); + + /* Bind these sockets to the test ports. */ + test_bind(sk1, &loop.sa, sizeof(loop)); + test_bind(sk2, &anyaddr.sa, sizeof(anyaddr)); + + tst_resm(TPASS, "bind INADDR_ANY address"); + + /* Mark sk2 as being able to accept new associations */ + test_listen(sk2, 1); + + /* Now use getsockaname() to retrieve the ephmeral ports. */ + namelen = sizeof(loop); + error = getsockname(sk1, &loop.sa, &namelen); + if (error != 0) + tst_brkm(TBROK, tst_exit, "getsockname: %s", strerror(errno)); + + namelen = sizeof(anyaddr); + error = getsockname(sk2, &anyaddr.sa, &namelen); + if (error != 0) + tst_brkm(TBROK, tst_exit, "getsockname: %s", strerror(errno)); + +#if TEST_V6 + loop.v6.sin6_port = anyaddr.v6.sin6_port; +#else + loop.v4.sin_port = anyaddr.v4.sin_port; +#endif + + /* Send the first message. This will create the association. */ + outmessage.msg_name = &loop; + outmessage.msg_namelen = sizeof(loop); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid = rand(); /* Choose an arbitrary value. */ + stream = 1; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + outmessage.msg_iov->iov_base = message; + outmessage.msg_iov->iov_len = strlen(message) + 1; + test_sendmsg(sk1, &outmessage, 0, strlen(message)+1); + + /* Initialize inmessage for all receives. */ + memset(&inmessage, 0, sizeof(inmessage)); + iov.iov_base = test_malloc(REALLY_BIG); + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + + /* Get the communication up message on sk2. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + + /* Get the communication up message on sk1. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk1, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + + /* Get the first message which was sent. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(message) + 1, + MSG_EOR, stream, ppid); + + /* Send 2 messages. */ + outmessage.msg_name = &loop; + outmessage.msg_namelen = sizeof(loop); + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid++; + stream++; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + outmessage.msg_iov->iov_base = telephone; + outmessage.msg_iov->iov_len = strlen(telephone) + 1; + test_sendmsg(sk1, &outmessage, 0, strlen(telephone)+1); + + outmessage.msg_iov->iov_base = telephone_resp; + outmessage.msg_iov->iov_len = strlen(telephone_resp) + 1; + test_sendmsg(sk1, &outmessage, 0, strlen(telephone_resp)+1); + + /* Get those two messages. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(telephone) + 1, + MSG_EOR, stream, ppid); + + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(telephone_resp) + 1, + MSG_EOR, stream, ppid); + + /* Shut down the link. */ + close(sk1); + + /* Get the shutdown complete notification. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP); + + close(sk2); + + tst_resm(TPASS, "send msgs from a socket with INADDR_ANY bind address"); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_peeloff.c b/src/func_tests/test_peeloff.c new file mode 100644 index 0000000..5e38a12 --- /dev/null +++ b/src/func_tests/test_peeloff.c @@ -0,0 +1,297 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2001, 2003 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2001 Intel Corp. + * Copyright (c) 2001 Nokia, Inc. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Sridhar Samudrala + */ + +/* This is a Functional test to verify the new SCTP interface sctp_peeloff() + * that can be used to branch off an association into a separate socket. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 6; +int TST_CNT = 0; + +#define MAX_CLIENTS 10 + +int +main(int argc, char *argv[]) +{ + int svr_sk, clt_sk[MAX_CLIENTS], peeloff_sk[MAX_CLIENTS]; + sctp_assoc_t svr_associd[MAX_CLIENTS], clt_associd[MAX_CLIENTS]; + sockaddr_storage_t svr_loop, clt_loop[MAX_CLIENTS]; + struct iovec iov; + struct msghdr inmessage; + struct msghdr outmessage; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + struct iovec out_iov; + int error; + uint32_t ppid; + uint32_t stream; + struct sctp_assoc_change *sac; + char *big_buffer; + int i; + char *message = "hello, world!\n"; + int pf_class; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + +#if TEST_V6 + pf_class = PF_INET6; + svr_loop.v6.sin6_family = AF_INET6; + svr_loop.v6.sin6_addr = in6addr_loopback; + svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1); +#else + pf_class = PF_INET; + svr_loop.v4.sin_family = AF_INET; + svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1); +#endif + + /* Create and bind the server socket. */ + svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop)); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(svr_sk); + + /* Mark server socket as being able to accept new associations. */ + test_listen(svr_sk, 1); + + /* Create and bind all the client sockets. */ + for (i = 0; i < MAX_CLIENTS; i++) { + clt_sk[i] = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); +#if TEST_V6 + clt_loop[i].v6.sin6_family = AF_INET6; + clt_loop[i].v6.sin6_addr = in6addr_loopback; + clt_loop[i].v6.sin6_port = htons(SCTP_TESTPORT_2 + i); +#else + clt_loop[i].v4.sin_family = AF_INET; + clt_loop[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + clt_loop[i].v4.sin_port = htons(SCTP_TESTPORT_2 + i); +#endif + test_bind(clt_sk[i], &clt_loop[i].sa, sizeof(clt_loop[i])); + + test_enable_assoc_change(clt_sk[i]); + } + + /* Send the first message from all the clients to the server. This + * will create the associations. + */ + outmessage.msg_name = &svr_loop; + outmessage.msg_namelen = sizeof(svr_loop); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid = rand(); /* Choose an arbitrary value. */ + stream = 1; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + outmessage.msg_iov->iov_base = message; + outmessage.msg_iov->iov_len = strlen(message) + 1; + for (i = 0; i < MAX_CLIENTS; i++) + test_sendmsg(clt_sk[i], &outmessage, 0, + strlen(message)+1); + + /* Initialize inmessage for all receives. */ + big_buffer = test_malloc(REALLY_BIG); + memset(&inmessage, 0, sizeof(inmessage)); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + + /* Get the communication up message on all client sockets. */ + for (i = 0; i < MAX_CLIENTS; i++) { + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + clt_associd[i] = sac->sac_assoc_id; + } + + /* Get the communication up message and the data message on the + * server sockets for all the clients. + */ + for (i = 0; i < MAX_CLIENTS; i++) { + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + svr_associd[i] = sac->sac_assoc_id; + + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(message) + 1, + MSG_EOR, stream, ppid); + } + + /* Branch off all the associations on the server socket to separate + * individual sockets. + */ + for (i = 0; i < MAX_CLIENTS; i++) + peeloff_sk[i] = test_sctp_peeloff(svr_sk, svr_associd[i]); + + tst_resm(TPASS, "sctp_peeloff"); + + errno = 0; + /* Verify that a peeled off socket is not allowed to do a listen(). */ + error = listen(peeloff_sk[0], 1); + if (error != -1) + tst_brkm(TBROK, tst_exit, "listen on a peeled off socket " + "error: %d, errno: %d", error, errno); + + tst_resm(TPASS, "listen on a peeled off socket"); + + errno = 0; + /* Verify that an association cannot be branched off an already + * peeled-off socket. + */ + if ((-1 != sctp_peeloff(peeloff_sk[0], svr_associd[0])) || + (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "sctp_peeloff on a peeled off " + "socket error:%d, errno:%d", + error, errno); + + tst_resm(TPASS, "sctp_peeloff on a peeled off socket"); + + /* Send a message from all the client sockets to the server socket. */ + for (i = 0; i < MAX_CLIENTS; i++) + test_sendmsg(clt_sk[i], &outmessage, 0, strlen(message)+1); + + /* Receive the sent messages on the peeled off server sockets. */ + for (i = 0; i < MAX_CLIENTS; i++) { + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(peeloff_sk[i], &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(message) + 1, + MSG_EOR, stream, ppid); + } + + tst_resm(TPASS, "Receive msgs on peeled off sockets"); + + /* Send a message from all the peeled off server sockets to the client + * sockets. + */ + for (i = 0; i < MAX_CLIENTS; i++) { + outmessage.msg_name = &clt_loop[i]; + outmessage.msg_namelen = sizeof(clt_loop[i]); + test_sendmsg(peeloff_sk[i], &outmessage, 0, strlen(message)+1); + } + + /* Receive the messages sent from the peeled of server sockets on + * the client sockets. + */ + for (i = 0; i < MAX_CLIENTS; i++) { + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(message) + 1, + MSG_EOR, stream, ppid); + } + + tst_resm(TPASS, "Send msgs on peeled off sockets"); + + errno = 0; + /* Verify that a peeled-off socket cannot initialize a new + * association by trying to send a message to a client that is not + * associated with the peeled-off socket. + * The message is sent to the client that is associated with the + * socket. + */ + outmessage.msg_name = &clt_loop[1]; + outmessage.msg_namelen = sizeof(clt_loop[1]); + test_sendmsg(peeloff_sk[0], &outmessage, 0, strlen(message)+1); + + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(clt_sk[0], &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(message) + 1, + MSG_EOR, stream, ppid); + + tst_resm(TPASS, "peeled off socket cannot initialize a new assoc"); + + close(svr_sk); + + /* Close all the peeled off server sockets. */ + for (i = 0; i < MAX_CLIENTS; i++) + close(peeloff_sk[i]); + + /* Get the shutdown complete notification from all the client + * sockets. + */ + for (i = 0; i < MAX_CLIENTS; i++) { + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, + SCTP_SHUTDOWN_COMP); + + close(clt_sk[i]); + } + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_recvmsg.c b/src/func_tests/test_recvmsg.c new file mode 100644 index 0000000..b16cceb --- /dev/null +++ b/src/func_tests/test_recvmsg.c @@ -0,0 +1,160 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2002, 2003 + * Copyright (c) 1999-2001 Motorola, Inc. + * + * This file is part of the SCTP kernel Implementation + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Written or modified by: + * Sridhar Samudrala + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + */ + +/* This is a kernel test to verify + * 1. MSG_EOR flag is set correctly when a single message is read using multiple + * recvmsg() calls. + * 2. MSG_PEEK support. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 2; +int TST_CNT = 0; + +int +main(int argc, char *argv[]) +{ + int svr_sk, clt_sk; + struct sockaddr_in svr_loop, clt_loop; + struct iovec iov, out_iov; + struct msghdr inmessage, outmessage; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + int error, msglen, i; + char *big_buffer; + void *msg_buf; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Initialize the server and client addresses. */ + svr_loop.sin_family = AF_INET; + svr_loop.sin_addr.s_addr = SCTP_IP_LOOPBACK; + svr_loop.sin_port = htons(SCTP_TESTPORT_1); + clt_loop.sin_family = AF_INET; + clt_loop.sin_addr.s_addr = SCTP_IP_LOOPBACK; + clt_loop.sin_port = htons(SCTP_TESTPORT_2); + + /* Create and bind the server socket. */ + svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + test_bind(svr_sk, (struct sockaddr *)&svr_loop, sizeof(svr_loop)); + + /* Mark server socket as being able to accept new associations. */ + test_listen(svr_sk, 1); + + /* Create and bind the client sockets. */ + clt_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + test_bind(clt_sk, (struct sockaddr *)&clt_loop, sizeof(clt_loop)); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(svr_sk); + test_enable_assoc_change(clt_sk); + + /* Send a message. This will create the association. */ + memset(&outmessage, 0, sizeof(outmessage)); + outmessage.msg_name = &svr_loop; + outmessage.msg_namelen = sizeof(svr_loop); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + msg_buf = test_build_msg(30000); + outmessage.msg_iov->iov_base = msg_buf; + outmessage.msg_iov->iov_len = 30000; + test_sendmsg(clt_sk, &outmessage, 0, 30000); + + /* Initialize inmessage for all receives. */ + big_buffer = test_malloc(REALLY_BIG); + memset(&inmessage, 0, sizeof(inmessage)); + iov.iov_base = big_buffer; + iov.iov_len = 2000; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + + /* Receive COMM_UP on clt_sk. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(clt_sk, &inmessage, 0); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + + /* Receive COMM_UP on svr_sk. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + + /* Read the 30000 byte message using multiple recvmsg() calls in a + * loop with 2000 bytes per read. + */ + for (i = 0, msglen = 30000; i < 15; i++, msglen-=2000) { + iov.iov_len = REALLY_BIG; + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(svr_sk, &inmessage, MSG_PEEK); + test_check_msg_data(&inmessage, error, msglen, + MSG_EOR, 0, 0); + + iov.iov_len = 2000; + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, 2000, + ((i==14)?MSG_EOR:0), 0, 0); + } + + tst_resm(TPASS, "recvmsg with MSG_PEEK flag"); + tst_resm(TPASS, "MSG_EOR in msg_flags set correctly"); + + close(svr_sk); + close(clt_sk); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_sctp_sendrecvmsg.c b/src/func_tests/test_sctp_sendrecvmsg.c new file mode 100644 index 0000000..c275e45 --- /dev/null +++ b/src/func_tests/test_sctp_sendrecvmsg.c @@ -0,0 +1,371 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2003 + * Copyright (c) 2003 Intel Corp. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * To compile the v6 version, set the symbol TEST_V6 to 1. + * + * Written or modified by: + * Ardelle Fan + * Sridhar Samudrala + */ + +/* This is a basic functional test for the SCTP new library APIs + * sctp_sendmsg() and sctp_recvmsg(). test_timetolive.c is rewritten using + * these new APIs. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 10; +int TST_CNT = 0; + +/* RCVBUF value, and indirectly RWND*2 */ +#define SMALL_RCVBUF 3000 +#define SMALL_MAXSEG 100 +/* This is extra data length to ensure rwnd closes */ +#define RWND_SLOP 100 +static char *fillmsg = NULL; +static char *ttlmsg = "This should time out!\n"; +static char *nottlmsg = "This should NOT time out!\n"; +static char ttlfrag[SMALL_MAXSEG*3] = {0}; +static char *message = "Hello world\n"; + +int main(int argc, char *argv[]) +{ + int sk1, sk2; + sockaddr_storage_t loop1; + sockaddr_storage_t loop2; + sockaddr_storage_t msgname; + int error; + int pf_class, af_family; + uint32_t ppid; + uint32_t stream; + struct sctp_event_subscribe subscribe; + char *big_buffer; + int offset, msg_flags; + socklen_t msgname_len; + size_t buflen; + struct sctp_send_failed *ssf; + struct sctp_sndrcvinfo sinfo; + struct sctp_sndrcvinfo snd_sinfo; + sctp_assoc_t associd1, associd2; + int len, oldlen; + struct sctp_status gstatus; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Set some basic values which depend on the address family. */ +#if TEST_V6 + pf_class = PF_INET6; + af_family = AF_INET6; + + loop1.v6.sin6_family = AF_INET6; + loop1.v6.sin6_addr = in6addr_loopback; + loop1.v6.sin6_port = htons(SCTP_TESTPORT_1); + + loop2.v6.sin6_family = AF_INET6; + loop2.v6.sin6_addr = in6addr_loopback; + loop2.v6.sin6_port = htons(SCTP_TESTPORT_2); +#else + pf_class = PF_INET; + af_family = AF_INET; + + loop1.v4.sin_family = AF_INET; + loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + loop1.v4.sin_port = htons(SCTP_TESTPORT_1); + + loop2.v4.sin_family = AF_INET; + loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + loop2.v4.sin_port = htons(SCTP_TESTPORT_2); +#endif /* TEST_V6 */ + + /* Create the two endpoints which will talk to each other. */ + sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + + /* Set the MAXSEG to something smallish. */ + { + int val = SMALL_MAXSEG; + test_setsockopt(sk1, SCTP_MAXSEG, &val, sizeof(val)); + } + + memset(&subscribe, 0, sizeof(subscribe)); + subscribe.sctp_data_io_event = 1; + subscribe.sctp_association_event = 1; + subscribe.sctp_send_failure_event = 1; + test_setsockopt(sk1, SCTP_EVENTS, &subscribe, sizeof(subscribe)); + test_setsockopt(sk2, SCTP_EVENTS, &subscribe, sizeof(subscribe)); + + /* Bind these sockets to the test ports. */ + test_bind(sk1, &loop1.sa, sizeof(loop1)); + test_bind(sk2, &loop2.sa, sizeof(loop2)); + + /* + * Set the RWND small so we can fill it up easily. + * then reset RCVBUF to avoid frame droppage + */ + len = sizeof(int); + error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &oldlen, &len); + + if (error) + tst_brkm(TBROK, tst_exit, "can't get rcvbuf size: %s", + strerror(errno)); + + len = SMALL_RCVBUF; /* Really becomes 2xlen when set. */ + + error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len)); + if (error) + tst_brkm(TBROK, tst_exit, "setsockopt(SO_RCVBUF): %s", + strerror(errno)); + + /* Mark sk2 as being able to accept new associations. */ + test_listen(sk2, 1); + + /* Send the first message. This will create the association. */ + ppid = rand(); + stream = 1; + test_sctp_sendmsg(sk1, message, strlen(message) + 1, + (struct sockaddr *)&loop2, sizeof(loop2), + ppid, 0, stream, 0, 0); + + tst_resm(TPASS, "sctp_sendmsg"); + + /* Get the communication up message on sk2. */ + buflen = REALLY_BIG; + big_buffer = test_malloc(buflen); + msgname_len = sizeof(msgname); + error = test_sctp_recvmsg(sk2, big_buffer, buflen, + (struct sockaddr *)&msgname, &msgname_len, + &sinfo, &msg_flags); + associd2 = ((struct sctp_assoc_change *)big_buffer)->sac_assoc_id; + test_check_buf_notification(big_buffer, error, msg_flags, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + + + /* restore the rcvbuffer size for the receiving socket */ + error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &oldlen, + sizeof(oldlen)); + + if (error) + tst_brkm(TBROK, tst_exit, "setsockopt(SO_RCVBUF): %s", + strerror(errno)); + + /* Get the communication up message on sk1. */ + buflen = REALLY_BIG; + msgname_len = sizeof(msgname); + error = test_sctp_recvmsg(sk1, big_buffer, buflen, + (struct sockaddr *)&msgname, &msgname_len, + &sinfo, &msg_flags); + associd1 = ((struct sctp_assoc_change *)big_buffer)->sac_assoc_id; + test_check_buf_notification(big_buffer, error, msg_flags, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + + tst_resm(TPASS, "sctp_recvmsg SCTP_COMM_UP notification"); + + /* Get the first message which was sent. */ + buflen = REALLY_BIG; + msgname_len = sizeof(msgname); + error = test_sctp_recvmsg(sk2, big_buffer, buflen, + (struct sockaddr *)&msgname, &msgname_len, + &sinfo, &msg_flags); + test_check_buf_data(big_buffer, error, msg_flags, &sinfo, + strlen(message) + 1, MSG_EOR, stream, ppid); + + tst_resm(TPASS, "sctp_recvmsg data"); + + /* Figure out how big to make our fillmsg */ + len = sizeof(struct sctp_status); + memset(&gstatus,0,sizeof(struct sctp_status)); + gstatus.sstat_assoc_id = associd1; + error = getsockopt(sk1, IPPROTO_SCTP, SCTP_STATUS, &gstatus, &len); + + if (error) + tst_brkm(TBROK, tst_exit, "can't get rwnd size: %s", + strerror(errno)); + tst_resm(TINFO, "creating a fillmsg of size %d", + gstatus.sstat_rwnd+RWND_SLOP); + fillmsg = malloc(gstatus.sstat_rwnd+RWND_SLOP); + + /* Send a fillmsg */ + memset(fillmsg, 'X', gstatus.sstat_rwnd+RWND_SLOP); + fillmsg[gstatus.sstat_rwnd+RWND_SLOP-1] = '\0'; + ppid++; + stream++; + test_sctp_sendmsg(sk1, fillmsg, gstatus.sstat_rwnd+RWND_SLOP, + (struct sockaddr *)&loop2, sizeof(loop2), + ppid, 0, stream, 0, 0); + + /* Now send a message that will timeout. */ + test_sctp_sendmsg(sk1, ttlmsg, strlen(ttlmsg) + 1, + (struct sockaddr *)&loop2, sizeof(loop2), + ppid, 0, stream, 2000, 0); + + tst_resm(TPASS, "sctp_sendmsg with ttl"); + + /* Next send a message that won't time out. */ + test_sctp_sendmsg(sk1, nottlmsg, strlen(nottlmsg) + 1, + (struct sockaddr *)&loop2, sizeof(loop2), + ppid, 0, stream, 0, 0); + + tst_resm(TPASS, "sctp_sendmsg with zero ttl"); + + /* And finally a fragmented message that will time out. */ + memset(ttlfrag, '0', sizeof(ttlfrag)); + ttlfrag[sizeof(ttlfrag)-1] = '\0'; + test_sctp_sendmsg(sk1, ttlfrag, sizeof(ttlfrag), + (struct sockaddr *)&loop2, sizeof(loop2), + ppid, 0, stream, 2000, 0); + + tst_resm(TPASS, "sctp_sendmsg fragmented msg with ttl"); + + /* Sleep waiting for the message to time out. */ + tst_resm(TINFO, "** SLEEPING for 3 seconds **"); + sleep(3); + + /* Get the fillmsg. */ + do { + buflen = REALLY_BIG; + msgname_len = sizeof(msgname); + test_sctp_recvmsg(sk2, big_buffer, buflen, + (struct sockaddr *)&msgname, &msgname_len, + &sinfo, &msg_flags); + } while (!(msg_flags & MSG_EOR)); + + /* Get the message that did NOT time out. */ + buflen = REALLY_BIG; + msgname_len = sizeof(msgname); + error = test_sctp_recvmsg(sk2, big_buffer, buflen, + (struct sockaddr *)&msgname, &msgname_len, + &sinfo, &msg_flags); + test_check_buf_data(big_buffer, error, msg_flags, &sinfo, + strlen(nottlmsg) + 1, MSG_EOR, stream, ppid); + if (0 != strncmp(big_buffer, nottlmsg, strlen(nottlmsg))) + tst_brkm(TBROK, tst_exit, "sctp_recvmsg: Wrong Message !!!"); + + tst_resm(TPASS, "sctp_recvmsg msg with zero ttl"); + + /* Get the SEND_FAILED notification for the message that DID + * time out. + */ + buflen = REALLY_BIG; + msgname_len = sizeof(msgname); + error = test_sctp_recvmsg(sk1, big_buffer, buflen, + (struct sockaddr *)&msgname, &msgname_len, + &sinfo, &msg_flags); + test_check_buf_notification(big_buffer, error, msg_flags, + sizeof(struct sctp_send_failed) + + strlen(ttlmsg) + 1, + SCTP_SEND_FAILED, 0); + ssf = (struct sctp_send_failed *)big_buffer; + if (0 != strncmp(ttlmsg, (char *)ssf->ssf_data, strlen(ttlmsg) + 1)) + tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch"); + + tst_resm(TPASS, "sctp_recvmsg SEND_FAILED for message with ttl"); + + offset = 0; + + /* Get the SEND_FAILED notifications for the fragmented message that + * timed out. + */ + do { + buflen = REALLY_BIG; + msgname_len = sizeof(msgname); + error = test_sctp_recvmsg(sk1, big_buffer, buflen, + (struct sockaddr *)&msgname, &msgname_len, + &sinfo, &msg_flags); + test_check_buf_notification(big_buffer, error, msg_flags, + sizeof(struct sctp_send_failed) + + SMALL_MAXSEG, + SCTP_SEND_FAILED, 0); + ssf = (struct sctp_send_failed *)big_buffer; + if (0 != strncmp(&ttlfrag[offset], (char *)ssf->ssf_data, + SMALL_MAXSEG)) + tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch"); + offset += SMALL_MAXSEG; + } while (!(ssf->ssf_info.sinfo_flags & 0x01)); /* LAST FRAG */ + + tst_resm(TPASS, "sctp_recvmsg SEND_FAILED for fragmented message with " + "ttl"); + + snd_sinfo.sinfo_ppid = rand(); + snd_sinfo.sinfo_flags = 0; + snd_sinfo.sinfo_stream = 2; + snd_sinfo.sinfo_timetolive = 0; + snd_sinfo.sinfo_assoc_id = associd1; + test_sctp_send(sk1, message, strlen(message) + 1, &snd_sinfo, + MSG_NOSIGNAL); + + buflen = REALLY_BIG; + msgname_len = sizeof(msgname); + error = test_sctp_recvmsg(sk2, big_buffer, buflen, + (struct sockaddr *)&msgname, &msgname_len, + &sinfo, &msg_flags); + test_check_buf_data(big_buffer, error, msg_flags, &sinfo, + strlen(message) + 1, MSG_EOR, snd_sinfo.sinfo_stream, + snd_sinfo.sinfo_ppid); + + tst_resm(TPASS, "sctp_send"); + + /* Shut down the link. */ + close(sk1); + + /* Get the shutdown complete notification. */ + buflen = REALLY_BIG; + msgname_len = sizeof(msgname); + error = test_sctp_recvmsg(sk2, big_buffer, buflen, + (struct sockaddr *)&msgname, &msgname_len, + &sinfo, &msg_flags); + test_check_buf_notification(big_buffer, error, msg_flags, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP); + + close(sk2); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_sockopt.c b/src/func_tests/test_sockopt.c new file mode 100644 index 0000000..5c7607d --- /dev/null +++ b/src/func_tests/test_sockopt.c @@ -0,0 +1,1149 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2001, 2004 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2001 Intel Corp. + * Copyright (c) 2001 Nokia, Inc. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * La Monte H.P. Yarroll + * Karl Knutson + * Hui Huang + * Jon Grimm + * Sridhar Samudrala + */ + +/* This is a functional test to verify the various SCTP level socket + * options that can be used to get information about existing SCTP + * associations and to configure certain parameters. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 29; +int TST_CNT = 0; + +int +main(void) +{ + int udp_svr_sk, udp_clt_sk, tcp_svr_sk, tcp_clt_sk; + int accept_sk, peeloff_sk; + sockaddr_storage_t udp_svr_loop, udp_clt_loop; + sockaddr_storage_t tcp_svr_loop, tcp_clt_loop; + struct iovec iov; + struct msghdr inmessage; + struct msghdr outmessage; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + struct iovec out_iov; + char *message = "hello, world!\n"; + int error; + int pf_class, af_family; + uint32_t ppid; + uint32_t stream; + sctp_assoc_t udp_svr_associd, udp_clt_associd; + struct sctp_assoc_change *sac; + char *big_buffer; + struct sctp_event_subscribe subscribe; + struct sctp_initmsg initmsg; + struct sctp_paddrparams paddrparams; + struct sctp_sndrcvinfo set_udp_sk_dflt_param, get_udp_sk_dflt_param; + struct sctp_sndrcvinfo set_tcp_sk_dflt_param, get_tcp_sk_dflt_param; + struct sctp_sndrcvinfo set_udp_assoc_dflt_param; + struct sctp_sndrcvinfo get_udp_assoc_dflt_param; + struct sctp_sndrcvinfo set_tcp_assoc_dflt_param; + struct sctp_sndrcvinfo get_tcp_assoc_dflt_param; + struct sctp_sndrcvinfo get_peeloff_assoc_dflt_param; + struct sctp_sndrcvinfo get_accept_assoc_dflt_param; + struct sctp_paddrinfo pinfo; + int dflt_pathmaxrxt; + socklen_t optlen, addrlen; + struct sctp_status status; + struct sctp_assoc_value value; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Set some basic values which depend on the address family. */ +#if TEST_V6 + pf_class = PF_INET6; + af_family = AF_INET6; + + udp_svr_loop.v6.sin6_family = AF_INET6; + udp_svr_loop.v6.sin6_addr = in6addr_loopback; + udp_svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1); + + udp_clt_loop.v6.sin6_family = AF_INET6; + udp_clt_loop.v6.sin6_addr = in6addr_loopback; + udp_clt_loop.v6.sin6_port = htons(SCTP_TESTPORT_1+1); + + tcp_svr_loop.v6.sin6_family = AF_INET6; + tcp_svr_loop.v6.sin6_addr = in6addr_loopback; + tcp_svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1+2); + + tcp_clt_loop.v6.sin6_family = AF_INET6; + tcp_clt_loop.v6.sin6_addr = in6addr_loopback; + tcp_clt_loop.v6.sin6_port = htons(SCTP_TESTPORT_1+3); +#else + pf_class = PF_INET; + af_family = AF_INET; + + udp_svr_loop.v4.sin_family = AF_INET; + udp_svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + udp_svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1); + + udp_clt_loop.v4.sin_family = AF_INET; + udp_clt_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + udp_clt_loop.v4.sin_port = htons(SCTP_TESTPORT_1+1); + + tcp_svr_loop.v4.sin_family = AF_INET; + tcp_svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + tcp_svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1+2); + + tcp_clt_loop.v4.sin_family = AF_INET; + tcp_clt_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + tcp_clt_loop.v4.sin_port = htons(SCTP_TESTPORT_2+3); +#endif /* TEST_V6 */ + + /* Create the two endpoints which will talk to each other. */ + udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(udp_svr_sk); + test_enable_assoc_change(udp_clt_sk); + + /* Bind these sockets to the test ports. */ + test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop)); + test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop)); + + /* Mark udp_svr_sk as being able to accept new associations. */ + test_listen(udp_svr_sk, 1); + + /* TEST #1: SCTP_STATUS socket option. */ + /* Make sure that SCTP_STATUS getsockopt on a socket with no + * association fails. + */ + optlen = sizeof(struct sctp_status); + memset(&status, 0, optlen); + error = getsockopt(udp_svr_sk, SOL_SCTP, SCTP_STATUS, &status, + &optlen); + if ((error != -1) && (errno != EINVAL)) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_STATUS) on a " + "socket with no assoc error:%d errno:%d", + error, errno); + + tst_resm(TPASS, "getsockopt(SCTP_STATUS) on a socket with no assoc"); + + /* Send the first message. This will create the association. */ + outmessage.msg_name = &udp_svr_loop; + outmessage.msg_namelen = sizeof(udp_svr_loop); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid = rand(); /* Choose an arbitrary value. */ + stream = 1; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + outmessage.msg_iov->iov_base = message; + outmessage.msg_iov->iov_len = strlen(message) + 1; + test_sendmsg(udp_clt_sk, &outmessage, 0, strlen(message)+1); + + /* Initialize inmessage for all receives. */ + big_buffer = test_malloc(REALLY_BIG); + memset(&inmessage, 0, sizeof(inmessage)); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + + /* Get the communication up message on udp_svr_sk. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + udp_svr_associd = sac->sac_assoc_id; + + /* Get the communication up message on udp_clt_sk. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(udp_clt_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + udp_clt_associd = sac->sac_assoc_id; + + /* Get the first message which was sent. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(message) + 1, + MSG_EOR, stream, ppid); + + /* Get SCTP_STATUS for udp_clt_sk's given association. */ + optlen = sizeof(struct sctp_status); + memset(&status, 0, optlen); + status.sstat_assoc_id = udp_clt_associd; + test_getsockopt(udp_clt_sk, SCTP_STATUS, &status, &optlen); + + tst_resm(TPASS, "getsockopt(SCTP_STATUS)"); + + /* Make sure that SCTP_STATUS getsockopt with invalid associd fails. */ + optlen = sizeof(struct sctp_status); + memset(&status, 0, optlen); + status.sstat_assoc_id = udp_svr_associd; + error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_STATUS, &status, + &optlen); + if ((error != -1) && (errno != EINVAL)) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_STATUS) with " + "associd error: %d errno:%d", error, errno); + + tst_resm(TPASS, "getsockopt(SCTP_STATUS) with invalid associd"); + + /* Make sure that SCTP_STATUS getsockopt with NULL associd fails. */ + optlen = sizeof(struct sctp_status); + memset(&status, 0, optlen); + status.sstat_assoc_id = 0; + error = getsockopt(udp_svr_sk, SOL_SCTP, SCTP_STATUS, &status, + &optlen); + if ((error != -1) && (errno != EINVAL)) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_STATUS) with " + "NULL associd error: %d errno:%d", error, errno); + + tst_resm(TPASS, "getsockopt(SCTP_STATUS) with NULL associd"); + + /* Shut down the link. */ + close(udp_clt_sk); + + /* Get the shutdown complete notification. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP); + + error = 0; + close(udp_svr_sk); + + /* TEST #2: SCTP_EVENTS socket option and SCTP_SHUTDOWN_EVENT + * notification. + */ + /* Create the two endpoints which will talk to each other. */ + udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(udp_svr_sk); + test_enable_assoc_change(udp_clt_sk); + + /* Bind these sockets to the test ports. */ + test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop)); + test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop)); + + /* Mark udp_svr_sk as being able to accept new associations. */ + test_listen(udp_svr_sk, 1); + + /* Get the default events that are enabled on udp_svr_sk. */ + optlen = sizeof(subscribe); + test_getsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe, &optlen); + + /* Get the default events that are enabled on udp_clt_sk. */ + optlen = sizeof(subscribe); + test_getsockopt(udp_clt_sk, SCTP_EVENTS, &subscribe, &optlen); + + tst_resm(TPASS, "getsockopt(SCTP_EVENTS)"); + + /* Disable all the events on udp_svr_sk and udp_clt_sk. */ + memset(&subscribe, 0, sizeof(struct sctp_event_subscribe)); + test_setsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe, + sizeof(subscribe)); + test_setsockopt(udp_clt_sk, SCTP_EVENTS, &subscribe, + sizeof(subscribe)); + + tst_resm(TPASS, "setsockopt(SCTP_EVENTS)"); + + /* Get the updated list of enabled events on udp_svr_sk and + * udp_clt_sk. + */ + optlen = sizeof(subscribe); + test_getsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe, &optlen); + optlen = sizeof(subscribe); + test_getsockopt(udp_clt_sk, SCTP_EVENTS, &subscribe, &optlen); + + /* Send a message. This will create the association. */ + outmessage.msg_iov->iov_base = message; + outmessage.msg_iov->iov_len = strlen(message) + 1; + test_sendmsg(udp_clt_sk, &outmessage, 0, strlen(message)+1); + + /* Get the message which was sent. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(message) + 1, + MSG_EOR, 0, 0); + /* Verify that we received the msg without any ancillary data. */ + if (inmessage.msg_controllen != 0) + tst_brkm(TBROK, tst_exit, "Receive unexpected ancillary" + "data"); + + /* Enable SCTP_SHUTDOWN_EVENTs on udp_svr_sk. */ + memset(&subscribe, 0, sizeof(struct sctp_event_subscribe)); + subscribe.sctp_shutdown_event = 1; + test_setsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe, + sizeof(subscribe)); + + error = 0; + /* Shut down the link. */ + close(udp_clt_sk); + + /* Get the SHUTDOWN_EVENT notification on udp_svr_sk. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_shutdown_event), + SCTP_SHUTDOWN_EVENT, 0); + + tst_resm(TPASS, "setsockopt(SCTP_EVENTS) - SCTP_SHUTDOWN_EVENT"); + + close(udp_svr_sk); + + /* TEST #3: whether sctp_opt_info equals */ + /* Create the two endpoints which will talk to each other. */ + udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(udp_svr_sk); + test_enable_assoc_change(udp_clt_sk); + + /* Bind these sockets to the test ports. */ + test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop)); + test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop)); + + /* Mark udp_svr_sk as being able to accept new associations. */ + test_listen(udp_svr_sk, 1); + + /* Send the first message. This will create the association. */ + outmessage.msg_name = &udp_svr_loop; + outmessage.msg_namelen = sizeof(udp_svr_loop); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid = rand(); /* Choose an arbitrary value. */ + stream = 1; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + outmessage.msg_iov->iov_base = message; + outmessage.msg_iov->iov_len = strlen(message) + 1; + test_sendmsg(udp_clt_sk, &outmessage, 0, strlen(message)+1); + + /* Get the communication up message on udp_clt_sk. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(udp_clt_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + udp_clt_associd = sac->sac_assoc_id; + + /* Compare the SCTP_STATUS result between sctp_opt_info and + * getsockopt + */ + { + struct sctp_status status1, status2; + + memset(&status1, 0, sizeof(status1)); + memset(&status2, 0, sizeof(status2)); + optlen = sizeof(struct sctp_status); + + /* Test SCTP_STATUS for udp_clt_sk's given association. */ + error = sctp_opt_info(udp_clt_sk,udp_clt_associd,SCTP_STATUS, + (char *)&status1, &optlen); + if (error != 0) + tst_brkm(TBROK, tst_exit, + "sctp_opt_info(SCTP_STATUS): %s", + strerror(errno)); + + status2.sstat_assoc_id = udp_clt_associd; + error = getsockopt(udp_clt_sk, IPPROTO_SCTP, SCTP_STATUS, + (char *)&status2, &optlen); + if (error != 0) + tst_brkm(TBROK, tst_exit, + "getsockopt(SCTP_STATUS): %s", + strerror(errno)); + if (strncmp((char *)&status1, (char *)&status2, optlen)) + tst_brkm(TBROK, tst_exit, "sctp_opt_info(SCTP_STAUS)" + "doesn't match getsockopt(SCTP_STATUS)"); + + tst_resm(TPASS, "sctp_opt_info(SCTP_STATUS)"); + } + error = 0; + /* Shut down the link. */ + close(udp_svr_sk); + close(udp_clt_sk); + + /* TEST #4: SCTP_INITMSG socket option. */ + /* Create a socket. */ + udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + + /* Bind this socket to the test port. */ + test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop)); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(udp_svr_sk); + + /* Get the default parameters for association initialization. */ + optlen = sizeof(initmsg); + test_getsockopt(udp_svr_sk, SCTP_INITMSG, &initmsg, &optlen); + + tst_resm(TPASS, "getsockopt(SCTP_INITMSG)"); + + /* Change the parameters for association initialization. */ + initmsg.sinit_num_ostreams = 5; + initmsg.sinit_max_instreams = 5; + initmsg.sinit_max_attempts = 3; + initmsg.sinit_max_init_timeo = 30; + test_setsockopt(udp_svr_sk, SCTP_INITMSG, &initmsg, sizeof(initmsg)); + + tst_resm(TPASS, "setsockopt(SCTP_INITMSG)"); + + /* Get the updated parameters for association initialization. */ + optlen = sizeof(initmsg); + test_getsockopt(udp_svr_sk, SCTP_INITMSG, &initmsg, &optlen); + + close(udp_svr_sk); + + /* TEST #5: SCTP_PEER_ADDR_PARAMS socket option. */ + /* Create a socket. */ + udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + + /* Get the default parameters for this endpoint */ + optlen = sizeof(paddrparams); + memset(&paddrparams, 0, sizeof(paddrparams)); + paddrparams.spp_address.ss_family = AF_INET; + test_getsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams, + &optlen); + + dflt_pathmaxrxt = paddrparams.spp_pathmaxrxt; + tst_resm(TPASS, "getsockopt(SCTP_PEER_ADDR_PARAMS)"); + + /* Change the default parameters for this endpoint (socket) */ + paddrparams.spp_hbinterval = 1000; + paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1; + paddrparams.spp_sackdelay = 100; + test_setsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams, + sizeof(paddrparams)); + + paddrparams.spp_pathmaxrxt = 0; + + /* Get the updated default parameters for this endpoint. */ + optlen = sizeof(paddrparams); + test_getsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams, + &optlen); + if (paddrparams.spp_pathmaxrxt != dflt_pathmaxrxt+1) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "mismatch"); + + value.assoc_id = 0; + optlen = sizeof(value); + test_getsockopt(udp_svr_sk, SCTP_DELAYED_ACK_TIME, &value, + &optlen); + if (value.assoc_value != 100) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DELAYED_ACK_TIME) " + "mismatch"); + + value.assoc_id = 0; + value.assoc_value = 250; + test_setsockopt(udp_svr_sk, SCTP_DELAYED_ACK_TIME, &value, + sizeof(value)); + optlen = sizeof(paddrparams); + test_getsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams, + &optlen); + if (paddrparams.spp_sackdelay != 250) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DELAYED_ACK_TIME) " + "mismatch"); + + tst_resm(TPASS, "setsockopt(SCTP_DELAYED_ACK_TIME)"); + + + /* Ensure that prior defaults are preserved for a new endpoint */ + udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + optlen = sizeof(paddrparams); + memset(&paddrparams, 0, sizeof(paddrparams)); + paddrparams.spp_address.ss_family = AF_INET; + test_getsockopt(udp_clt_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams, + &optlen); + if (paddrparams.spp_pathmaxrxt != dflt_pathmaxrxt) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_PEER_ADDR_PARAMS) " + "mismatch"); + + + tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS)"); + + /* Invalid assoc id */ + paddrparams.spp_assoc_id = 1234; + error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, + &paddrparams, + sizeof(paddrparams)); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "invalid associd error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "- one-to-many style invalid associd"); + + test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop)); + test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop)); + + test_listen(udp_svr_sk, 5); + + test_enable_assoc_change(udp_svr_sk); + test_enable_assoc_change(udp_clt_sk); + + /* Do a connect on a UDP-style socket and establish an association. */ + test_connect(udp_clt_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop)); + + /* Receive the COMM_UP notifications and get the associd's */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + + paddrparams.spp_assoc_id = sac->sac_assoc_id; + memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop)); + paddrparams.spp_hbinterval = 1000; + paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1; + test_setsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams, + sizeof(paddrparams)); + tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) - " + "one-to-many style valid associd valid address"); + + paddrparams.spp_assoc_id = sac->sac_assoc_id; + memcpy(&paddrparams.spp_address, &udp_svr_loop, sizeof(udp_svr_loop)); + paddrparams.spp_hbinterval = 1000; + paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1; + + error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, + &paddrparams, + sizeof(paddrparams)); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "invalid transport error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "- one-to-many style invalid transport"); + + paddrparams.spp_assoc_id = sac->sac_assoc_id; + memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop)); + paddrparams.spp_hbinterval = 1000; + paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1; + + error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, + &paddrparams, + sizeof(paddrparams) - 1); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "invalid parameter length error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "- one-to-many style invalid parameter length"); + + error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_DELAYED_ACK_TIME, + &value, + sizeof(value) - 1); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DELAYED_ACK_TIME) " + "invalid parameter length error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "setsockopt(SCTP_DELAYED_ACK_TIME) " + "- one-to-many style invalid parameter length"); + + memset(&paddrparams, 0, sizeof(paddrparams)); + paddrparams.spp_assoc_id = sac->sac_assoc_id; + memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop)); + paddrparams.spp_sackdelay = 501; + + error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, + &paddrparams, + sizeof(paddrparams)); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "invalid sack delay error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "- one-to-many style invalid sack delay"); + + value.assoc_id = sac->sac_assoc_id; + value.assoc_value = 501; + + error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_DELAYED_ACK_TIME, + &value, + sizeof(value)); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DELAYED_ACK_TIME) " + "invalid sack delay error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "setsockopt(SCTP_DELAYED_ACK_TIME) " + "- one-to-many style invalid sack delay"); + + memset(&paddrparams, 0, sizeof(paddrparams)); + paddrparams.spp_assoc_id = sac->sac_assoc_id; + memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop)); + paddrparams.spp_pathmtu = 511; + + error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, + &paddrparams, + sizeof(paddrparams)); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "invalid path MTU error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "- one-to-many style invalid path MTU"); + + memset(&paddrparams, 0, sizeof(paddrparams)); + paddrparams.spp_assoc_id = sac->sac_assoc_id; + memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop)); + paddrparams.spp_flags = SPP_HB_ENABLE | SPP_HB_DISABLE; + + error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, + &paddrparams, + sizeof(paddrparams)); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "invalid hb enable flags error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "- one-to-many style invalid hb enable flags"); + + memset(&paddrparams, 0, sizeof(paddrparams)); + paddrparams.spp_assoc_id = sac->sac_assoc_id; + memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop)); + paddrparams.spp_flags = SPP_PMTUD_ENABLE | SPP_PMTUD_DISABLE; + + error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, + &paddrparams, + sizeof(paddrparams)); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "invalid PMTU discovery enable flags error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "- one-to-many style invalid PMTU discovery enable flags"); + + memset(&paddrparams, 0, sizeof(paddrparams)); + paddrparams.spp_assoc_id = sac->sac_assoc_id; + memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop)); + paddrparams.spp_flags = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE; + + error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, + &paddrparams, + sizeof(paddrparams)); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "invalid sack delay enable flags error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "- one-to-many style invalid sack delay enable flags"); + + memset(&paddrparams, 0, sizeof(paddrparams)); + paddrparams.spp_flags = SPP_HB_DEMAND; + + error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, + &paddrparams, + sizeof(paddrparams)); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "invalid hb demand error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) " + "- one-to-many style invalid hb demand"); + + close(udp_svr_sk); + close(udp_clt_sk); + + + /* TEST #6: SCTP_DEFAULT_SEND_PARAM socket option. */ + /* Create and bind 2 UDP-style sockets(udp_svr_sk, udp_clt_sk) and + * 2 TCP-style sockets. (tcp_svr_sk, tcp_clt_sk) + */ + udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + tcp_svr_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + tcp_clt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(udp_svr_sk); + test_enable_assoc_change(udp_clt_sk); + test_enable_assoc_change(tcp_svr_sk); + test_enable_assoc_change(tcp_clt_sk); + + test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop)); + test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop)); + test_bind(tcp_svr_sk, &tcp_svr_loop.sa, sizeof(tcp_svr_loop)); + test_bind(tcp_clt_sk, &tcp_clt_loop.sa, sizeof(tcp_clt_loop)); + + /* Mark udp_svr_sk and tcp_svr_sk as being able to accept new + * associations. + */ + test_listen(udp_svr_sk, 5); + test_listen(tcp_svr_sk, 5); + + /* Set default send parameters on the unconnected UDP-style sockets. */ + memset(&set_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + set_udp_sk_dflt_param.sinfo_ppid = 1000; + test_setsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM, + &set_udp_sk_dflt_param, sizeof(set_udp_sk_dflt_param)); + memset(&set_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + set_udp_sk_dflt_param.sinfo_ppid = 1000; + test_setsockopt(udp_clt_sk, SCTP_DEFAULT_SEND_PARAM, + &set_udp_sk_dflt_param, sizeof(set_udp_sk_dflt_param)); + + tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - " + "one-to-many style socket"); + + /* Get default send parameters on the unconnected UDP-style socket. */ + memset(&get_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + optlen = sizeof(get_udp_sk_dflt_param); + test_getsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM, + &get_udp_sk_dflt_param, &optlen); + + /* Verify that the get param matches set param. */ + if (set_udp_sk_dflt_param.sinfo_ppid != + get_udp_sk_dflt_param.sinfo_ppid) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) " + "mismatch."); + + /* Get default send parameters on the unconnected UDP-style socket. */ + memset(&get_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + optlen = sizeof(get_udp_sk_dflt_param); + test_getsockopt(udp_clt_sk, SCTP_DEFAULT_SEND_PARAM, + &get_udp_sk_dflt_param, &optlen); + + /* Verify that the get param matches set param. */ + if (set_udp_sk_dflt_param.sinfo_ppid != + get_udp_sk_dflt_param.sinfo_ppid) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) " + "mismatch."); + + tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - " + "one-to-many style socket"); + + /* Verify that trying to set send params with an invalid assoc id + * on an UDP-style socket fails. + */ + memset(&set_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + set_udp_sk_dflt_param.sinfo_ppid = 1000; + /* Invalid assoc id */ + set_udp_sk_dflt_param.sinfo_assoc_id = 1234; + error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_DEFAULT_SEND_PARAM, + &set_udp_sk_dflt_param, + sizeof(set_udp_sk_dflt_param)); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DEFAULT_SEND_PARAM) " + "invalid associd error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) " + "- one-to-many style invalid associd"); + + /* Do a connect on a UDP-style socket and establish an association. */ + test_connect(udp_clt_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop)); + + /* Receive the COMM_UP notifications and get the associd's */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + udp_svr_associd = sac->sac_assoc_id; + + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(udp_clt_sk, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + udp_clt_associd = sac->sac_assoc_id; + + /* Verify that trying to set send params with an assoc id not + * belonging to the socket on an UDP-style socket fails. + */ + memset(&set_udp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + set_udp_assoc_dflt_param.sinfo_ppid = 3000; + set_udp_assoc_dflt_param.sinfo_assoc_id = udp_clt_associd; + error = setsockopt(udp_svr_sk, SOL_SCTP, SCTP_DEFAULT_SEND_PARAM, + &set_udp_assoc_dflt_param, + sizeof(set_udp_assoc_dflt_param)); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DEFAULT_SEND_PARAM) " + "associd belonging to another socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - " + "one-to-many style associd belonging to another socket"); + + /* Set default send parameters of an association on the listening + * UDP-style socket with a valid associd. + */ + memset(&set_udp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + set_udp_assoc_dflt_param.sinfo_ppid = 3000; + set_udp_assoc_dflt_param.sinfo_assoc_id = udp_svr_associd; + test_setsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM, + &set_udp_assoc_dflt_param, + sizeof(set_udp_assoc_dflt_param)); + + tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - " + "one-to-many style valid associd"); + + /* Get default send parameters of an association on the listening + * UDP-style socket with a valid associd. + */ + memset(&get_udp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + get_udp_assoc_dflt_param.sinfo_assoc_id = udp_svr_associd ; + optlen = sizeof(get_udp_assoc_dflt_param); + test_getsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM, + &get_udp_assoc_dflt_param, &optlen); + + /* Verify that the get param matches the set param. */ + if (get_udp_assoc_dflt_param.sinfo_ppid != + set_udp_assoc_dflt_param.sinfo_ppid) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) " + "mismatch."); + + tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - " + "one-to-many style valid associd"); + + /* Get default send parameters of an association on the connected + * UDP-style socket with zero associd. This should return the + * socket wide default parameters. + */ + memset(&get_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + get_udp_sk_dflt_param.sinfo_assoc_id = 0 ; + optlen = sizeof(get_udp_sk_dflt_param); + test_getsockopt(udp_clt_sk, SCTP_DEFAULT_SEND_PARAM, + &get_udp_sk_dflt_param, &optlen); + + /* Verify that the get param matches the socket-wide set param. */ + if (get_udp_sk_dflt_param.sinfo_ppid != + set_udp_sk_dflt_param.sinfo_ppid) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) " + "mismatch."); + + tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - " + "one-to-many style zero associd"); + + peeloff_sk = test_sctp_peeloff(udp_svr_sk, udp_svr_associd); + + /* Get default send parameters of an association on the peeled off + * UDP-style socket. This should return the association's default + * parameters. + */ + memset(&get_peeloff_assoc_dflt_param, 0, + sizeof(struct sctp_sndrcvinfo)); + get_peeloff_assoc_dflt_param.sinfo_assoc_id = 0 ; + optlen = sizeof(get_peeloff_assoc_dflt_param); + test_getsockopt(peeloff_sk, SCTP_DEFAULT_SEND_PARAM, + &get_peeloff_assoc_dflt_param, &optlen); + + /* Verify that the get param matches the association's set param. */ + if (get_peeloff_assoc_dflt_param.sinfo_ppid != + set_udp_assoc_dflt_param.sinfo_ppid) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) " + "mismatch."); + + tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - " + "one-to-many style peeled off socket"); + + /* Set default send parameters on the unconnected TCP-style sockets. */ + memset(&set_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + set_tcp_sk_dflt_param.sinfo_ppid = 2000; + /* Invalid assoc id, ignored on a TCP-style socket. */ + set_tcp_sk_dflt_param.sinfo_assoc_id = 1234; + test_setsockopt(tcp_svr_sk, SCTP_DEFAULT_SEND_PARAM, + &set_tcp_sk_dflt_param, + sizeof(set_tcp_sk_dflt_param)); + + /* Set default send parameters on the unconnected TCP-style sockets. */ + memset(&set_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + set_tcp_sk_dflt_param.sinfo_ppid = 2000; + /* Invalid assoc id, ignored on a TCP-style socket. */ + set_tcp_sk_dflt_param.sinfo_assoc_id = 1234; + test_setsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM, + &set_tcp_sk_dflt_param, + sizeof(set_tcp_sk_dflt_param)); + + tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - " + "one-to-one style socket"); + + /* Get default send parameters on the unconnected TCP-style socket. */ + memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + optlen = sizeof(get_tcp_sk_dflt_param); + test_getsockopt(tcp_svr_sk, SCTP_DEFAULT_SEND_PARAM, + &get_tcp_sk_dflt_param, &optlen); + + /* Verify that the get param matches set param. */ + if (set_tcp_sk_dflt_param.sinfo_ppid != + get_tcp_sk_dflt_param.sinfo_ppid) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) " + "mismatch."); + + /* Get default send parameters on the unconnected TCP-style socket. */ + memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + optlen = sizeof(get_tcp_sk_dflt_param); + test_getsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM, + &get_tcp_sk_dflt_param, &optlen); + + /* Verify that the get param matches set param. */ + if (set_tcp_sk_dflt_param.sinfo_ppid != + get_tcp_sk_dflt_param.sinfo_ppid) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) " + "mismatch."); + + tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - " + "one-to-one style socket"); + + /* Do a connect on a TCP-style socket and establish an association. */ + test_connect(tcp_clt_sk, &tcp_svr_loop.sa, sizeof(tcp_svr_loop)); + + /* Set default send parameters of an association on the connected + * TCP-style socket. + */ + memset(&set_tcp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + set_tcp_assoc_dflt_param.sinfo_ppid = 4000; + set_tcp_assoc_dflt_param.sinfo_assoc_id = 0; + test_setsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM, + &set_tcp_assoc_dflt_param, + sizeof(set_tcp_assoc_dflt_param)); + + tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - " + "one-to-one style assoc"); + + /* Get default send parameters of an association on the connected + * TCP-style socket. + */ + memset(&get_tcp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + optlen = sizeof(get_tcp_assoc_dflt_param); + test_getsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM, + &get_tcp_assoc_dflt_param, &optlen); + + if (set_tcp_assoc_dflt_param.sinfo_ppid != + get_tcp_assoc_dflt_param.sinfo_ppid) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) " + "mismatch."); + + /* Get default send parameters on the connected TCP-style socket. */ + memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + optlen = sizeof(get_tcp_sk_dflt_param); + test_getsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM, + &get_tcp_sk_dflt_param, &optlen); + + /* Verify that the get parameters returned matches the set param + * set for the association, not the socket-wide param. + */ + if ((get_tcp_sk_dflt_param.sinfo_ppid == + set_tcp_sk_dflt_param.sinfo_ppid) || + (get_tcp_sk_dflt_param.sinfo_ppid != + set_tcp_assoc_dflt_param.sinfo_ppid)) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) " + "mismatch."); + + /* Get default send parameters on the listening TCP-style socket. */ + memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + optlen = sizeof(get_tcp_sk_dflt_param); + test_getsockopt(tcp_svr_sk, SCTP_DEFAULT_SEND_PARAM, + &get_tcp_sk_dflt_param, &optlen); + + /* Verify that the get parameters returned matches the socket-wide + * set param. + */ + if (get_tcp_sk_dflt_param.sinfo_ppid != + set_tcp_sk_dflt_param.sinfo_ppid) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) " + "mismatch."); + + tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - " + "one-to-one style assoc"); + + accept_sk = test_accept(tcp_svr_sk, NULL, &addrlen); + + /* Get default send parameters of an association on the accepted + * TCP-style socket. + */ + memset(&get_accept_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo)); + optlen = sizeof(get_accept_assoc_dflt_param); + test_getsockopt(accept_sk, SCTP_DEFAULT_SEND_PARAM, + &get_accept_assoc_dflt_param, &optlen); + + error = 0; + + /* Verify that the get parameters returned matches the socket-wide + * set param. + */ + if (get_tcp_sk_dflt_param.sinfo_ppid != + set_tcp_sk_dflt_param.sinfo_ppid) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) " + "mismatch."); + + tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - " + "one-to-one style accepted socket"); + + /* TEST #7: SCTP_GET_PEER_ADDR_INFO socket option. */ + /* Try 0 associd and 0 addr */ + memset(&pinfo, 0, sizeof(pinfo)); + optlen = sizeof(pinfo); + error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO, + &pinfo, &optlen); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_GET_PEER_ADDR_INFO) " + "null associd, null addr error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - " + "null associd and null addr"); + + /* Try valid associd, but 0 addr */ + memset(&pinfo, 0, sizeof(pinfo)); + optlen = sizeof(pinfo); + pinfo.spinfo_assoc_id = udp_clt_associd; + error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO, + &pinfo, &optlen); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_GET_PEER_ADDR_INFO) " + "valid associd, null addr error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - " + "valid associd and null addr"); + + /* Try valid associd, invalid addr */ + memset(&pinfo, 0, sizeof(pinfo)); + optlen = sizeof(pinfo); + pinfo.spinfo_assoc_id = udp_clt_associd; + memcpy(&pinfo.spinfo_address, &udp_clt_loop, sizeof(udp_clt_loop)); + error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO, + &pinfo, &optlen); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_GET_PEER_ADDR_INFO) " + "valid associd, invalid addr error:%d, errno:%d\n", + error, errno); + + tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - " + "valid associd and invalid addr"); + + /* Try valid associd, valid addr */ + memset(&pinfo, 0, sizeof(pinfo)); + optlen = sizeof(pinfo); + pinfo.spinfo_assoc_id = udp_clt_associd; + memcpy(&pinfo.spinfo_address, &udp_svr_loop, sizeof(udp_svr_loop)); + test_getsockopt(udp_clt_sk, SCTP_GET_PEER_ADDR_INFO, &pinfo, &optlen); + + tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - " + "valid associd and valid addr"); + + /* Try valid addr, peeled off socket */ + memset(&pinfo, 0, sizeof(pinfo)); + optlen = sizeof(pinfo); + pinfo.spinfo_assoc_id = 0; + memcpy(&pinfo.spinfo_address, &udp_clt_loop, sizeof(udp_clt_loop)); + test_getsockopt(peeloff_sk, SCTP_GET_PEER_ADDR_INFO, &pinfo, &optlen); + + tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - " + "valid associd and valid addr peeled off socket"); + + /* Try valid addr, TCP-style accept socket */ + memset(&pinfo, 0, sizeof(pinfo)); + optlen = sizeof(pinfo); + pinfo.spinfo_assoc_id = 0; + memcpy(&pinfo.spinfo_address, &tcp_clt_loop, sizeof(tcp_clt_loop)); + error = test_getsockopt(accept_sk, SCTP_GET_PEER_ADDR_INFO, &pinfo, + &optlen); + + tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - " + "valid associd and valid addr accepted socket"); + + close(udp_svr_sk); + close(udp_clt_sk); + close(tcp_svr_sk); + close(tcp_clt_sk); + close(accept_sk); + close(peeloff_sk); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_tcp_style.c b/src/func_tests/test_tcp_style.c new file mode 100644 index 0000000..f4f835a --- /dev/null +++ b/src/func_tests/test_tcp_style.c @@ -0,0 +1,463 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2003 + * Copyright (c) 1999-2001 Motorola, Inc. + * + * This file is part of the SCTP kernel Implementation + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Sridhar Samudrala + */ + +/* This is a kernel test to verify the TCP-style socket interfaces. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 22; +int TST_CNT = 0; + +#define MAX_CLIENTS 10 + +int +main(int argc, char *argv[]) +{ + int clt_sk[MAX_CLIENTS], accept_sk[MAX_CLIENTS]; + int listen_sk, clt2_sk, accept2_sk; + sockaddr_storage_t clt_loop[MAX_CLIENTS]; + sockaddr_storage_t svr_loop, accept_loop, clt2_loop; + socklen_t addrlen; + int error, i; + char *message = "hello, world!\n"; + char msgbuf[100]; + int pf_class; + struct pollfd poll_fd; + fd_set set; + struct msghdr outmessage; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct iovec out_iov; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + struct msghdr inmessage; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + char *big_buffer; + struct iovec iov; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Initialize the server and client addresses. */ +#if TEST_V6 + pf_class = PF_INET6; + svr_loop.v6.sin6_family = AF_INET6; + svr_loop.v6.sin6_addr = in6addr_loopback; + svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1); + for (i = 0; i < MAX_CLIENTS; i++) { + clt_loop[i].v6.sin6_family = AF_INET6; + clt_loop[i].v6.sin6_addr = in6addr_loopback; + clt_loop[i].v6.sin6_port = htons(SCTP_TESTPORT_2 + i); + } + clt2_loop.v6.sin6_family = AF_INET6; + clt2_loop.v6.sin6_addr = in6addr_loopback; + clt2_loop.v6.sin6_port = htons(SCTP_TESTPORT_2 + i); +#else + pf_class = PF_INET; + svr_loop.v4.sin_family = AF_INET; + svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1); + for (i = 0; i < MAX_CLIENTS; i++) { + clt_loop[i].v4.sin_family = AF_INET; + clt_loop[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + clt_loop[i].v4.sin_port = htons(SCTP_TESTPORT_2 + i); + } + clt2_loop.v4.sin_family = AF_INET; + clt2_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + clt2_loop.v4.sin_port = htons(SCTP_TESTPORT_2 + i); +#endif + + /* Create and bind the listening server socket. */ + listen_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + test_bind(listen_sk, &svr_loop.sa, sizeof(svr_loop)); + + /* Mark listen_sk as being able to accept new associations. */ + test_listen(listen_sk, MAX_CLIENTS-1); + + /* Create and bind the client sockets. */ + for (i = 0; i < MAX_CLIENTS; i++) { + clt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + test_bind(clt_sk[i], &clt_loop[i].sa, sizeof(clt_loop[i])); + } + clt2_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + test_bind(clt2_sk, &clt2_loop.sa, sizeof(clt2_loop)); + + addrlen = sizeof(accept_loop); + /* Try to do accept on a non-listening socket. It should fail. */ + error = accept(clt_sk[0], &accept_loop.sa, &addrlen); + if ((-1 != error) && (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "accept on non-listening socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "accept on non-listening socket"); + + /* Try to do a connect from a listening socket. It should fail. */ + error = connect(listen_sk, (struct sockaddr *)&clt_loop[0], + sizeof(clt_loop[0])); + if ((-1 != error) && (EISCONN != errno)) + tst_brkm(TBROK, tst_exit, "connect to non-listening socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "connect to non-listening socket"); + + /* Do a blocking connect from clt_sk's to listen_sk */ + for (i = 0; i < MAX_CLIENTS; i++) + test_connect(clt_sk[i], &svr_loop.sa, sizeof(svr_loop)); + + tst_resm(TPASS, "connect to listening socket"); + + /* Verify that no more connect's can be done after the acceptq + * backlog has reached the max value. + */ + error = connect(clt2_sk, &svr_loop.sa, sizeof(svr_loop)); + if ((-1 != error) && (ECONNREFUSED != errno)) + tst_brkm(TBROK, tst_exit, "connect after max backlog " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "connect after max backlog"); + + /* Extract the associations on the listening socket as new sockets. */ + for (i = 0; i < MAX_CLIENTS; i++) { + poll_fd.fd = listen_sk; + poll_fd.events = POLLIN; + poll_fd.revents = 0; + error = poll(&poll_fd, 1, -1); + if ((1 != error) && (1 != poll_fd.revents)) + tst_brkm(TBROK, tst_exit, "Unexpected return value " + "with poll, error:%d errno:%d, revents:%d", + error, errno, poll_fd.revents); + + addrlen = sizeof(accept_loop); + accept_sk[i] = test_accept(listen_sk, &accept_loop.sa, + &addrlen); + } + + tst_resm(TPASS, "accept from listening socket"); + + /* Try to do a connect on an established socket. It should fail. */ + error = connect(accept_sk[0], &clt_loop[0].sa, sizeof(clt_loop[0])); + if ((-1 != error) || (EISCONN != errno)) + tst_brkm(TBROK, tst_exit, "connect on an established socket " + "error:%d errno:%d", error, errno); + + tst_resm(TPASS, "connect on an established socket"); + + /* Try to do accept on an established socket. It should fail. */ + error = accept(accept_sk[0], &accept_loop.sa, &addrlen); + if ((-1 != error) && (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "accept on an established socket " + "error:%d errno:%d", error, errno); + + error = accept(clt_sk[0], &accept_loop.sa, &addrlen); + if ((-1 != error) && (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "accept on an established socket " + "failure: error:%d errno:%d", error, errno); + + tst_resm(TPASS, "accept on an established socket"); + + /* Send and receive a message from the client sockets to the accepted + * sockets. + */ + for (i = 0; i < MAX_CLIENTS; i++) { + test_send(clt_sk[i], message, strlen(message), 0); + test_recv(accept_sk[i], msgbuf, 100, 0); + } + + tst_resm(TPASS, "client sockets -> accepted sockets"); + + /* Send and receive a message from the accepted sockets to the client + * sockets. + */ + for (i = 0; i < MAX_CLIENTS; i++) { + test_send(accept_sk[i], message, strlen(message), 0); + test_recv(clt_sk[i], msgbuf, 100, 0); + } + + tst_resm(TPASS, "accepted sockets -> client sockets"); + + /* Sending a message on a listening socket should fail. */ + error = send(listen_sk, message, strlen(message), MSG_NOSIGNAL); + if ((-1 != error) || (EPIPE != errno)) + tst_brkm(TBROK, tst_exit, "send on a listening socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "send on a listening socket"); + + /* Trying to receive a message on a listening socket should fail. */ + error = recv(listen_sk, msgbuf, 100, 0); + if ((-1 != error) || (ENOTCONN != errno)) + tst_brkm(TBROK, tst_exit, "recv on a listening socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "recv on a listening socket"); + + /* TESTCASES for shutdown() */ + errno = 0; + test_send(accept_sk[0], message, strlen(message), 0); + + /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ + test_enable_assoc_change(clt_sk[0]); + + /* Do a SHUT_WR on clt_sk[0] to disable any new sends. */ + test_shutdown(clt_sk[0], SHUT_WR); + + /* Reading on a socket that has received SHUTDOWN should return 0 + * indicating EOF. + */ + error = recv(accept_sk[0], msgbuf, 100, 0); + if ((0 != error) || (0 != errno)) + tst_brkm(TBROK, tst_exit, "recv on a SHUTDOWN received socket " + "error:%d errno:%d", error, errno); + + tst_resm(TPASS, "recv on a SHUTDOWN received socket"); + + /* Read the pending message on clt_sk[0] that was received before + * SHUTDOWN call. + */ + test_recv(clt_sk[0], msgbuf, 100, 0); + + /* Initialize inmessage for all receives. */ + big_buffer = test_malloc(REALLY_BIG); + memset(&inmessage, 0, sizeof(inmessage)); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + inmessage.msg_controllen = sizeof(incmsg); + + /* Receive the SHUTDOWN_COMP notification as they are enabled. */ + error = test_recvmsg(clt_sk[0], &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP); + + tst_resm(TPASS, "recv SHUTDOWN_COMP notification on a SHUT_WR socket"); + + /* No more messages and the association is SHUTDOWN, should fail. */ + error = recv(clt_sk[0], msgbuf, 100, 0); + if ((-1 != error) || (ENOTCONN != errno)) + tst_brkm(TBROK, tst_exit, "recv on a SHUTDOWN sent socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "recv on a SHUTDOWN sent socket"); + + errno = 0; + + /* Do a SHUT_RD on clt_sk[1] to disable any new receives. */ + test_shutdown(clt_sk[1], SHUT_RD); + + error = recv(clt_sk[1], msgbuf, 100, 0); + if ((0 != error) || (0 != errno)) + tst_brkm(TBROK, tst_exit, "recv on a SHUT_RD socket " + "error:%d, errno:%d", error, errno); + + /* Sending a message on SHUT_RD socket. */ + test_send(clt_sk[1], message, strlen(message), 0); + + /* Receive the message sent on SHUT_RD socket. */ + test_recv(accept_sk[1], msgbuf, 100, 0); + + /* Send a message to the SHUT_RD socket. */ + test_send(accept_sk[1], message, strlen(message), 0); + + /* We should not receive the message as the socket is SHUT_RD */ + error = recv(clt_sk[1], msgbuf, 100, 0); + if ((0 != error) || (0 != errno)) + tst_brkm(TBROK, tst_exit, "recv on a SHUT_RD socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "recv on a SHUT_RD socket"); + + /* Do a SHUT_RDWR on clt_sk[2] to disable any new sends/receives. */ + test_shutdown(clt_sk[2], SHUT_RDWR); + + error = recv(accept_sk[2], msgbuf, 100, 0); + if ((0 != error) || (0 != errno)) + tst_brkm(TBROK, tst_exit, "recv on a SHUT_RDWR socket " + "error:%d, errno:%d", error, errno); + + error = recv(clt_sk[2], msgbuf, 100, 0); + if ((0 != error) || (0 != errno)) + tst_brkm(TBROK, tst_exit, "recv on a SHUT_RDWR socket " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "recv on a SHUT_RDWR socket"); + + error = 0; + + for (i = 0; i < MAX_CLIENTS; i++) + close(clt_sk[i]); + for (i = 0; i < MAX_CLIENTS; i++) + close(accept_sk[i]); + + /* Test case to verify accept of a CLOSED association. */ + /* Do a connect, send and a close to ESTABLISH and CLOSE an + * association on the listening socket. + */ + test_connect(clt2_sk, &svr_loop.sa, sizeof(svr_loop)); + + test_send(clt2_sk, message, strlen(message), 0); + + close(clt2_sk); + + FD_ZERO(&set); + FD_SET(listen_sk, &set); + + error = select(listen_sk + 1, &set, NULL, NULL, NULL); + if (1 != error) + tst_brkm(TBROK, tst_exit, "select error:%d, " + "errno: %d", error, errno); + + /* Now accept the CLOSED association waiting on the listening + * socket. + */ + accept2_sk = test_accept(listen_sk, &accept_loop.sa, &addrlen); + + /* Receive the message sent before doing a close. */ + test_recv(accept2_sk, msgbuf, 100, 0); + + /* Receive EOF indication as there are no more messages and the + * socket is SHUTDOWN. + */ + error = recv(accept2_sk, msgbuf, 100, 0); + if ((0 != error) || (0 != errno)) + tst_brkm(TBROK, tst_exit, "Unexpected error return on " + "recv(error:%d, errno:%d)", error, errno); + + tst_resm(TPASS, "accept of a CLOSED association"); + + /* Trying to send a message over the CLOSED association should + * generate EPIPE. + */ + error = send(accept2_sk, message, strlen(message), MSG_NOSIGNAL); + if ((-1 != error) || (EPIPE != errno)) + tst_brkm(TBROK, tst_exit, "send to a CLOSED association " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "send to a CLOSED association"); + + error = 0; + close(accept2_sk); + + /* Verify that auto-connect can be done on a TCP-style socket using + * sendto/sendmsg. + */ + clt2_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); + test_bind(clt2_sk, &clt2_loop.sa, sizeof(clt2_loop)); + + /* Do a sendto() without a connect() */ + test_sendto(clt2_sk, message, strlen(message), 0, &svr_loop.sa, + sizeof(svr_loop)); + + accept2_sk = test_accept(listen_sk, &accept_loop.sa, &addrlen); + + test_recv(accept2_sk, msgbuf, 100, 0); + + tst_resm(TPASS, "auto-connect using sendto"); + + outmessage.msg_name = &svr_loop; + outmessage.msg_namelen = sizeof(svr_loop); + outmessage.msg_iov = NULL; + outmessage.msg_iovlen = 0; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + + /* Verify that SCTP_EOF cannot be used to shutdown an association + * on a TCP-style socket. + */ + sinfo->sinfo_flags |= SCTP_EOF; + error = sendmsg(clt2_sk, &outmessage, 0); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_EOF flag " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sendmsg with SCTP_EOF flag"); + + /* Verify that SCTP_ABORT cannot be used to abort an association + * on a TCP-style socket. + */ + sinfo->sinfo_flags |= SCTP_ABORT; + error = sendmsg(clt2_sk, &outmessage, 0); + if ((-1 != error) || (EINVAL != errno)) + tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_ABORT flag " + "error:%d, errno:%d", error, errno); + + tst_resm(TPASS, "sendmsg with SCTP_ABORT flag"); + + /* Verify that a normal message can be sent using sendmsg. */ + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + out_iov.iov_base = message; + out_iov.iov_len = strlen(message) + 1; + sinfo->sinfo_flags = 0; + test_sendmsg(clt2_sk, &outmessage, 0, strlen(message)+1); + + test_recv(accept2_sk, msgbuf, 100, 0); + + tst_resm(TPASS, "sendmsg with no flags"); + + close(clt2_sk); + close(accept2_sk); + close(listen_sk); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/func_tests/test_timetolive.c b/src/func_tests/test_timetolive.c new file mode 100644 index 0000000..d9bdf1b --- /dev/null +++ b/src/func_tests/test_timetolive.c @@ -0,0 +1,406 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2001, 2003 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2001 Intel Corp. + * Copyright (c) 2001 Nokia, Inc. + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * Jon Grimm + * Sridhar Samudrala + */ + +/* + * This is a basic functional test for the SCTP kernel + * implementation of sndrcvinfo.sinfo_timetolive. + * + * 1) Create two sockets, the listening socket sets its RECVBUF small + * 2) Create a connection. Send enough data to the non-reading listener + * to fill the RCVBUF. + * 5) Set sinfo_timetolive on a message and send. + * 6) Disable sinfo_timetolive on a message and send. + * 7) Wait sinfo_timetolive. + * 8) Read out all the data at the receiver. + * 9) Make sure timed out message did not make it. + * 10) Make sure that the message with no timeout makes it to the receiver. + * + * Also test with SEND_FAILED notifications. Also, use a fragmented + * message so as to also exercise the SEND_FAILED of fragmentation + * code. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *TCID = __FILE__; +int TST_TOTAL = 6; +int TST_CNT = 0; + +/* This is the size of our RCVBUF */ +#define SMALL_RCVBUF 3000 + +/* MAX segment size */ +#define SMALL_MAXSEG 100 + +/* RWND_SLOP is the extra data that fills up the rwnd */ +#define RWND_SLOP 100 +static char *fillmsg = NULL; +static char *ttlmsg = "This should time out!\n"; +static char *nottlmsg = "This should NOT time out!\n"; +static char ttlfrag[SMALL_MAXSEG*3] = {0}; +static char *message = "Hello world\n"; + +int main(int argc, char *argv[]) +{ + int sk1, sk2; + sockaddr_storage_t loop1; + sockaddr_storage_t loop2; + struct iovec iov; + struct msghdr inmessage; + struct msghdr outmessage; + char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + struct iovec out_iov; + int error; + int pf_class, af_family; + uint32_t ppid; + uint32_t stream; + sctp_assoc_t associd1, associd2; + struct sctp_assoc_change *sac; + struct sctp_event_subscribe subscribe; + char *big_buffer; + int offset; + struct sctp_send_failed *ssf; + int len; /* Really becomes 2xlen when set. */ + int orig_len; + struct sctp_status gstatus; + + /* Rather than fflush() throughout the code, set stdout to + * be unbuffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Set some basic values which depend on the address family. */ +#if TEST_V6 + pf_class = PF_INET6; + af_family = AF_INET6; + + loop1.v6.sin6_family = AF_INET6; + loop1.v6.sin6_addr = in6addr_loopback; + loop1.v6.sin6_port = htons(SCTP_TESTPORT_1); + + loop2.v6.sin6_family = AF_INET6; + loop2.v6.sin6_addr = in6addr_loopback; + loop2.v6.sin6_port = htons(SCTP_TESTPORT_2); +#else + pf_class = PF_INET; + af_family = AF_INET; + + loop1.v4.sin_family = AF_INET; + loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + loop1.v4.sin_port = htons(SCTP_TESTPORT_1); + + loop2.v4.sin_family = AF_INET; + loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; + loop2.v4.sin_port = htons(SCTP_TESTPORT_2); +#endif /* TEST_V6 */ + + /* Create the two endpoints which will talk to each other. */ + sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); + + len = sizeof(int); + error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &orig_len, + &len); + if (error) + tst_brkm(TBROK, tst_exit, "can't get rcvbuf size: %s", + strerror(errno)); + /* Set the MAXSEG to something smallish. */ + { + int val = SMALL_MAXSEG; + test_setsockopt(sk1, SCTP_MAXSEG, &val, sizeof(val)); + } + + memset(&subscribe, 0, sizeof(subscribe)); + subscribe.sctp_data_io_event = 1; + subscribe.sctp_association_event = 1; + subscribe.sctp_send_failure_event = 1; + test_setsockopt(sk1, SCTP_EVENTS, &subscribe, sizeof(subscribe)); + test_setsockopt(sk2, SCTP_EVENTS, &subscribe, sizeof(subscribe)); + + /* Bind these sockets to the test ports. */ + test_bind(sk1, &loop1.sa, sizeof(loop1)); + test_bind(sk2, &loop2.sa, sizeof(loop2)); + + /* + * This code sets the associations RWND very small so we can + * fill it. It does this by manipulating the rcvbuf as follows: + * 1) Reduce the rcvbuf size on the socket + * 2) create an association so that we advertize rcvbuf/2 as + * our initial rwnd + * 3) raise the rcvbuf value so that we don't drop data wile + * receiving later data + */ + len = SMALL_RCVBUF; + error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &len, + sizeof(len)); + if (error) + tst_brkm(TBROK, tst_exit, "setsockopt(SO_RCVBUF): %s", + strerror(errno)); + + /* Mark sk2 as being able to accept new associations. */ + test_listen(sk2, 1); + + /* Send the first message. This will create the association. */ + outmessage.msg_name = &loop2; + outmessage.msg_namelen = sizeof(loop2); + outmessage.msg_iov = &out_iov; + outmessage.msg_iovlen = 1; + outmessage.msg_control = outcmsg; + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid = rand(); /* Choose an arbitrary value. */ + stream = 1; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + outmessage.msg_iov->iov_base = message; + outmessage.msg_iov->iov_len = strlen(message) + 1; + test_sendmsg(sk1, &outmessage, 0, strlen(message)+1); + + /* Initialize inmessage for all receives. */ + big_buffer = test_malloc(REALLY_BIG); + memset(&inmessage, 0, sizeof(inmessage)); + iov.iov_base = big_buffer; + iov.iov_len = REALLY_BIG; + inmessage.msg_iov = &iov; + inmessage.msg_iovlen = 1; + inmessage.msg_control = incmsg; + + /* Get the communication up message on sk2. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + associd2 = sac->sac_assoc_id; + + /* Get the communication up message on sk1. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk1, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_COMM_UP); + sac = (struct sctp_assoc_change *)iov.iov_base; + associd1 = sac->sac_assoc_id; + + /* restore the rcvbuffer size for the receiving socket */ + error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &orig_len, + sizeof(orig_len)); + + if (error) + tst_brkm(TBROK, tst_exit, "setsockopt(SO_RCVBUF): %s", + strerror(errno)); + + /* Get the first data message which was sent. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(message) + 1, + MSG_EOR, stream, ppid); + + /* Figure out how big to make our fillmsg */ + len = sizeof(struct sctp_status); + memset(&gstatus,0,sizeof(struct sctp_status)); + gstatus.sstat_assoc_id = associd1; + error = getsockopt(sk1, IPPROTO_SCTP, SCTP_STATUS, &gstatus, &len); + + if (error) + tst_brkm(TBROK, tst_exit, "can't get rwnd size: %s", + strerror(errno)); + tst_resm(TINFO, "Creating fillmsg of size %d", + gstatus.sstat_rwnd+RWND_SLOP); + fillmsg = malloc(gstatus.sstat_rwnd+RWND_SLOP); + + /* Send a fillmsg */ + outmessage.msg_controllen = sizeof(outcmsg); + outmessage.msg_flags = 0; + cmsg = CMSG_FIRSTHDR(&outmessage); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + outmessage.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); + ppid++; + stream++; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + memset(fillmsg, 'X', gstatus.sstat_rwnd+RWND_SLOP); + fillmsg[gstatus.sstat_rwnd+RWND_SLOP-1] = '\0'; + outmessage.msg_iov->iov_base = fillmsg; + outmessage.msg_iov->iov_len = gstatus.sstat_rwnd+RWND_SLOP; + outmessage.msg_name = NULL; + outmessage.msg_namelen = 0; + sinfo->sinfo_assoc_id = associd1; + sinfo->sinfo_timetolive = 0; + test_sendmsg(sk1, &outmessage, MSG_NOSIGNAL, + gstatus.sstat_rwnd+RWND_SLOP); + + /* Now send the message with timeout. */ + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + outmessage.msg_iov->iov_base = ttlmsg; + outmessage.msg_iov->iov_len = strlen(ttlmsg) + 1; + outmessage.msg_name = NULL; + outmessage.msg_namelen = 0; + sinfo->sinfo_assoc_id = associd1; + sinfo->sinfo_timetolive = 2000; + test_sendmsg(sk1, &outmessage, MSG_NOSIGNAL, strlen(ttlmsg) + 1); + + tst_resm(TPASS, "Send a message with timeout"); + + /* Next send a message with no timeout. */ + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + outmessage.msg_iov->iov_base = nottlmsg; + outmessage.msg_iov->iov_len = strlen(nottlmsg) + 1; + outmessage.msg_name = NULL; + outmessage.msg_namelen = 0; + sinfo->sinfo_assoc_id = associd1; + sinfo->sinfo_timetolive = 0; + test_sendmsg(sk1, &outmessage, MSG_NOSIGNAL, strlen(nottlmsg)+1); + + tst_resm(TPASS, "Send a message with no timeout"); + + /* And finally a fragmented message that will time out. */ + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_stream = stream; + memset(ttlfrag, '0', sizeof(ttlfrag)); + ttlfrag[sizeof(ttlfrag)-1] = '\0'; + outmessage.msg_iov->iov_base = ttlfrag; + outmessage.msg_iov->iov_len = sizeof(ttlfrag); + outmessage.msg_name = NULL; + outmessage.msg_namelen = 0; + sinfo->sinfo_assoc_id = associd1; + sinfo->sinfo_timetolive = 2000; + test_sendmsg(sk1, &outmessage, MSG_NOSIGNAL, sizeof(ttlfrag)); + + tst_resm(TPASS, "Send a fragmented message with timeout"); + + /* Sleep waiting for the message to time out. */ + tst_resm(TINFO, " ** SLEEPING for 3 seconds **"); + sleep(3); + + /* Read the fillmsg snuck in between the ttl'd messages. */ + do { + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + } while (!(inmessage.msg_flags & MSG_EOR)); + + /* Now get the message that did NOT time out. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_data(&inmessage, error, strlen(nottlmsg) + 1, + MSG_EOR, stream, ppid); + if (0 != strncmp(iov.iov_base, nottlmsg, strlen(nottlmsg)+1)) + tst_brkm(TBROK, tst_exit, "Received Wrong Message !!!"); + + tst_resm(TPASS, "Receive message with no timeout"); + + /* Get the SEND_FAILED notification for the message that DID + * time out. + */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk1, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_send_failed) + + strlen(ttlmsg) + 1, + SCTP_SEND_FAILED, 0); + ssf = (struct sctp_send_failed *)iov.iov_base; + if (0 != strncmp(ttlmsg, (char *)ssf->ssf_data, strlen(ttlmsg) + 1)) + tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch"); + + tst_resm(TPASS, "Receive SEND_FAILED for message with timeout"); + + /* Get the SEND_FAILED notification for the fragmented message that + * DID time out. + */ + offset = 0; + do { + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk1, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_send_failed) + + SMALL_MAXSEG, + SCTP_SEND_FAILED, 0); + ssf = (struct sctp_send_failed *)iov.iov_base; + if (0 != strncmp(&ttlfrag[offset], (char *)ssf->ssf_data, + SMALL_MAXSEG)) + tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch"); + offset += SMALL_MAXSEG; + } while (!(ssf->ssf_info.sinfo_flags & 0x01)); /* LAST_FRAG */ + + tst_resm(TPASS, "Receive SEND_FAILED for fragmented message with " + "timeout"); + + /* Shut down the link. */ + close(sk1); + + /* Get the shutdown complete notification. */ + inmessage.msg_controllen = sizeof(incmsg); + error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); + test_check_msg_notification(&inmessage, error, + sizeof(struct sctp_assoc_change), + SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP); + + close(sk2); + + /* Indicate successful completion. */ + return 0; +} diff --git a/src/include/Makefile.am b/src/include/Makefile.am new file mode 100644 index 0000000..38abaec --- /dev/null +++ b/src/include/Makefile.am @@ -0,0 +1,5 @@ + +include $(top_srcdir)/Makefile.vars +include $(top_srcdir)/Makefile.rules + +SUBDIRS = netinet diff --git a/src/include/Makefile.in b/src/include/Makefile.in new file mode 100644 index 0000000..f350388 --- /dev/null +++ b/src/include/Makefile.in @@ -0,0 +1,510 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*-makefile-*- +# +# type: deep, strictness: gnu +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.rules $(top_srcdir)/Makefile.vars +subdir = src/include +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +MAINTAINERCLEANFILES = Makefile.in +DISTCLEANFILES = \\\#*\\\# Makefile +CLEANFILES = +MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io +EXTRA_DIST = +LATEX = @LATEX@ +DVIPS = @DVIPS@ +DVIPDFM = @DVIPDFM@ +ENSCRIPTBIN = @ENSCRIPTBIN@ +PS2PDF = @PS2PDF@ +edit = @sed \ + -e "s|\@bindir\@|$(bindir)|" \ + -e "s|\@libdir\@|$(libdir)|" \ + -e "s|\@PACKAGE\@|$(PACKAGE)|" + +SUBDIRS = netinet +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.vars $(top_srcdir)/Makefile.rules $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/include/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/include/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/../.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(mkdir_p) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ + clean clean-generic clean-libtool clean-recursive ctags \ + ctags-recursive distclean distclean-generic distclean-libtool \ + distclean-recursive distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic maintainer-clean-recursive \ + mostlyclean mostlyclean-generic mostlyclean-libtool \ + mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-info-am + + +# -*-makefile-*- +# +# Generate pre-parsed C code. +%.i: %.c + $(COMPILE) -E -c $^ -o $@ + +.PRECIOUS: %.i +%.ci: %.i + -grep -v -e "^#" -e "^ *$$" $^ | indent > $@ + mv -f $@ $^ +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/include/netinet/Makefile.am b/src/include/netinet/Makefile.am new file mode 100644 index 0000000..8aa9429 --- /dev/null +++ b/src/include/netinet/Makefile.am @@ -0,0 +1,14 @@ + +include $(top_srcdir)/Makefile.vars +include $(top_srcdir)/Makefile.rules + +libcnetinetdir = $(includedir)/netinet + + +## FIXME: Your stuff here + +# Supposing this is part of the development package, header for our +# API. +include_HEADERS = + +libcnetinet_HEADERS = sctp.h diff --git a/src/include/netinet/Makefile.in b/src/include/netinet/Makefile.in new file mode 100644 index 0000000..3f63baf --- /dev/null +++ b/src/include/netinet/Makefile.in @@ -0,0 +1,457 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*-makefile-*- +# +# type: deep, strictness: gnu + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(include_HEADERS) $(libcnetinet_HEADERS) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.rules $(top_srcdir)/Makefile.vars +subdir = src/include/netinet +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(includedir)" \ + "$(DESTDIR)$(libcnetinetdir)" +includeHEADERS_INSTALL = $(INSTALL_HEADER) +libcnetinetHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(include_HEADERS) $(libcnetinet_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +MAINTAINERCLEANFILES = Makefile.in +DISTCLEANFILES = \\\#*\\\# Makefile +CLEANFILES = +MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io +EXTRA_DIST = +LATEX = @LATEX@ +DVIPS = @DVIPS@ +DVIPDFM = @DVIPDFM@ +ENSCRIPTBIN = @ENSCRIPTBIN@ +PS2PDF = @PS2PDF@ +edit = @sed \ + -e "s|\@bindir\@|$(bindir)|" \ + -e "s|\@libdir\@|$(libdir)|" \ + -e "s|\@PACKAGE\@|$(PACKAGE)|" + +libcnetinetdir = $(includedir)/netinet + +# Supposing this is part of the development package, header for our +# API. +include_HEADERS = +libcnetinet_HEADERS = sctp.h +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.vars $(top_srcdir)/Makefile.rules $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/include/netinet/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/include/netinet/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ + $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ + rm -f "$(DESTDIR)$(includedir)/$$f"; \ + done +install-libcnetinetHEADERS: $(libcnetinet_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(libcnetinetdir)" || $(mkdir_p) "$(DESTDIR)$(libcnetinetdir)" + @list='$(libcnetinet_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(libcnetinetHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libcnetinetdir)/$$f'"; \ + $(libcnetinetHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libcnetinetdir)/$$f"; \ + done + +uninstall-libcnetinetHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(libcnetinet_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(libcnetinetdir)/$$f'"; \ + rm -f "$(DESTDIR)$(libcnetinetdir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/../../.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(includedir)" "$(DESTDIR)$(libcnetinetdir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS install-libcnetinetHEADERS + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-includeHEADERS uninstall-info-am \ + uninstall-libcnetinetHEADERS + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool ctags distclean distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am \ + install-includeHEADERS install-info install-info-am \ + install-libcnetinetHEADERS install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-includeHEADERS uninstall-info-am \ + uninstall-libcnetinetHEADERS + + +# -*-makefile-*- +# +# Generate pre-parsed C code. +%.i: %.c + $(COMPILE) -E -c $^ -o $@ + +.PRECIOUS: %.i +%.ci: %.i + -grep -v -e "^#" -e "^ *$$" $^ | indent > $@ + mv -f $@ $^ +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/include/netinet/sctp.h b/src/include/netinet/sctp.h new file mode 100644 index 0000000..ae557a5 --- /dev/null +++ b/src/include/netinet/sctp.h @@ -0,0 +1,841 @@ +/* SCTP kernel Implementation: User API extensions. + * + * sctp.h + * + * Distributed under the terms of the LGPL v2.1 as described in + * http://www.gnu.org/copyleft/lesser.txt + * + * This file is part of the user library that offers support for the + * Linux Kernel SCTP Implementation. The main purpose of this + * code is to provide the SCTP Socket API mappings for user + * application to interface with SCTP in kernel. + * + * This header represents the structures and constants needed to support + * the SCTP Extension to the Sockets API. + * + * (C) Copyright IBM Corp. 2001, 2004 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * + * Written or modified by: + * La Monte H.P. Yarroll + * R. Stewart + * K. Morneau + * Q. Xie + * Karl Knutson + * Jon Grimm + * Daisy Chang + * Inaky Perez-Gonzalez + * Sridhar Samudrala + * Vlad Yasevich + */ + +#ifndef __linux_sctp_h__ +#define __linux_sctp_h__ + +#include +#include +#include + +__BEGIN_DECLS + +typedef __s32 sctp_assoc_t; + +/* Socket option layer for SCTP */ +#ifndef SOL_SCTP +#define SOL_SCTP 132 +#endif + +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif + +/* 9. Preprocessor constants */ +#define HAVE_SCTP +#define HAVE_KERNEL_SCTP +#define HAVE_SCTP_MULTIBUF +#define HAVE_SCTP_NOCONNECT +#define HAVE_SCTP_PRSCTP +#define HAVE_SCTP_ADDIP +#define HAVE_SCTP_CANSET_PRIMARY + +/* The following symbols come from the Sockets API Extensions for + * SCTP . + */ +enum sctp_optname { + SCTP_RTOINFO, +#define SCTP_RTOINFO SCTP_RTOINFO + SCTP_ASSOCINFO, +#define SCTP_ASSOCINFO SCTP_ASSOCINFO + SCTP_INITMSG, +#define SCTP_INITMSG SCTP_INITMSG + SCTP_NODELAY, /* Get/set nodelay option. */ +#define SCTP_NODELAY SCTP_NODELAY + SCTP_AUTOCLOSE, +#define SCTP_AUTOCLOSE SCTP_AUTOCLOSE + SCTP_SET_PEER_PRIMARY_ADDR, +#define SCTP_SET_PEER_PRIMARY_ADDR SCTP_SET_PEER_PRIMARY_ADDR + SCTP_PRIMARY_ADDR, +#define SCTP_PRIMARY_ADDR SCTP_PRIMARY_ADDR + SCTP_ADAPTATION_LAYER, +#define SCTP_ADAPTATION_LAYER SCTP_ADAPTATION_LAYER + SCTP_DISABLE_FRAGMENTS, +#define SCTP_DISABLE_FRAGMENTS SCTP_DISABLE_FRAGMENTS + SCTP_PEER_ADDR_PARAMS, +#define SCTP_PEER_ADDR_PARAMS SCTP_PEER_ADDR_PARAMS + SCTP_DEFAULT_SEND_PARAM, +#define SCTP_DEFAULT_SEND_PARAM SCTP_DEFAULT_SEND_PARAM + SCTP_EVENTS, +#define SCTP_EVENTS SCTP_EVENTS + SCTP_I_WANT_MAPPED_V4_ADDR, /* Turn on/off mapped v4 addresses */ +#define SCTP_I_WANT_MAPPED_V4_ADDR SCTP_I_WANT_MAPPED_V4_ADDR + SCTP_MAXSEG, /* Get/set maximum fragment. */ +#define SCTP_MAXSEG SCTP_MAXSEG + SCTP_STATUS, +#define SCTP_STATUS SCTP_STATUS + SCTP_GET_PEER_ADDR_INFO, +#define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO + SCTP_DELAYED_ACK_TIME, +#define SCTP_DELAYED_ACK_TIME SCTP_DELAYED_ACK_TIME + SCTP_CONTEXT, /* Receive Context */ +#define SCTP_CONTEXT SCTP_CONTEXT + SCTP_FRAGMENT_INTERLEAVE, +#define SCTP_FRAGMENT_INTERLEAVE SCTP_FRAGMENT_INTERLEAVE + SCTP_PARTIAL_DELIVERY_POINT, /* Set/Get partial delivery point */ +#define SCTP_PARTIAL_DELIVERY_POINT SCTP_PARTIAL_DELIVERY_POINT + SCTP_MAX_BURST, /* Set/Get max burst */ +#define SCTP_MAX_BURST SCTP_MAX_BURST + SCTP_AUTH_CHUNK, /* Set only: add a chunk type to authenticat */ +#define SCTP_AUTH_CHUNK SCTP_AUTH_CHUNK + SCTP_HMAC_IDENT, +#define SCTP_HMAC_IDENT SCTP_HMAC_IDENT + SCTP_AUTH_KEY, +#define SCTP_AUTH_KEY SCTP_AUTH_KEY + SCTP_AUTH_ACTIVE_KEY, +#define SCTP_AUTH_ACTIVE_KEY SCTP_AUTH_ACTIVE_KEY + SCTP_AUTH_DELETE_KEY, +#define SCTP_AUTH_DELETE_KEY SCTP_AUTH_DELETE_KEY + SCTP_PEER_AUTH_CHUNKS, /* Read only */ +#define SCTP_PEER_AUTH_CHUNKS SCTP_PEER_AUTH_CHUNKS + SCTP_LOCAL_AUTH_CHUNKS, /* Read only */ +#define SCTP_LOCAL_AUTH_CHUNKS SCTP_LOCAL_AUTH_CHUNKS + + + /* Internal Socket Options. Some of the sctp library functions are + * implemented using these socket options. + */ + SCTP_SOCKOPT_BINDX_ADD = 100,/* BINDX requests for adding addresses. */ +#define SCTP_SOCKOPT_BINDX_ADD SCTP_SOCKOPT_BINDX_ADD + SCTP_SOCKOPT_BINDX_REM, /* BINDX requests for removing addresses. */ +#define SCTP_SOCKOPT_BINDX_REM SCTP_SOCKOPT_BINDX_REM + SCTP_SOCKOPT_PEELOFF, /* peel off association. */ +#define SCTP_SOCKOPT_PEELOFF SCTP_SOCKOPT_PEELOFF + SCTP_GET_PEER_ADDRS_NUM_OLD, /* Get number of peer addresss. */ +#define SCTP_GET_PEER_ADDRS_NUM_OLD SCTP_GET_PEER_ADDRS_NUM_OLD + SCTP_GET_PEER_ADDRS_OLD, /* Get all peer addresss. */ +#define SCTP_GET_PEER_ADDRS_OLD SCTP_GET_PEER_ADDRS_OLD + SCTP_GET_LOCAL_ADDRS_NUM_OLD, /* Get number of local addresss. */ +#define SCTP_GET_LOCAL_ADDRS_NUM_OLD SCTP_GET_LOCAL_ADDRS_NUM_OLD + SCTP_GET_LOCAL_ADDRS_OLD, /* Get all local addresss. */ +#define SCTP_GET_LOCAL_ADDRS_OLD SCTP_GET_LOCAL_ADDRS_OLD + SCTP_SOCKOPT_CONNECTX_OLD, /* CONNECTX requests. OLD implementation */ +#define SCTP_SOCKOPT_CONNECTX_OLD SCTP_SOCKOPT_CONNECTX_OLD + SCTP_GET_PEER_ADDRS, /* Get all peer addresss. */ +#define SCTP_GET_PEER_ADDRS SCTP_GET_PEER_ADDRS + SCTP_GET_LOCAL_ADDRS, /* Get all local addresss. */ +#define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS + SCTP_SOCKOPT_CONNECTX, /* CONNECTX requests. NEW implementation */ +#define SCTP_SOCKOPT_CONNECTX SCTP_SOCKOPT_CONNECTX +}; + +/* + * 5.2.1 SCTP Initiation Structure (SCTP_INIT) + * + * This cmsghdr structure provides information for initializing new + * SCTP associations with sendmsg(). The SCTP_INITMSG socket option + * uses this same data structure. This structure is not used for + * recvmsg(). + * + * cmsg_level cmsg_type cmsg_data[] + * ------------ ------------ ---------------------- + * IPPROTO_SCTP SCTP_INIT struct sctp_initmsg + * + */ +struct sctp_initmsg { + __u16 sinit_num_ostreams; + __u16 sinit_max_instreams; + __u16 sinit_max_attempts; + __u16 sinit_max_init_timeo; +}; + +/* + * 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) + * + * This cmsghdr structure specifies SCTP options for sendmsg() and + * describes SCTP header information about a received message through + * recvmsg(). + * + * cmsg_level cmsg_type cmsg_data[] + * ------------ ------------ ---------------------- + * IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo + * + */ +struct sctp_sndrcvinfo { + __u16 sinfo_stream; + __u16 sinfo_ssn; + __u16 sinfo_flags; + __u32 sinfo_ppid; + __u32 sinfo_context; + __u32 sinfo_timetolive; + __u32 sinfo_tsn; + __u32 sinfo_cumtsn; + sctp_assoc_t sinfo_assoc_id; +}; + +/* + * sinfo_flags: 16 bits (unsigned integer) + * + * This field may contain any of the following flags and is composed of + * a bitwise OR of these values. + */ + +enum sctp_sinfo_flags { + SCTP_UNORDERED = 1, /* Send/receive message unordered. */ + SCTP_ADDR_OVER = 2, /* Override the primary destination. */ + SCTP_ABORT=4, /* Send an ABORT message to the peer. */ + SCTP_EOF=MSG_FIN, /* Initiate graceful shutdown process. */ +}; + + +typedef union { + __u8 raw; + struct sctp_initmsg init; + struct sctp_sndrcvinfo sndrcv; +} sctp_cmsg_data_t; + +/* These are cmsg_types. */ +typedef enum sctp_cmsg_type { + SCTP_INIT, /* 5.2.1 SCTP Initiation Structure */ +#define SCTP_INIT SCTP_INIT + SCTP_SNDRCV, /* 5.2.2 SCTP Header Information Structure */ +#define SCTP_SNDRCV SCTP_SNDRCV +} sctp_cmsg_t; + + +/* + * 5.3.1.1 SCTP_ASSOC_CHANGE + * + * Communication notifications inform the ULP that an SCTP association + * has either begun or ended. The identifier for a new association is + * provided by this notificaion. The notification information has the + * following format: + * + */ +struct sctp_assoc_change { + __u16 sac_type; + __u16 sac_flags; + __u32 sac_length; + __u16 sac_state; + __u16 sac_error; + __u16 sac_outbound_streams; + __u16 sac_inbound_streams; + sctp_assoc_t sac_assoc_id; + __u8 sac_info[0]; +}; + +/* + * sac_state: 32 bits (signed integer) + * + * This field holds one of a number of values that communicate the + * event that happened to the association. They include: + * + * Note: The following state names deviate from the API draft as + * the names clash too easily with other kernel symbols. + */ +enum sctp_sac_state { + SCTP_COMM_UP, + SCTP_COMM_LOST, + SCTP_RESTART, + SCTP_SHUTDOWN_COMP, + SCTP_CANT_STR_ASSOC, +}; + +/* + * 5.3.1.2 SCTP_PEER_ADDR_CHANGE + * + * When a destination address on a multi-homed peer encounters a change + * an interface details event is sent. The information has the + * following structure: + */ +struct sctp_paddr_change { + __u16 spc_type; + __u16 spc_flags; + __u32 spc_length; + struct sockaddr_storage spc_aaddr; + int spc_state; + int spc_error; + sctp_assoc_t spc_assoc_id; +} __attribute__((packed, aligned(4))); + +/* + * spc_state: 32 bits (signed integer) + * + * This field holds one of a number of values that communicate the + * event that happened to the address. They include: + */ +enum sctp_spc_state { + SCTP_ADDR_AVAILABLE, + SCTP_ADDR_UNREACHABLE, + SCTP_ADDR_REMOVED, + SCTP_ADDR_ADDED, + SCTP_ADDR_MADE_PRIM, + SCTP_ADDR_CONFIRMED, +}; + + +/* + * 5.3.1.3 SCTP_REMOTE_ERROR + * + * A remote peer may send an Operational Error message to its peer. + * This message indicates a variety of error conditions on an + * association. The entire error TLV as it appears on the wire is + * included in a SCTP_REMOTE_ERROR event. Please refer to the SCTP + * specification [SCTP] and any extensions for a list of possible + * error formats. SCTP error TLVs have the format: + */ +struct sctp_remote_error { + __u16 sre_type; + __u16 sre_flags; + __u32 sre_length; + __u16 sre_error; + sctp_assoc_t sre_assoc_id; + __u8 sre_data[0]; +}; + + +/* + * 5.3.1.4 SCTP_SEND_FAILED + * + * If SCTP cannot deliver a message it may return the message as a + * notification. + */ +struct sctp_send_failed { + __u16 ssf_type; + __u16 ssf_flags; + __u32 ssf_length; + __u32 ssf_error; + struct sctp_sndrcvinfo ssf_info; + sctp_assoc_t ssf_assoc_id; + __u8 ssf_data[0]; +}; + +/* + * ssf_flags: 16 bits (unsigned integer) + * + * The flag value will take one of the following values + * + * SCTP_DATA_UNSENT - Indicates that the data was never put on + * the wire. + * + * SCTP_DATA_SENT - Indicates that the data was put on the wire. + * Note that this does not necessarily mean that the + * data was (or was not) successfully delivered. + */ +enum sctp_ssf_flags { + SCTP_DATA_UNSENT, + SCTP_DATA_SENT, +}; + +/* + * 5.3.1.5 SCTP_SHUTDOWN_EVENT + * + * When a peer sends a SHUTDOWN, SCTP delivers this notification to + * inform the application that it should cease sending data. + */ +struct sctp_shutdown_event { + __u16 sse_type; + __u16 sse_flags; + __u32 sse_length; + sctp_assoc_t sse_assoc_id; +}; + +/* + * 5.3.1.6 SCTP_ADAPTATION_INDICATION + * + * When a peer sends a Adaptation Layer Indication parameter , SCTP + * delivers this notification to inform the application + * that of the peers requested adaptation layer. + */ +struct sctp_adaptation_event { + __u16 sai_type; + __u16 sai_flags; + __u32 sai_length; + __u32 sai_adaptation_ind; + sctp_assoc_t sai_assoc_id; +}; + +/* + * 5.3.1.7 SCTP_PARTIAL_DELIVERY_EVENT + * + * When a receiver is engaged in a partial delivery of a + * message this notification will be used to indicate + * various events. + */ +struct sctp_pdapi_event { + __u16 pdapi_type; + __u16 pdapi_flags; + __u32 pdapi_length; + __u32 pdapi_indication; + sctp_assoc_t pdapi_assoc_id; +}; + +enum { SCTP_PARTIAL_DELIVERY_ABORTED=0, }; + +/* +* 5.3.1.8. SCTP_AUTHENTICATION_EVENT +* +* When a receiver is using authentication this message will provide +* notifications regarding new keys being made active as well as errors. +*/ + +struct sctp_authkey_event { + __u16 auth_type; + __u16 auth_flags; + __u32 auth_length; + __u16 auth_keynumber; + __u16 auth_altkeynumber; + __u32 auth_indication; + sctp_assoc_t auth_assoc_id; +}; + +enum { SCTP_AUTH_NEWKEY = 0, }; + + +/* + * Described in Section 7.3 + * Ancillary Data and Notification Interest Options + */ +struct sctp_event_subscribe { + __u8 sctp_data_io_event; + __u8 sctp_association_event; + __u8 sctp_address_event; + __u8 sctp_send_failure_event; + __u8 sctp_peer_error_event; + __u8 sctp_shutdown_event; + __u8 sctp_partial_delivery_event; + __u8 sctp_adaptation_layer_event; + __u8 sctp_authentication_event; +}; + +/* + * 5.3.1 SCTP Notification Structure + * + * The notification structure is defined as the union of all + * notification types. + * + */ +union sctp_notification { + struct { + __u16 sn_type; /* Notification type. */ + __u16 sn_flags; + __u32 sn_length; + } sn_header; + struct sctp_assoc_change sn_assoc_change; + struct sctp_paddr_change sn_paddr_change; + struct sctp_remote_error sn_remote_error; + struct sctp_send_failed sn_send_failed; + struct sctp_shutdown_event sn_shutdown_event; + struct sctp_adaptation_event sn_adaptation_event; + struct sctp_pdapi_event sn_pdapi_event; + struct sctp_authkey_event sn_authkey_event; +}; + +/* Section 5.3.1 + * All standard values for sn_type flags are greater than 2^15. + * Values from 2^15 and down are reserved. + */ + +enum sctp_sn_type { + SCTP_SN_TYPE_BASE = (1<<15), + SCTP_ASSOC_CHANGE, + SCTP_PEER_ADDR_CHANGE, + SCTP_SEND_FAILED, + SCTP_REMOTE_ERROR, + SCTP_SHUTDOWN_EVENT, + SCTP_PARTIAL_DELIVERY_EVENT, + SCTP_ADAPTATION_INDICATION, + SCTP_AUTHENTICATION_INDICATION, +}; + +/* Notification error codes used to fill up the error fields in some + * notifications. + * SCTP_PEER_ADDRESS_CHAGE : spc_error + * SCTP_ASSOC_CHANGE : sac_error + * These names should be potentially included in the draft 04 of the SCTP + * sockets API specification. + */ +typedef enum sctp_sn_error { + SCTP_FAILED_THRESHOLD, + SCTP_RECEIVED_SACK, + SCTP_HEARTBEAT_SUCCESS, + SCTP_RESPONSE_TO_USER_REQ, + SCTP_INTERNAL_ERROR, + SCTP_SHUTDOWN_GUARD_EXPIRES, + SCTP_PEER_FAULTY, +} sctp_sn_error_t; + +/* + * 7.1.1 Retransmission Timeout Parameters (SCTP_RTOINFO) + * + * The protocol parameters used to initialize and bound retransmission + * timeout (RTO) are tunable. See [SCTP] for more information on how + * these parameters are used in RTO calculation. + */ +struct sctp_rtoinfo { + sctp_assoc_t srto_assoc_id; + __u32 srto_initial; + __u32 srto_max; + __u32 srto_min; +}; + +/* + * 7.1.2 Association Parameters (SCTP_ASSOCINFO) + * + * This option is used to both examine and set various association and + * endpoint parameters. + */ +struct sctp_assocparams { + sctp_assoc_t sasoc_assoc_id; + __u16 sasoc_asocmaxrxt; + __u16 sasoc_number_peer_destinations; + __u32 sasoc_peer_rwnd; + __u32 sasoc_local_rwnd; + __u32 sasoc_cookie_life; +}; + +/* + * 7.1.9 Set Peer Primary Address (SCTP_SET_PEER_PRIMARY_ADDR) + * + * Requests that the peer mark the enclosed address as the association + * primary. The enclosed address must be one of the association's + * locally bound addresses. The following structure is used to make a + * set primary request: + */ +struct sctp_setpeerprim { + sctp_assoc_t sspp_assoc_id; + struct sockaddr_storage sspp_addr; +} __attribute__((packed, aligned(4))); + +/* + * 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR) + * + * Requests that the local SCTP stack use the enclosed peer address as + * the association primary. The enclosed address must be one of the + * association peer's addresses. The following structure is used to + * make a set peer primary request: + */ +struct sctp_setprim { + sctp_assoc_t ssp_assoc_id; + struct sockaddr_storage ssp_addr; +} __attribute__((packed, aligned(4))); + +/* For backward compatibility use, define the old name too */ +#define sctp_prim sctp_setprim + +/* + * 7.1.11 Set Adaptation Layer Indicator (SCTP_ADAPTATION_LAYER) + * + * Requests that the local endpoint set the specified Adaptation Layer + * Indication parameter for all future INIT and INIT-ACK exchanges. + */ +struct sctp_setadaptation { + __u32 ssb_adaptation_ind; +}; + +/* + * 7.1.13 Peer Address Parameters (SCTP_PEER_ADDR_PARAMS) + * + * Applications can enable or disable heartbeats for any peer address + * of an association, modify an address's heartbeat interval, force a + * heartbeat to be sent immediately, and adjust the address's maximum + * number of retransmissions sent before an address is considered + * unreachable. The following structure is used to access and modify an + * address's parameters: + */ +enum sctp_spp_flags { + SPP_HB_ENABLE = 1<<0, /*Enable heartbeats*/ + SPP_HB_DISABLE = 1<<1, /*Disable heartbeats*/ + SPP_HB = SPP_HB_ENABLE | SPP_HB_DISABLE, + SPP_HB_DEMAND = 1<<2, /*Send heartbeat immediately*/ + SPP_PMTUD_ENABLE = 1<<3, /*Enable PMTU discovery*/ + SPP_PMTUD_DISABLE = 1<<4, /*Disable PMTU discovery*/ + SPP_PMTUD = SPP_PMTUD_ENABLE | SPP_PMTUD_DISABLE, + SPP_SACKDELAY_ENABLE = 1<<5, /*Enable SACK*/ + SPP_SACKDELAY_DISABLE = 1<<6, /*Disable SACK*/ + SPP_SACKDELAY = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE, + SPP_HB_TIME_IS_ZERO = 1<<7, /* Set HB delay to 0 */ +}; + +struct sctp_paddrparams { + sctp_assoc_t spp_assoc_id; + struct sockaddr_storage spp_address; + __u32 spp_hbinterval; + __u16 spp_pathmaxrxt; + __u32 spp_pathmtu; + __u32 spp_sackdelay; + __u32 spp_flags; +} __attribute__((packed, aligned(4))); + +/* + * 7.1.18. Add a chunk that must be authenticated (SCTP_AUTH_CHUNK) + * + * This set option adds a chunk type that the user is requesting to be + * received only in an authenticated way. Changes to the list of chunks + * will only effect future associations on the socket. + */ +struct sctp_authchunk { + __u8 sauth_chunk; +}; + +/* + * 7.1.19. Get or set the list of supported HMAC Identifiers (SCTP_HMAC_IDENT) + * + * This option gets or sets the list of HMAC algorithms that the local + * endpoint requires the peer to use. +*/ + +enum { + SCTP_AUTH_HMAC_ID_SHA1 = 1, + SCTP_AUTH_HMAC_ID_SHA256 = 3, +}; + +struct sctp_hmacalgo { + __u32 shmac_number_of_idents; + __u16 shmac_idents[]; +}; + +/* + * 7.1.20. Set a shared key (SCTP_AUTH_KEY) + * + * This option will set a shared secret key which is used to build an + * association shared key. + */ +struct sctp_authkey { + sctp_assoc_t sca_assoc_id; + __u16 sca_keynumber; + __u16 sca_keylength; + __u8 sca_key[]; +}; + +/* + * 7.1.21. Get or set the active shared key (SCTP_AUTH_ACTIVE_KEY) + * + * This option will get or set the active shared key to be used to build + * the association shared key. + */ + +struct sctp_authkeyid { + sctp_assoc_t scact_assoc_id; + __u16 scact_keynumber; +}; + + +/* 7.1.23. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) + * + * This options will get or set the delayed ack timer. The time is set + * in milliseconds. If the assoc_id is 0, then this sets or gets the + * endpoints default delayed ack timer value. If the assoc_id field is + * non-zero, then the set or get effects the specified association. + */ +struct sctp_assoc_value { + sctp_assoc_t assoc_id; + uint32_t assoc_value; +}; + +/* + * 7.2.2 Peer Address Information + * + * Applications can retrieve information about a specific peer address + * of an association, including its reachability state, congestion + * window, and retransmission timer values. This information is + * read-only. The following structure is used to access this + * information: + */ +struct sctp_paddrinfo { + sctp_assoc_t spinfo_assoc_id; + struct sockaddr_storage spinfo_address; + __s32 spinfo_state; + __u32 spinfo_cwnd; + __u32 spinfo_srtt; + __u32 spinfo_rto; + __u32 spinfo_mtu; +} __attribute__((packed, aligned(4))); + +/* Peer addresses's state. */ +/* UNKNOWN: Peer address passed by the upper layer in sendmsg or connect[x] + * calls. + * UNCONFIRMED: Peer address received in INIT/INIT-ACK address parameters. + * Not yet confirmed by a heartbeat and not available for data + * transfers. + * ACTIVE : Peer address confirmed, active and available for data transfers. + * INACTIVE: Peer address inactive and not available for data transfers. + */ +enum sctp_spinfo_state { + SCTP_INACTIVE, + SCTP_ACTIVE, + SCTP_UNCONFIRMED +}; + +/* + * 7.2.1 Association Status (SCTP_STATUS) + * + * Applications can retrieve current status information about an + * association, including association state, peer receiver window size, + * number of unacked data chunks, and number of data chunks pending + * receipt. This information is read-only. The following structure is + * used to access this information: + */ +struct sctp_status { + sctp_assoc_t sstat_assoc_id; + __s32 sstat_state; + __u32 sstat_rwnd; + __u16 sstat_unackdata; + __u16 sstat_penddata; + __u16 sstat_instrms; + __u16 sstat_outstrms; + __u32 sstat_fragmentation_point; + struct sctp_paddrinfo sstat_primary; +}; + +/* + * 7.2.3. Get the list of chunks the peer requires to be authenticated + * (SCTP_PEER_AUTH_CHUNKS) + * + * This option gets a list of chunks for a specified association that + * the peer requires to be received authenticated only. + */ +struct sctp_authchunks { + sctp_assoc_t gauth_assoc_id; + __u32 guth_number_of_chunks; + uint8_t gauth_chunks[]; +}; + +/* Association states. */ +enum sctp_sstat_state { + SCTP_EMPTY = 0, + SCTP_CLOSED = 1, + SCTP_COOKIE_WAIT = 2, + SCTP_COOKIE_ECHOED = 3, + SCTP_ESTABLISHED = 4, + SCTP_SHUTDOWN_PENDING = 5, + SCTP_SHUTDOWN_SENT = 6, + SCTP_SHUTDOWN_RECEIVED = 7, + SCTP_SHUTDOWN_ACK_SENT = 8, +}; + +/* + * 8.3, 8.5 get all peer/local addresses in an association. + * This parameter struct is used by SCTP_GET_PEER_ADDRS and + * SCTP_GET_LOCAL_ADDRS socket options used internally to implement + * sctp_getpaddrs() and sctp_getladdrs() API. + */ +struct sctp_getaddrs_old { + sctp_assoc_t assoc_id; + int addr_num; + struct sockaddr *addrs; +}; +struct sctp_getaddrs { + sctp_assoc_t assoc_id; /*input*/ + __u32 addr_num; /*output*/ + __u8 addrs[0]; /*output, variable size*/ +}; + +/* These are bit fields for msghdr->msg_flags. See section 5.1. */ +/* On user space Linux, these live in as an enum. */ +enum sctp_msg_flags { + MSG_NOTIFICATION = 0x8000, +#define MSG_NOTIFICATION MSG_NOTIFICATION +}; + +/* + * 8.1 sctp_bindx() + * + * The flags parameter is formed from the bitwise OR of zero or more of the + * following currently defined flags: + */ +#define SCTP_BINDX_ADD_ADDR 0x01 +#define SCTP_BINDX_REM_ADDR 0x02 + +/* This is the structure that is passed as an argument(optval) to + * getsockopt(SCTP_SOCKOPT_PEELOFF). + */ +typedef struct { + sctp_assoc_t associd; + int sd; +} sctp_peeloff_arg_t; + + +int sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags); + +int sctp_connectx(int sd, struct sockaddr *addrs, int addrcnt, + sctp_assoc_t *id); + +int sctp_peeloff(int sd, sctp_assoc_t assoc_id); + +/* Prototype for the library function sctp_opt_info defined in + * API 7. Socket Options. + */ +int sctp_opt_info(int sd, sctp_assoc_t id, int opt, void *arg, socklen_t *size); + +/* Get all peer address on a socket. This is a new SCTP API + * described in the section 8.3 of the Sockets API Extensions for SCTP. + * This is implemented using the getsockopt() interface. + */ +int sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr **addrs); + +/* Frees all resources allocated by sctp_getpaddrs(). This is a new SCTP API + * described in the section 8.4 of the Sockets API Extensions for SCTP. + */ +int sctp_freepaddrs(struct sockaddr *addrs); + +/* Get all locally bound address on a socket. This is a new SCTP API + * described in the section 8.5 of the Sockets API Extensions for SCTP. + * This is implemented using the getsockopt() interface. + */ +int sctp_getladdrs(int sd, sctp_assoc_t id, struct sockaddr **addrs); + +/* Frees all resources allocated by sctp_getladdrs(). This is a new SCTP API + * described in the section 8.6 of the Sockets API Extensions for SCTP. + */ +int sctp_freeladdrs(struct sockaddr *addrs); + +/* This library function assists the user with the advanced features + * of SCTP. This is a new SCTP API described in the section 8.7 of the + * Sockets API Extensions for SCTP. This is implemented using the + * sendmsg() interface. + */ +int sctp_sendmsg(int s, const void *msg, size_t len, struct sockaddr *to, + socklen_t tolen, uint32_t ppid, uint32_t flags, + uint16_t stream_no, uint32_t timetolive, uint32_t context); + +/* This library function assist the user with sending a message without + * dealing directly with the CMSG header. + */ +int sctp_send(int s, const void *msg, size_t len, + const struct sctp_sndrcvinfo *sinfo, int flags); + +/* This library function assists the user with the advanced features + * of SCTP. This is a new SCTP API described in the section 8.8 of the + * Sockets API Extensions for SCTP. This is implemented using the + * recvmsg() interface. + */ +int sctp_recvmsg(int s, void *msg, size_t len, struct sockaddr *from, + socklen_t *fromlen, struct sctp_sndrcvinfo *sinfo, + int *msg_flags); + +/* Return the address length for an address family. */ +int sctp_getaddrlen(sa_family_t family); + +__END_DECLS + +#endif /* __linux_sctp_h__ */ diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am new file mode 100644 index 0000000..93be8a1 --- /dev/null +++ b/src/lib/Makefile.am @@ -0,0 +1,12 @@ +# Include these two in all the Makefile.am's!!! +include $(top_srcdir)/Makefile.vars +include $(top_srcdir)/Makefile.rules + +include $(top_srcdir)/Makefile.dirs + +# General compilation flags +INCLUDES = -I$(top_srcdir)/src/include + +lib_LTLIBRARIES = libsctp.la +libsctp_la_SOURCES = bindx.c connectx.c peeloff.c opt_info.c addrs.c sendmsg.c recvmsg.c Versions.map +libsctp_la_LDFLAGS = -version-info 1:10:0 -Wl,--version-script=Versions.map diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in new file mode 100644 index 0000000..0a22e56 --- /dev/null +++ b/src/lib/Makefile.in @@ -0,0 +1,558 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*-makefile-*- +# +# type: deep, strictness: gnu + +# -*-makefile-*- +# +# Define here directories you want + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.dirs $(top_srcdir)/Makefile.rules \ + $(top_srcdir)/Makefile.vars +subdir = src/lib +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" +libLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(lib_LTLIBRARIES) +libsctp_la_LIBADD = +am_libsctp_la_OBJECTS = bindx.lo connectx.lo peeloff.lo opt_info.lo \ + addrs.lo sendmsg.lo recvmsg.lo +libsctp_la_OBJECTS = $(am_libsctp_la_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/bin/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libsctp_la_SOURCES) +DIST_SOURCES = $(libsctp_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = $(datadir)/locale +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +MAINTAINERCLEANFILES = Makefile.in directories.h +DISTCLEANFILES = \\\ directories.h +CLEANFILES = +MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io +EXTRA_DIST = +LATEX = @LATEX@ +DVIPS = @DVIPS@ +DVIPDFM = @DVIPDFM@ +ENSCRIPTBIN = @ENSCRIPTBIN@ +PS2PDF = @PS2PDF@ +edit = @sed \ + -e "s|\@bindir\@|$(bindir)|" \ + -e "s|\@libdir\@|$(libdir)|" \ + -e "s|\@PACKAGE\@|$(PACKAGE)|" + +rootbindir = /bin +rootsbindir = /sbin +rootlibdir = /lib +pkgsysconfdir = $(sysconfdir)/@PACKAGE@ +pkgdocdir = $(datadir)/@PACKAGE@ +vpkgsysconfdir = $(pkgsysconfdir)/v@VERSION@ +vpkgdatadir = $(pkgdatadir)/v@VERSION@ +vpkglibdir = $(pkglibdir)/v@VERSION@ +vpkgdocdir = $(docdir)/v@VERSION@ + +# List here all the directories you want listed in the file to be used +# in your programs: +directories := \ + localedir \ + pkgsysconfdir \ + rootbindir \ + rootlibdir \ + rootsbindir \ + vpkgdatadir \ + vpkgdocdir \ + vpkglibdir \ + vpkgsysconfdir \ + \ + bindir \ + datadir \ + libdir \ + pkgdatadir \ + pkgdocdir \ + pkglibdir \ + sbindir + + +# Include these two in all the Makefile.am's!!! + +# General compilation flags +INCLUDES = -I$(top_srcdir)/src/include +lib_LTLIBRARIES = libsctp.la +libsctp_la_SOURCES = bindx.c connectx.c peeloff.c opt_info.c addrs.c sendmsg.c recvmsg.c Versions.map +libsctp_la_LDFLAGS = -version-info 1:10:0 -Wl,--version-script=Versions.map +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.vars $(top_srcdir)/Makefile.rules $(top_srcdir)/Makefile.dirs $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/lib/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/lib/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libsctp.la: $(libsctp_la_OBJECTS) $(libsctp_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libsctp_la_LDFLAGS) $(libsctp_la_OBJECTS) $(libsctp_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addrs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bindx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connectx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_info.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peeloff.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/recvmsg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sendmsg.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/../.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: install-libLTLIBRARIES + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am \ + uninstall-libLTLIBRARIES + + +# -*-makefile-*- +# +# Generate pre-parsed C code. +%.i: %.c + $(COMPILE) -E -c $^ -o $@ + +.PRECIOUS: %.i +%.ci: %.i + -grep -v -e "^#" -e "^ *$$" $^ | indent > $@ + mv -f $@ $^ + +# To modify this target for another language, just copy, paste and +# modify the target to generate directories.h. We depend on +# config.status and Makefile.dirs, as anything changed is going to be +# reflected there. + +# This is for generating the list in C/C++ +directories.h: $(top_builddir)/config.status $(top_srcdir)/Makefile.dirs + @rm -f $@ + @echo -n "Creating $@ ..." + @echo "#ifndef __$(subst .,_,$@)__" > $@ + @echo "# define __$(subst .,_,$@)__" >> $@ + @echo "" >> $@ + @echo -e $(foreach v,$(directories),$(shell echo 'D_$(v) \"$($v)\"\\n')) \ + | sed 's/^ *D_/# define D_/' >> $@ + @echo "#endif" >> $@ + @echo " done" +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/lib/Versions.map b/src/lib/Versions.map new file mode 100644 index 0000000..f06c56e --- /dev/null +++ b/src/lib/Versions.map @@ -0,0 +1,22 @@ +VERS_1 { + global: + sctp_getpaddrs; + sctp_freepaddrs; + sctp_getladdrs; + sctp_freeladdrs; + sctp_getaddrlen; + sctp_bindx; + sctp_connectx; + sctp_opt_info; + sctp_peeloff; + sctp_recvmsg; + sctp_sendmsg; + sctp_send; + + local: + *; +}; + +VERS_2 { + global: sctp_connectx; +} VERS_1; diff --git a/src/lib/addrs.c b/src/lib/addrs.c new file mode 100644 index 0000000..bcbcec0 --- /dev/null +++ b/src/lib/addrs.c @@ -0,0 +1,210 @@ +/* SCTP kernel Implementation: User API extensions. + * + * addrs.c + * + * Distributed under the terms of the LGPL v2.1 as described in + * http://www.gnu.org/copyleft/lesser.txt + * + * This file is part of the user library that offers support for the + * SCTP kernel Implementation. The main purpose of this + * code is to provide the SCTP Socket API mappings for user + * application to interface with the SCTP in kernel. + * + * This implementation is based on the Socket API Extensions for SCTP + * defined in + * Sridhar Samudrala + * Ivan Skytte Jørgensen + */ + +#include +#include +#include +#include +#include + +/* + * Get local/peer addresses using the old API + * Old kernels (2.6.13 and earlier) only support this API but it breaks 32-bit + * programs on 64-bit kernels. + */ +static int +sctp_getaddrs_old(int sd, sctp_assoc_t id, int optname_num, int optname_old, + struct sockaddr **addrs) +{ + socklen_t len = sizeof(sctp_assoc_t); + int cnt, err; + struct sctp_getaddrs_old getaddrs; + + cnt = getsockopt(sd, SOL_SCTP, optname_num, &id, &len); + if (cnt < 0) + return -1; + + if (0 == cnt) { + *addrs = NULL; + return 0; + } + + len = cnt * sizeof(struct sockaddr_in6); + + getaddrs.assoc_id = id; + getaddrs.addr_num = cnt; + getaddrs.addrs = (struct sockaddr *)malloc(len); + if (NULL == getaddrs.addrs) + return -1; + + len = sizeof(getaddrs); + err = getsockopt(sd, SOL_SCTP, optname_old, &getaddrs, &len); + if (err < 0) { + free(getaddrs.addrs); + return -1; + } + + *addrs = getaddrs.addrs; + + return getaddrs.addr_num; + +} /* sctp_getaddrs_old() */ + +/* + * Common getsockopt() layer + * If the NEW getsockopt() API fails this function will fall back to using + * the old API + */ +static int +sctp_getaddrs(int sd, sctp_assoc_t id, + int optname_new, int optname_num_old, int optname_old, + struct sockaddr **addrs) +{ + int cnt, err; + socklen_t len; + size_t bufsize = 4096; /*enough for most cases*/ + + struct sctp_getaddrs *getaddrs = (struct sctp_getaddrs*)malloc(bufsize); + if(!getaddrs) + return -1; + + for(;;) { + char *new_buf; + + len = bufsize; + getaddrs->assoc_id = id; + err = getsockopt(sd, SOL_SCTP, optname_new, getaddrs, &len); + if (err == 0) { + /*got it*/ + break; + } + if (errno == ENOPROTOOPT) { + /*Kernel does not support new API*/ + free(getaddrs); + return sctp_getaddrs_old(sd, id, + optname_num_old, optname_old, + addrs); + } + if (errno != ENOMEM ) { + /*unknown error*/ + free(getaddrs); + return -1; + } + /*expand buffer*/ + if (bufsize > 128*1024) { + /*this is getting ridiculous*/ + free(getaddrs); + errno = ENOBUFS; + return -1; + } + new_buf = realloc(getaddrs, bufsize+4096); + if (!new_buf) { + free(getaddrs); + return -1; + } + bufsize += 4096; + getaddrs = (struct sctp_getaddrs*)new_buf; + } + + /* we skip traversing the list, allocating a new buffer etc. and enjoy + * a simple hack*/ + cnt = getaddrs->addr_num; + memmove(getaddrs, getaddrs + 1, len); + *addrs = (struct sockaddr*)getaddrs; + + return cnt; +} /* sctp_getaddrs() */ + +/* Get all peer address on a socket. This is a new SCTP API + * described in the section 8.3 of the Sockets API Extensions for SCTP. + * This is implemented using the getsockopt() interface. + */ +int +sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr **addrs) +{ + return sctp_getaddrs(sd, id, + SCTP_GET_PEER_ADDRS, + SCTP_GET_PEER_ADDRS_NUM_OLD, + SCTP_GET_PEER_ADDRS_OLD, + addrs); +} /* sctp_getpaddrs() */ + +/* Frees all resources allocated by sctp_getpaddrs(). This is a new SCTP API + * described in the section 8.4 of the Sockets API Extensions for SCTP. + */ +int +sctp_freepaddrs(struct sockaddr *addrs) +{ + free(addrs); + return 0; + +} /* sctp_freepaddrs() */ + +/* Get all locally bound address on a socket. This is a new SCTP API + * described in the section 8.5 of the Sockets API Extensions for SCTP. + * This is implemented using the getsockopt() interface. + */ +int +sctp_getladdrs(int sd, sctp_assoc_t id, struct sockaddr **addrs) +{ + return sctp_getaddrs(sd, id, + SCTP_GET_LOCAL_ADDRS, + SCTP_GET_LOCAL_ADDRS_NUM_OLD, + SCTP_GET_LOCAL_ADDRS_OLD, + addrs); +} /* sctp_getladdrs() */ + +/* Frees all resources allocated by sctp_getladdrs(). This is a new SCTP API + * described in the section 8.6 of the Sockets API Extensions for SCTP. + */ +int +sctp_freeladdrs(struct sockaddr *addrs) +{ + free(addrs); + return 0; + +} /* sctp_freeladdrs() */ + +int +sctp_getaddrlen(sa_family_t family) +{ + /* We could call into the kernel to see what it thinks the size should + * be, but hardcoding the address families here is: (a) faster, + * (b) easier, and (c) probably good enough for forseeable future. + */ + switch(family) { + case AF_INET: + return sizeof(struct sockaddr_in); + case AF_INET6: + return sizeof(struct sockaddr_in6); + default: + /* Currently there is no defined error handling in + * draft-ietf-tsvwg-sctpsocket-13.txt. + * -1 might cause the application to overwrite buffer + * or misinterpret data. 0 is more likely to cause + * an endless loop. + */ + return 0; + } +} diff --git a/src/lib/bindx.c b/src/lib/bindx.c new file mode 100644 index 0000000..8e0b464 --- /dev/null +++ b/src/lib/bindx.c @@ -0,0 +1,78 @@ +/* SCTP kernel Implementation: User API extensions. + * + * bindx.c + * + * Distributed under the terms of the LGPL v2.1 as described in + * http://www.gnu.org/copyleft/lesser.txt + * + * This file is part of the user library that offers support for the + * SCTP kernel Implementation. The main purpose of this + * code is to provide the SCTP Socket API mappings for user + * application to interface with the SCTP in kernel. + * + * This implementation is based on the Socket API Extensions for SCTP + * defined in + * Daisy Chang + * Inaky Perez-Gonzalez + * Sridhar Samudrala + */ + +#include /* struct sockaddr_storage, setsockopt() */ +#include +#include /* SCTP_SOCKOPT_BINDX_* */ +#include + +/* Support the sctp_bindx() interface. + * + * See Sockets API Extensions for SCTP. Section 8.1. + * + * Instead of implementing through a socket call in sys_socketcall(), + * tunnel the request through setsockopt(). + */ +int +sctp_bindx(int fd, struct sockaddr *addrs, int addrcnt, int flags) +{ + int setsock_option = 0; + void *addrbuf; + struct sockaddr *sa_addr; + socklen_t addrs_size = 0; + int i; + + switch (flags) { + case SCTP_BINDX_ADD_ADDR: + setsock_option = SCTP_SOCKOPT_BINDX_ADD; + break; + case SCTP_BINDX_REM_ADDR: + setsock_option = SCTP_SOCKOPT_BINDX_REM; + break; + default: + errno = EINVAL; + return -1; + } + + addrbuf = addrs; + for (i = 0; i < addrcnt; i++) { + sa_addr = (struct sockaddr *)addrbuf; + switch (sa_addr->sa_family) { + case AF_INET: + addrs_size += sizeof(struct sockaddr_in); + addrbuf += sizeof(struct sockaddr_in); + break; + case AF_INET6: + addrs_size += sizeof(struct sockaddr_in6); + addrbuf += sizeof(struct sockaddr_in6); + break; + default: + errno = EINVAL; + return -1; + } + } + + return setsockopt(fd, SOL_SCTP, setsock_option, addrs, addrs_size); +} diff --git a/src/lib/connectx.c b/src/lib/connectx.c new file mode 100644 index 0000000..375e638 --- /dev/null +++ b/src/lib/connectx.c @@ -0,0 +1,111 @@ +/* SCTP kernel Implementation: User API extensions. + * + * connectx.c + * + * Distributed under the terms of the LGPL v2.1 as described in + * http://www.gnu.org/copyleft/lesser.txt. + * + * This file is part of the user library that offers support for the + * SCTP kernel Implementation. The main purpose of this + * code is to provide the SCTP Socket API mappings for user + * application to interface with the SCTP in kernel. + * + * This implementation is based on the Socket API Extensions for SCTP + * defined in + */ + +#include /* struct sockaddr_storage, setsockopt() */ +#include +#include /* SCTP_SOCKOPT_CONNECTX_* */ +#include +#include + +/* Support the sctp_connectx() interface. + * + * See Sockets API Extensions for SCTP. Section 8.1. + * + * Instead of implementing through a socket call in sys_socketcall(), + * tunnel the request through setsockopt(). + */ +static int __connectx_addrsize(const struct sockaddr *addrs, + const int addrcnt) +{ + void *addrbuf; + struct sockaddr *sa_addr; + int addrs_size = 0; + int i; + + addrbuf = addrs; + for (i = 0; i < addrcnt; i++) { + sa_addr = (struct sockaddr *)addrbuf; + switch (sa_addr->sa_family) { + case AF_INET: + addrs_size += sizeof(struct sockaddr_in); + addrbuf += sizeof(struct sockaddr_in); + break; + case AF_INET6: + addrs_size += sizeof(struct sockaddr_in6); + addrbuf += sizeof(struct sockaddr_in6); + break; + default: + errno = EINVAL; + return -1; + } + } + + return addrs_size; +} + + +int __sctp_connectx(int fd, struct sockaddr *addrs, int addrcnt) +{ + socklen_t addrs_size = __connectx_addrsize(addrs, addrcnt); + + if (addrs_size < 0) + return addrs_size; + + return setsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_CONNECTX_OLD, addrs, + addrs_size); +} + +extern int sctp_connectx_orig (int) + __attribute ((alias ("__sctp_connectx"))); + +int sctp_connectx_new(int fd, struct sockaddr *addrs, int addrcnt, + sctp_assoc_t *id) +{ + socklen_t addrs_size = __connectx_addrsize(addrs, addrcnt); + int status; + + if (addrs_size < 0) + return addrs_size; + + if (id) + *id = 0; + + status = setsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_CONNECTX, addrs, + addrs_size); + + /* the kernel doesn't support the new connectx interface */ + if (status < 0 && errno == ENOPROTOOPT) + return setsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_CONNECTX_OLD, + addrs, addrs_size); + + /* Normalize status and set association id */ + if (status > 0) { + if (id) + *id = status; + status = 0; + } + + return status; +} + +__asm__(".symver __sctp_connectx, sctp_connectx@"); +__asm__(".symver sctp_connectx_orig, sctp_connectx@VERS_1"); +__asm__(".symver sctp_connectx_new, sctp_connectx@@VERS_2"); diff --git a/src/lib/opt_info.c b/src/lib/opt_info.c new file mode 100644 index 0000000..21c8307 --- /dev/null +++ b/src/lib/opt_info.c @@ -0,0 +1,62 @@ +/* SCTP kernel Implementation: User API extensions. + * + * opt_info.c + * + * Distributed under the terms of the LGPL v2.1 as described in + * http://www.gnu.org/copyleft/lesser.txt + * + * This file is part of the user library that offers support for the + * SCTP kernel Implementation. The main purpose of this + * code if to provide the SCTP Socket API mappings for user + * application to interface with the SCTP in kernel. + * + * This implementation is based on the Socket API Extensions for SCTP + * defined in + */ + +#include /* struct sockaddr_storage, setsockopt() */ +#include /* SCTP_SOCKOPT_BINDX_* */ +#include + +/* Support the sctp_opt_info() interface. + * + * See Sockets API Extensions for SCTP. Section 7. + * + * Pass sctp option information pass both in to and out of the SCTP stack. + * This is a new SCTP API described in the section 7 of the Sockets API + * Extensions for SCTP. This is implemented using the getsockopt() interface. + */ +int +sctp_opt_info(int sd, sctp_assoc_t id, int opt, void *arg, socklen_t *size) +{ + switch (opt) { + case SCTP_RTOINFO: + case SCTP_ASSOCINFO: + case SCTP_INITMSG: + case SCTP_NODELAY: + case SCTP_AUTOCLOSE: + case SCTP_PRIMARY_ADDR: + case SCTP_DISABLE_FRAGMENTS: + case SCTP_PEER_ADDR_PARAMS: + case SCTP_DEFAULT_SEND_PARAM: + case SCTP_EVENTS: + case SCTP_I_WANT_MAPPED_V4_ADDR: + case SCTP_MAXSEG: + case SCTP_STATUS: + case SCTP_GET_PEER_ADDR_INFO: + case SCTP_AUTH_ACTIVE_KEY: + case SCTP_PEER_AUTH_CHUNKS: + case SCTP_LOCAL_AUTH_CHUNKS: + *(sctp_assoc_t *)arg = id; + return getsockopt(sd, IPPROTO_SCTP, opt, arg, size); + default: + return ENOTSUP; + } + +} /* sctp_opt_info() */ diff --git a/src/lib/peeloff.c b/src/lib/peeloff.c new file mode 100644 index 0000000..a870050 --- /dev/null +++ b/src/lib/peeloff.c @@ -0,0 +1,47 @@ +/* SCTP kernel Implementation: User API extensions. + * + * peeloff.c + * + * Distributed under the terms of the LGPL v2.1 as described in + * http://www.gnu.org/copyleft/lesser.txt + * + * This file is part of the user library that offers support for the + * SCTP kernel Implementation. The main purpose of this + * code is to provide the SCTP Socket API mappings for user + * application to interface with the SCTP in kernel. + * + * This implementation is based on the Socket API Extensions for SCTP + * defined in + */ + +#include /* struct sockaddr_storage, setsockopt() */ +#include /* SCTP_SOCKOPT_BINDX_* */ +#include + +/* Branch off an association into a seperate socket. This is a new SCTP API + * described in the section 8.2 of the Sockets API Extensions for SCTP. + * This is implemented using the getsockopt() interface. + */ +int +sctp_peeloff(int fd, sctp_assoc_t associd) +{ + sctp_peeloff_arg_t peeloff; + socklen_t peeloff_size = sizeof(peeloff); + int err; + + peeloff.associd = associd; + peeloff.sd = 0; + err = getsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_PEELOFF, &peeloff, + &peeloff_size); + if (err < 0) { + return err; + } + + return peeloff.sd; + +} /* sctp_peeloff() */ diff --git a/src/lib/recvmsg.c b/src/lib/recvmsg.c new file mode 100644 index 0000000..4575788 --- /dev/null +++ b/src/lib/recvmsg.c @@ -0,0 +1,101 @@ +/* SCTP kernel Implementation: User API extensions. + * + * sctp_recvmsg.c + * + * Distributed under the terms of the LGPL v2.1 as described in + * http://www.gnu.org/copyleft/lesser.txt + * + * This file is part of the user library that offers support for the + * SCTP kernel Implementation. The main purpose of this + * code is to provide the SCTP Socket API mappings for user + * application to interface with the SCTP in kernel. + * + * This implementation is based on the Socket API Extensions for SCTP + * defined in + * + * Copyright (c) 2003 International Business Machines, Corp. + * + * Written or modified by: + * Ryan Layer + * + * An implementation may provide a library function (or possibly system + * call) to assist the user with the advanced features of SCTP. Note + * that in order for the sctp_sndrcvinfo structure to be filled in by + * sctp_recvmsg() the caller must enable the sctp_data_io_events with + * the SCTP_EVENTS option. + * + * sctp_recvmsg(). Its syntax is, + * + * int sctp_recvmsg(int s, + * void *msg, + * size_t len, + * struct sockaddr *from, + * socklen_t *fromlen, + * struct sctp_sndrcvinfo *sinfo, + * int *msg_flags) + * + * + * s - is the socket descriptor + * msg - is a message buffer to be filled. + * len - is the length of the message buffer. + * from - is a pointer to a address to be filled with + * the sender of this messages address. + * fromlen - is the from length. + * sinfo - A pointer to a sctp_sndrcvinfo structure + * to be filled upon receipt of the message. + * msg_flags - A pointer to a integer to be filled with + * any message flags (e.g. MSG_NOTIFICATION). + */ + +#include +#include +#include /* struct sockaddr_storage, setsockopt() */ +#include + +int sctp_recvmsg(int s, void *msg, size_t len, struct sockaddr *from, + socklen_t *fromlen, struct sctp_sndrcvinfo *sinfo, + int *msg_flags) +{ + int error; + struct iovec iov; + struct msghdr inmsg; + char incmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg = NULL; + + memset(&inmsg, 0, sizeof (inmsg)); + + iov.iov_base = msg; + iov.iov_len = len; + + inmsg.msg_name = from; + inmsg.msg_namelen = fromlen ? *fromlen : 0; + inmsg.msg_iov = &iov; + inmsg.msg_iovlen = 1; + inmsg.msg_control = incmsg; + inmsg.msg_controllen = sizeof(incmsg); + + error = recvmsg(s, &inmsg, msg_flags ? *msg_flags : 0); + if (error < 0) + return error; + + if (fromlen) + *fromlen = inmsg.msg_namelen; + if (msg_flags) + *msg_flags = inmsg.msg_flags; + + if (!sinfo) + return error; + + for (cmsg = CMSG_FIRSTHDR(&inmsg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&inmsg, cmsg)){ + if ((IPPROTO_SCTP == cmsg->cmsg_level) && + (SCTP_SNDRCV == cmsg->cmsg_type)) + break; + } + + /* Copy sinfo. */ + if (cmsg) + memcpy(sinfo, CMSG_DATA(cmsg), sizeof(struct sctp_sndrcvinfo)); + + return (error); +} diff --git a/src/lib/sendmsg.c b/src/lib/sendmsg.c new file mode 100644 index 0000000..1de592d --- /dev/null +++ b/src/lib/sendmsg.c @@ -0,0 +1,106 @@ +/* SCTP kernel Implementation: User API extensions. + * + * sendmsg.c + * + * Distributed under the terms of the LGPL v2.1 as described in + * http://www.gnu.org/copyleft/lesser.txt + * + * This file is part of the user library that offers support for the + * SCTP kernel Implementation. The main purpose of this + * code is to provide the SCTP Socket API mappings for user + * application to interface with the SCTP in kernel. + * + * This implementation is based on the Socket API Extensions for SCTP + * defined in + * + * Copyright (c) 2003 Intel Corp. + * + * Written or modified by: + * Ardelle Fan + */ + +#include +#include /* struct sockaddr_storage, setsockopt() */ +#include + +/* This library function assists the user with the advanced features + * of SCTP. This is a new SCTP API described in the section 8.7 of the + * Sockets API Extensions for SCTP. This is implemented using the + * sendmsg() interface. + */ +int +sctp_sendmsg(int s, const void *msg, size_t len, struct sockaddr *to, + socklen_t tolen, uint32_t ppid, uint32_t flags, + uint16_t stream_no, uint32_t timetolive, uint32_t context) +{ + struct msghdr outmsg; + struct iovec iov; + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct sctp_sndrcvinfo *sinfo; + + outmsg.msg_name = to; + outmsg.msg_namelen = tolen; + outmsg.msg_iov = &iov; + iov.iov_base = (void *)msg; + iov.iov_len = len; + outmsg.msg_iovlen = 1; + + outmsg.msg_control = outcmsg; + outmsg.msg_controllen = sizeof(outcmsg); + outmsg.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&outmsg); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + + outmsg.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo)); + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_flags = flags; + sinfo->sinfo_stream = stream_no; + sinfo->sinfo_timetolive = timetolive; + sinfo->sinfo_context = context; + + return sendmsg(s, &outmsg, 0); +} + +/* This library function assist the user with sending a message without + * dealing directly with the CMSG header. + */ +int +sctp_send(int s, const void *msg, size_t len, + const struct sctp_sndrcvinfo *sinfo, int flags) +{ + struct msghdr outmsg; + struct iovec iov; + + outmsg.msg_name = NULL; + outmsg.msg_namelen = 0; + outmsg.msg_iov = &iov; + iov.iov_base = (void *)msg; + iov.iov_len = len; + outmsg.msg_iovlen = 1; + outmsg.msg_controllen = 0; + + if (sinfo) { + char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + + outmsg.msg_control = outcmsg; + outmsg.msg_controllen = sizeof(outcmsg); + outmsg.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&outmsg); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + + outmsg.msg_controllen = cmsg->cmsg_len; + memcpy(CMSG_DATA(cmsg), sinfo, sizeof(struct sctp_sndrcvinfo)); + } + + return sendmsg(s, &outmsg, flags); +} diff --git a/src/testlib/Makefile.am b/src/testlib/Makefile.am new file mode 100644 index 0000000..e9db41c --- /dev/null +++ b/src/testlib/Makefile.am @@ -0,0 +1,12 @@ +# Include these two in all the Makefile.am's!!! +include $(top_srcdir)/Makefile.vars +include $(top_srcdir)/Makefile.rules + +include $(top_srcdir)/Makefile.dirs + +# General compilation flags +INCLUDES = -I$(top_srcdir)/src/include + +noinst_LTLIBRARIES = libsctputil.la +libsctputil_la_SOURCES = sctputil.c sctputil.h +libsctputil_la_LDFLAGS = -version-info 1:10:0 diff --git a/src/testlib/Makefile.in b/src/testlib/Makefile.in new file mode 100644 index 0000000..fa45bd0 --- /dev/null +++ b/src/testlib/Makefile.in @@ -0,0 +1,521 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*-makefile-*- +# +# type: deep, strictness: gnu + +# -*-makefile-*- +# +# Define here directories you want + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.dirs $(top_srcdir)/Makefile.rules \ + $(top_srcdir)/Makefile.vars +subdir = src/testlib +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libsctputil_la_LIBADD = +am_libsctputil_la_OBJECTS = sctputil.lo +libsctputil_la_OBJECTS = $(am_libsctputil_la_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/bin/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libsctputil_la_SOURCES) +DIST_SOURCES = $(libsctputil_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = $(datadir)/locale +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +MAINTAINERCLEANFILES = Makefile.in directories.h +DISTCLEANFILES = \\\ directories.h +CLEANFILES = +MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io +EXTRA_DIST = +LATEX = @LATEX@ +DVIPS = @DVIPS@ +DVIPDFM = @DVIPDFM@ +ENSCRIPTBIN = @ENSCRIPTBIN@ +PS2PDF = @PS2PDF@ +edit = @sed \ + -e "s|\@bindir\@|$(bindir)|" \ + -e "s|\@libdir\@|$(libdir)|" \ + -e "s|\@PACKAGE\@|$(PACKAGE)|" + +rootbindir = /bin +rootsbindir = /sbin +rootlibdir = /lib +pkgsysconfdir = $(sysconfdir)/@PACKAGE@ +pkgdocdir = $(datadir)/@PACKAGE@ +vpkgsysconfdir = $(pkgsysconfdir)/v@VERSION@ +vpkgdatadir = $(pkgdatadir)/v@VERSION@ +vpkglibdir = $(pkglibdir)/v@VERSION@ +vpkgdocdir = $(docdir)/v@VERSION@ + +# List here all the directories you want listed in the file to be used +# in your programs: +directories := \ + localedir \ + pkgsysconfdir \ + rootbindir \ + rootlibdir \ + rootsbindir \ + vpkgdatadir \ + vpkgdocdir \ + vpkglibdir \ + vpkgsysconfdir \ + \ + bindir \ + datadir \ + libdir \ + pkgdatadir \ + pkgdocdir \ + pkglibdir \ + sbindir + + +# Include these two in all the Makefile.am's!!! + +# General compilation flags +INCLUDES = -I$(top_srcdir)/src/include +noinst_LTLIBRARIES = libsctputil.la +libsctputil_la_SOURCES = sctputil.c sctputil.h +libsctputil_la_LDFLAGS = -version-info 1:10:0 +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.vars $(top_srcdir)/Makefile.rules $(top_srcdir)/Makefile.dirs $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/testlib/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/testlib/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libsctputil.la: $(libsctputil_la_OBJECTS) $(libsctputil_la_DEPENDENCIES) + $(LINK) $(libsctputil_la_LDFLAGS) $(libsctputil_la_OBJECTS) $(libsctputil_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sctputil.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/../.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-info-am + + +# -*-makefile-*- +# +# Generate pre-parsed C code. +%.i: %.c + $(COMPILE) -E -c $^ -o $@ + +.PRECIOUS: %.i +%.ci: %.i + -grep -v -e "^#" -e "^ *$$" $^ | indent > $@ + mv -f $@ $^ + +# To modify this target for another language, just copy, paste and +# modify the target to generate directories.h. We depend on +# config.status and Makefile.dirs, as anything changed is going to be +# reflected there. + +# This is for generating the list in C/C++ +directories.h: $(top_builddir)/config.status $(top_srcdir)/Makefile.dirs + @rm -f $@ + @echo -n "Creating $@ ..." + @echo "#ifndef __$(subst .,_,$@)__" > $@ + @echo "# define __$(subst .,_,$@)__" >> $@ + @echo "" >> $@ + @echo -e $(foreach v,$(directories),$(shell echo 'D_$(v) \"$($v)\"\\n')) \ + | sed 's/^ *D_/# define D_/' >> $@ + @echo "#endif" >> $@ + @echo " done" +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/testlib/sctputil.c b/src/testlib/sctputil.c new file mode 100644 index 0000000..abf80fa --- /dev/null +++ b/src/testlib/sctputil.c @@ -0,0 +1,418 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2001, 2003 + * Copyright (C) 1999 Cisco + * Copyright (C) 1999-2000 Motorola + # Copyright (C) 2001 Nokia + * Copyright (C) 2001 La Monte H.P. Yarroll + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * La Monte H.P. Yarroll + * Narasimha Budihal + * Karl Knutson + * Jon Grimm + * Daisy Chang + * Sridhar Samudrala + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* This function prints the cmsg data. */ +void +test_print_cmsg(sctp_cmsg_t type, sctp_cmsg_data_t *data) +{ + switch(type) { + case SCTP_INIT: + printf("INIT\n"); + printf(" sinit_num_ostreams %d\n", + data->init.sinit_num_ostreams); + printf(" sinit_max_instreams %d\n", + data->init.sinit_max_instreams); + printf(" sinit_max_attempts %d\n", + data->init.sinit_max_attempts); + printf(" sinit_max_init_timeo %d\n", + data->init.sinit_max_init_timeo); + + break; + case SCTP_SNDRCV: + printf("SNDRCV\n"); + printf(" sinfo_stream %u\n", data->sndrcv.sinfo_stream); + printf(" sinfo_ssn %u\n", data->sndrcv.sinfo_ssn); + printf(" sinfo_flags 0x%x\n", data->sndrcv.sinfo_flags); + printf(" sinfo_ppid %u\n", data->sndrcv.sinfo_ppid); + printf(" sinfo_context %x\n", data->sndrcv.sinfo_context); + printf(" sinfo_tsn %u\n", data->sndrcv.sinfo_tsn); + printf(" sinfo_cumtsn %u\n", data->sndrcv.sinfo_cumtsn); + printf(" sinfo_assoc_id %u\n", data->sndrcv.sinfo_assoc_id); + + break; + + default: + printf("UNKNOWN CMSG: %d\n", type); + break; + } +} + +/* This function prints the message. */ +void +test_print_message(int sk, struct msghdr *msg, size_t msg_len) +{ + sctp_cmsg_data_t *data; + struct cmsghdr *cmsg; + int i; + int done = 0; + char save; + union sctp_notification *sn; + + for (cmsg = CMSG_FIRSTHDR(msg); + cmsg != NULL; + cmsg = CMSG_NXTHDR(msg, cmsg)) { + data = (sctp_cmsg_data_t *)CMSG_DATA(cmsg); + test_print_cmsg(cmsg->cmsg_type, data); + } + + if (!(MSG_NOTIFICATION & msg->msg_flags)) { + int index = 0; + /* Make sure that everything is printable and that we + * are NUL terminated... + */ + printf("DATA(%d): ", msg_len); + while ( msg_len > 0 ) { + char *text; + int len; + + text = msg->msg_iov[index].iov_base; + len = msg->msg_iov[index].iov_len; + + save = text[msg_len-1]; + if ( len > msg_len ) { + text[(len = msg_len) - 1] = '\0'; + } + + if ( (msg_len -= len) > 0 ) { index++; } + + for (i = 0; i < len - 1; ++i) { + if (!isprint(text[i])) text[i] = '.'; + } + + printf("%s", text); + text[msg_len-1] = save; + + if ( (done = !strcmp(text, "exit")) ) { break; } + } + } else { + printf("NOTIFICATION: "); + sn = (union sctp_notification *)msg->msg_iov[0].iov_base; + switch (sn->sn_header.sn_type) { + case SCTP_ASSOC_CHANGE: + switch (sn->sn_assoc_change.sac_state) { + case SCTP_COMM_UP: + printf("ASSOC_CHANGE - COMM_UP"); + break; + case SCTP_COMM_LOST: + printf("ASSOC_CHANGE - COMM_LOST"); + break; + case SCTP_RESTART: + printf("ASSOC_CHANGE - RESTART"); + break; + case SCTP_SHUTDOWN_COMP: + printf("ASSOC_CHANGE - SHUTDOWN_COMP"); + break; + case SCTP_CANT_STR_ASSOC: + printf("ASSOC_CHANGE - CANT_STR_ASSOC"); + break; + default: + printf("ASSOC_CHANGE - UNEXPECTED(%d)", + sn->sn_assoc_change.sac_state); + break; + } + break; + default: + printf("%d", sn->sn_header.sn_type); + break; + } + } + + printf("\n"); +} + +/* Check if a buf/msg_flags matches a notification, its type, and possibly an + * additional field in the corresponding notification structure. + */ +void +test_check_buf_notification(void *buf, int datalen, int msg_flags, + int expected_datalen, uint16_t expected_sn_type, + uint32_t expected_additional) +{ + union sctp_notification *sn; + + if (!(msg_flags & MSG_NOTIFICATION)) + tst_brkm(TBROK, tst_exit, "Got a datamsg, expecting " + "notification"); + + if (expected_datalen <= 0) + return; + + if (datalen != expected_datalen) + tst_brkm(TBROK, tst_exit, "Got a notification of unexpected " + "length:%d, expected length:%d", datalen, + expected_datalen); + + sn = (union sctp_notification *)buf; + if (sn->sn_header.sn_type != expected_sn_type) + tst_brkm(TBROK, tst_exit, "Unexpected notification:%d" + "expected:%d", sn->sn_header.sn_type, + expected_sn_type); + + switch(sn->sn_header.sn_type){ + case SCTP_ASSOC_CHANGE: + if (sn->sn_assoc_change.sac_state != expected_additional) + tst_brkm(TBROK, tst_exit, "Unexpected sac_state:%d " + "expected:%d", sn->sn_assoc_change.sac_state, + expected_additional); + break; + default: + break; + } +} + +/* Check if a message matches a notification, its type, and possibly an + * additional field in the corresponding notification structure. + */ +void +test_check_msg_notification(struct msghdr *msg, int datalen, + int expected_datalen, uint16_t expected_sn_type, + uint32_t expected_additional) +{ + test_check_buf_notification(msg->msg_iov[0].iov_base, datalen, + msg->msg_flags, expected_datalen, + expected_sn_type, expected_additional); +} + +/* Check if a buf/msg_flags/sinfo corresponds to data, its length, msg_flags, + * stream and ppid. + */ +void +test_check_buf_data(void *buf, int datalen, int msg_flags, + struct sctp_sndrcvinfo *sinfo, int expected_datalen, + int expected_msg_flags, uint16_t expected_stream, + uint32_t expected_ppid) +{ + if (msg_flags & MSG_NOTIFICATION) + tst_brkm(TBROK, tst_exit, "Got a notification, expecting a" + "datamsg"); + + if (expected_datalen <= 0) + return; + + if (datalen != expected_datalen) + tst_brkm(TBROK, tst_exit, "Got a datamsg of unexpected " + "length:%d, expected length:%d", datalen, + expected_datalen); + + if ((msg_flags & ~0x80000000) != expected_msg_flags) + tst_brkm(TBROK, tst_exit, "Unexpected msg_flags:0x%x " + "expecting:0x%x", msg_flags, expected_msg_flags); + + if ((0 == expected_stream) && (0 == expected_ppid)) + return; + + if (!sinfo) + tst_brkm(TBROK, tst_exit, "Null sinfo, but expected " + "stream:%d expected ppid:%d", expected_stream, + expected_ppid); + + if (sinfo->sinfo_stream != expected_stream) + tst_brkm(TBROK, tst_exit, "stream mismatch: expected:%x " + "got:%x", expected_stream, sinfo->sinfo_stream); + if (sinfo->sinfo_ppid != expected_ppid) + tst_brkm(TBROK, tst_exit, "ppid mismatch: expected:%x " + "got:%x\n", expected_ppid, sinfo->sinfo_ppid); +} + +/* Check if a message corresponds to data, its length, msg_flags, stream and + * ppid. + */ +void +test_check_msg_data(struct msghdr *msg, int datalen, int expected_datalen, + int expected_msg_flags, uint16_t expected_stream, + uint32_t expected_ppid) +{ + struct cmsghdr *cmsg = NULL; + struct sctp_sndrcvinfo *sinfo = NULL; + + /* Receive auxiliary data in msgh. */ + for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(msg, cmsg)){ + if (IPPROTO_SCTP == cmsg->cmsg_level && + SCTP_SNDRCV == cmsg->cmsg_type) + break; + } /* for( all cmsgs) */ + + if ((!cmsg) || + (cmsg->cmsg_len < CMSG_LEN(sizeof(struct sctp_sndrcvinfo)))) + sinfo = NULL; + else + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + + test_check_buf_data(msg->msg_iov[0].iov_base, datalen, msg->msg_flags, + sinfo, expected_datalen, expected_msg_flags, + expected_stream, expected_ppid); + +} + + +/* Allocate a buffer of requested len and fill in with data. */ +void * +test_build_msg(int len) +{ + int i = len - 1; + int n; + unsigned char msg[] = + "012345678901234567890123456789012345678901234567890"; + char *msg_buf, *p; + + msg_buf = (char *)malloc(len); + if (!msg_buf) + tst_brkm(TBROK, tst_exit, "malloc failed"); + + p = msg_buf; + + do { + n = ((i > 50)?50:i); + memcpy(p, msg, ((i > 50)?50:i)); + p += n; + i -= n; + } while (i > 0); + + msg_buf[len-1] = '\0'; + + return(msg_buf); +} + +/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ +void test_enable_assoc_change(int fd) +{ + struct sctp_event_subscribe subscribe; + + memset(&subscribe, 0, sizeof(subscribe)); + subscribe.sctp_data_io_event = 1; + subscribe.sctp_association_event = 1; + test_setsockopt(fd, SCTP_EVENTS, (char *)&subscribe, + sizeof(subscribe)); +} + +static int cmp_addr(sockaddr_storage_t *addr1, sockaddr_storage_t *addr2) +{ + if (addr1->sa.sa_family != addr2->sa.sa_family) + return 0; + switch (addr1->sa.sa_family) { + case AF_INET6: + if (addr1->v6.sin6_port != addr2->v6.sin6_port) + return -1; + return memcmp(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr, + sizeof(addr1->v6.sin6_addr)); + case AF_INET: + if (addr1->v4.sin_port != addr2->v4.sin_port) + return 0; + return memcmp(&addr1->v4.sin_addr, &addr2->v4.sin_addr, + sizeof(addr1->v4.sin_addr)); + default: + tst_brkm(TBROK, tst_exit, "invalid address type %d", + addr1->sa.sa_family); + return -1; + } +} + +/* Test peer addresses for association. */ +int test_peer_addr(int sk, sctp_assoc_t asoc, sockaddr_storage_t *peers, int count) +{ + struct sockaddr *addrs; + int error, i, j; + struct sockaddr *sa_addr; + socklen_t addrs_size = 0; + void *addrbuf; + char *found = (char *) malloc(count); + memset(found, 0, count); + + error = sctp_getpaddrs(sk, asoc, &addrs); + if (-1 == error) { + tst_brkm(TBROK, tst_exit, "sctp_getpaddrs: %s", strerror(errno)); + return error; + } + if (error != count) { + sctp_freepaddrs(addrs); + tst_brkm(TBROK, tst_exit, "peer count %d mismatch, expected %d", + error, count); + } + addrbuf = addrs; + for (i = 0; i < count; i++) { + sa_addr = (struct sockaddr *)addrbuf; + switch (sa_addr->sa_family) { + case AF_INET: + addrs_size += sizeof(struct sockaddr_in); + addrbuf += sizeof(struct sockaddr_in); + break; + case AF_INET6: + addrs_size += sizeof(struct sockaddr_in6); + addrbuf += sizeof(struct sockaddr_in6); + break; + default: + errno = EINVAL; + sctp_freepaddrs(addrs); + tst_brkm(TBROK, tst_exit, "sctp_getpaddrs: %s", strerror(errno)); + return -1; + } + for (j = 0; j < count; j++) { + if (cmp_addr((sockaddr_storage_t *)sa_addr, + &peers[j]) == 0) { + found[j] = 1; + } + } + } + for (j = 0; j < count; j++) { + if (found[j] == 0) { + tst_brkm(TBROK, tst_exit, "peer address %d not found", j); + } + } + sctp_freepaddrs(addrs); + return 0; +} diff --git a/src/testlib/sctputil.h b/src/testlib/sctputil.h new file mode 100644 index 0000000..347c91b --- /dev/null +++ b/src/testlib/sctputil.h @@ -0,0 +1,324 @@ +/* SCTP kernel Implementation + * (C) Copyright IBM Corp. 2001, 2003 + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2001 Intel Corp. + * Copyright (c) 2001 Nokia, Inc. + * Copyright (c) 2001 La Monte H.P. Yarroll + * + * The SCTP implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Any bugs reported to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + * + * Written or modified by: + * La Monte H.P. Yarroll + * Karl Knutson + * Randall Stewart + * Ken Morneau + * Qiaobing Xie + * Daisy Chang + * Jon Grimm + * Sridhar Samudrala + * Hui Huang + */ + +#ifndef __sctputil_h__ +#define __sctputil_h__ + +#ifdef LTP +#include +#include +#endif + +#include + +typedef union { + struct sockaddr_in v4; + struct sockaddr_in6 v6; + struct sockaddr sa; +} sockaddr_storage_t; + + +#define REALLY_BIG 65536 + +/* Literal defines. */ +#ifdef PROT_SOCK +#define SCTP_TESTPORT_1 PROT_SOCK +#else +#define SCTP_TESTPORT_1 1024 +#endif +#define SCTP_TESTPORT_2 (SCTP_TESTPORT_1+1) + +#define SCTP_IP_BCAST htonl(0xffffffff) +#define SCTP_IP_LOOPBACK htonl(0x7f000001) + +/* These are stolen from . */ +#define SCTP_IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } } +#define SCTP_IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } } + +/* Display an IPv4 address in readable format. */ +#define NIPQUAD(addr) \ + ((unsigned char *)&addr)[0], \ + ((unsigned char *)&addr)[1], \ + ((unsigned char *)&addr)[2], \ + ((unsigned char *)&addr)[3] + +/* Display an IPv6 address in readable format. */ +#define NIP6(addr) \ + ntohs((addr).s6_addr16[0]), \ + ntohs((addr).s6_addr16[1]), \ + ntohs((addr).s6_addr16[2]), \ + ntohs((addr).s6_addr16[3]), \ + ntohs((addr).s6_addr16[4]), \ + ntohs((addr).s6_addr16[5]), \ + ntohs((addr).s6_addr16[6]), \ + ntohs((addr).s6_addr16[7]) + +#define DUMP_CORE { \ + char *diediedie = 0; \ + printf("DUMP_CORE %s: %d\n", __FILE__, __LINE__);\ + *diediedie = 0; \ +} + +#ifndef LTP +enum { + TPASS, + TINFO, +}; + +extern char *TCID; +extern int TST_TOTAL; +extern int TST_CNT; + +#define tst_brkm(a1, a2, whatever...) \ + { \ + printf("%s %2d BROK : ", TCID, ++TST_CNT); \ + printf(whatever); \ + printf("\n"); \ + DUMP_CORE \ + } +#define tst_resm(a1, whatever...) \ + { \ + printf("%s %2d %s : ", TCID, \ + (a1 == TPASS)?++TST_CNT:0, \ + (a1 == TPASS)?"PASS":"INFO"); \ + printf(whatever); \ + printf("\n"); \ + } +#endif + +static inline int test_socket(int domain, int type, int protocol) +{ + int sk = socket(domain, type, protocol); + if (-1 == sk) + tst_brkm(TBROK, tst_exit, "socket: %s", strerror(errno)); + return sk; +} + +static inline int test_bind(int sk, struct sockaddr *addr, socklen_t addrlen) +{ + int error = bind(sk, addr, addrlen); + if (-1 == error) + tst_brkm(TBROK, tst_exit, "bind: %s", strerror(errno)); + return error; +} + +static inline int test_bindx_add(int sk, struct sockaddr *addr, int count) +{ + int error = sctp_bindx(sk, addr, count, SCTP_BINDX_ADD_ADDR); + if (-1 == error) + tst_brkm(TBROK, tst_exit, "bindx (add): %s", strerror(errno)); + return error; +} + +static inline int test_listen(int sk, int backlog) +{ + int error = listen(sk, backlog); + if (-1 == error) + tst_brkm(TBROK, tst_exit, "listen: %s", strerror(errno)); + return error; +} + +static inline int test_connect(int sk, struct sockaddr *addr, socklen_t addrlen) +{ + int error = connect(sk, addr, addrlen); + if (-1 == error) + tst_brkm(TBROK, tst_exit, "connect: %s", strerror(errno)); + return error; +} + +static inline int test_connectx(int sk, struct sockaddr *addr, int count) +{ + int error = sctp_connectx(sk, addr, count, NULL); + if (-1 == error) + tst_brkm(TBROK, tst_exit, "connectx: %s", strerror(errno)); + return error; +} + +static inline int test_accept(int sk, struct sockaddr *addr, socklen_t *addrlen) +{ + int error = accept(sk, addr, addrlen); + if (-1 == error) + tst_brkm(TBROK, tst_exit, "accept: %s", strerror(errno)); + return error; +} + +static inline int test_send(int sk, const void *msg, size_t len, int flags) +{ + int error = send(sk, msg, len, flags); + if (len != error) + tst_brkm(TBROK, tst_exit, "send: error:%d errno:%d", + error, errno); + return error; +} + +static inline int test_sendto(int sk, const void *msg, size_t len, int flags, + const struct sockaddr *to, socklen_t tolen) +{ + int error = sendto(sk, msg, len, flags, to, tolen); + if (len != error) + tst_brkm(TBROK, tst_exit, "sendto: error:%d errno:%d", + error, errno); + return error; +} + +static inline int test_sendmsg(int sk, const struct msghdr *msg, int flags, + int msglen) +{ + int error = sendmsg(sk, msg, flags); + if (msglen != error) + tst_brkm(TBROK, tst_exit, "sendmsg: error:%d errno:%d", + error, errno); + return error; +} + +static inline int test_recv(int sk, void *buf, size_t len, int flags) +{ + int error = recv(sk, buf, len, flags); + if (-1 == error) + tst_brkm(TBROK, tst_exit, "recv: %s", strerror(errno)); + return error; +} + +static inline int test_recvmsg(int sk, struct msghdr *msg, int flags) +{ + int error = recvmsg(sk, msg, flags); + if (-1 == error) + tst_brkm(TBROK, tst_exit, "recvmsg: %s", strerror(errno)); + return error; +} + +static inline int test_shutdown(int sk, int how) +{ + int error = shutdown(sk, how); + if (-1 == error) + tst_brkm(TBROK, tst_exit, "shutdown: %s", strerror(errno)); + return error; +} + +static inline int test_getsockopt(int sk, int optname, void *optval, + socklen_t *optlen) +{ + int error = getsockopt(sk, SOL_SCTP, optname, optval, optlen); + if (error) + tst_brkm(TBROK, tst_exit, "getsockopt(%d): %s", optname, + strerror(errno)); + return error; +} + +static inline int test_setsockopt(int sk, int optname, const void *optval, + socklen_t optlen) +{ + int error = setsockopt(sk, SOL_SCTP, optname, optval, optlen); + if (error) + tst_brkm(TBROK, tst_exit, "setsockopt(%d): %s", optname, + strerror(errno)); + return error; +} + +static inline int test_sctp_peeloff(int sk, sctp_assoc_t assoc_id) +{ + int error = sctp_peeloff(sk, assoc_id); + if (-1 == error) + tst_brkm(TBROK, tst_exit, "sctp_peeloff: %s", strerror(errno)); + return error; +} + +static inline int test_sctp_sendmsg(int s, const void *msg, size_t len, + struct sockaddr *to, socklen_t tolen, + uint32_t ppid, uint32_t flags, + uint16_t stream_no, uint32_t timetolive, + uint32_t context) +{ + int error = sctp_sendmsg(s, msg, len, to, tolen, ppid, flags, stream_no, + timetolive, context); + if (len != error) + tst_brkm(TBROK, tst_exit, "sctp_sendmsg: error:%d errno:%d", + error, errno); + return error; +} + +static inline int test_sctp_send(int s, const void *msg, size_t len, + const struct sctp_sndrcvinfo *sinfo, + int flags) +{ + int error = sctp_send(s, msg, len, sinfo, flags); + if (len != error) + tst_brkm(TBROK, tst_exit, "sctp_send: error:%d errno:%d", + error, errno); + return error; +} + +static inline int test_sctp_recvmsg(int sk, void *msg, size_t len, + struct sockaddr *from, socklen_t *fromlen, + struct sctp_sndrcvinfo *sinfo, + int *msg_flags) +{ + int error = sctp_recvmsg(sk, msg, len, from, fromlen, sinfo, msg_flags); + if (-1 == error) + tst_brkm(TBROK, tst_exit, "sctp_recvmsg: %s", strerror(errno)); + return error; +} + +static inline void *test_malloc(size_t size) +{ + void *buf = malloc(size); + if (NULL == buf) + tst_brkm(TBROK, tst_exit, "malloc failed"); + return buf; +} + +void test_check_msg_notification(struct msghdr *, int, int, uint16_t, uint32_t); +void test_check_buf_notification(void *, int, int, int, uint16_t, uint32_t); +void test_check_msg_data(struct msghdr *, int, int, int, uint16_t, uint32_t); +void test_check_buf_data(void *, int, int, struct sctp_sndrcvinfo *, int, int, + uint16_t, uint32_t); +void *test_build_msg(int); +void test_enable_assoc_change(int); +void test_print_message(int sk, struct msghdr *msg, size_t msg_len); +int test_peer_addr(int sk, sctp_assoc_t asoc, sockaddr_storage_t *peers, int count); + +#endif /* __sctputil_h__ */ diff --git a/src/withsctp/Makefile.am b/src/withsctp/Makefile.am new file mode 100644 index 0000000..241c0f2 --- /dev/null +++ b/src/withsctp/Makefile.am @@ -0,0 +1,27 @@ +# -*- Makefile -*- +# +# The author (La Monte H.P. Yarroll) disclaims copyright on this file. +# + +include $(top_srcdir)/Makefile.vars +include $(top_srcdir)/Makefile.dirs +include $(top_srcdir)/Makefile.rules + +bin_PROGRAMS = checksctp +bin_SCRIPTS = withsctp + +AM_CPPFLAGS=-I../include +pkglib_LTLIBRARIES = libwithsctp.la +libwithsctp_la_SOURCES = sctp_load_libs.c sctp_socket.c sctp_bind.c \ + sctp_sockopt.c sctp_socket.h +libwithsctp_la_LDFLAGS = -version-info 1:10:0 -ldl + +pkgdoc_DATA = sctp_load_libs.c sctp_socket.c sctp_bind.c \ + sctp_sockopt.c sctp_socket.h checksctp.c + +withsctp: withsctp.in + $(edit) $< >$@ + +EXTRA_DIST += withsctp.in + +CLEANFILES += withsctp diff --git a/src/withsctp/Makefile.in b/src/withsctp/Makefile.in new file mode 100644 index 0000000..7178b21 --- /dev/null +++ b/src/withsctp/Makefile.in @@ -0,0 +1,652 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*- Makefile -*- +# +# The author (La Monte H.P. Yarroll) disclaims copyright on this file. +# + +# -*-makefile-*- +# +# type: deep, strictness: gnu + +# -*-makefile-*- +# +# Define here directories you want + + + + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.dirs $(top_srcdir)/Makefile.rules \ + $(top_srcdir)/Makefile.vars +bin_PROGRAMS = checksctp$(EXEEXT) +subdir = src/withsctp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdocdir)" +pkglibLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(pkglib_LTLIBRARIES) +libwithsctp_la_LIBADD = +am_libwithsctp_la_OBJECTS = sctp_load_libs.lo sctp_socket.lo \ + sctp_bind.lo sctp_sockopt.lo +libwithsctp_la_OBJECTS = $(am_libwithsctp_la_OBJECTS) +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +checksctp_SOURCES = checksctp.c +checksctp_OBJECTS = checksctp.$(OBJEXT) +checksctp_LDADD = $(LDADD) +binSCRIPT_INSTALL = $(INSTALL_SCRIPT) +SCRIPTS = $(bin_SCRIPTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/bin/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libwithsctp_la_SOURCES) checksctp.c +DIST_SOURCES = $(libwithsctp_la_SOURCES) checksctp.c +pkgdocDATA_INSTALL = $(INSTALL_DATA) +DATA = $(pkgdoc_DATA) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = $(datadir)/locale +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +MAINTAINERCLEANFILES = Makefile.in directories.h +DISTCLEANFILES = \\\ directories.h +CLEANFILES = withsctp +MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io +EXTRA_DIST = withsctp.in +LATEX = @LATEX@ +DVIPS = @DVIPS@ +DVIPDFM = @DVIPDFM@ +ENSCRIPTBIN = @ENSCRIPTBIN@ +PS2PDF = @PS2PDF@ +rootbindir = /bin +rootsbindir = /sbin +rootlibdir = /lib +pkgsysconfdir = $(sysconfdir)/@PACKAGE@ +pkgdocdir = $(datadir)/@PACKAGE@ +vpkgsysconfdir = $(pkgsysconfdir)/v@VERSION@ +vpkgdatadir = $(pkgdatadir)/v@VERSION@ +vpkglibdir = $(pkglibdir)/v@VERSION@ +vpkgdocdir = $(docdir)/v@VERSION@ + +# List here all the directories you want listed in the file to be used +# in your programs: +directories := \ + localedir \ + pkgsysconfdir \ + rootbindir \ + rootlibdir \ + rootsbindir \ + vpkgdatadir \ + vpkgdocdir \ + vpkglibdir \ + vpkgsysconfdir \ + \ + bindir \ + datadir \ + libdir \ + pkgdatadir \ + pkgdocdir \ + pkglibdir \ + sbindir + +edit = @sed \ + -e "s|\@bindir\@|$(bindir)|" \ + -e "s|\@libdir\@|$(libdir)|" \ + -e "s|\@PACKAGE\@|$(PACKAGE)|" + +bin_SCRIPTS = withsctp +AM_CPPFLAGS = -I../include +pkglib_LTLIBRARIES = libwithsctp.la +libwithsctp_la_SOURCES = sctp_load_libs.c sctp_socket.c sctp_bind.c \ + sctp_sockopt.c sctp_socket.h + +libwithsctp_la_LDFLAGS = -version-info 1:10:0 -ldl +pkgdoc_DATA = sctp_load_libs.c sctp_socket.c sctp_bind.c \ + sctp_sockopt.c sctp_socket.h checksctp.c + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.vars $(top_srcdir)/Makefile.dirs $(top_srcdir)/Makefile.rules $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/withsctp/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/withsctp/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(pkglibdir)" || $(mkdir_p) "$(DESTDIR)$(pkglibdir)" + @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(pkglibLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) --mode=install $(pkglibLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(pkglibdir)/$$f"; \ + else :; fi; \ + done + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @set -x; list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$p"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libwithsctp.la: $(libwithsctp_la_OBJECTS) $(libwithsctp_la_DEPENDENCIES) + $(LINK) -rpath $(pkglibdir) $(libwithsctp_la_LDFLAGS) $(libwithsctp_la_OBJECTS) $(libwithsctp_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +checksctp$(EXEEXT): $(checksctp_OBJECTS) $(checksctp_DEPENDENCIES) + @rm -f checksctp$(EXEEXT) + $(LINK) $(checksctp_LDFLAGS) $(checksctp_OBJECTS) $(checksctp_LDADD) $(LIBS) +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f $$d$$p; then \ + f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ + echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \ + else :; fi; \ + done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checksctp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sctp_bind.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sctp_load_libs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sctp_socket.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sctp_sockopt.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +install-pkgdocDATA: $(pkgdoc_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgdocdir)" || $(mkdir_p) "$(DESTDIR)$(pkgdocdir)" + @list='$(pkgdoc_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(pkgdocDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgdocdir)/$$f'"; \ + $(pkgdocDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgdocdir)/$$f"; \ + done + +uninstall-pkgdocDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgdoc_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pkgdocdir)/$$f'"; \ + rm -f "$(DESTDIR)$(pkgdocdir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/../.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdocdir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool \ + clean-pkglibLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-pkgdocDATA + +install-exec-am: install-binPROGRAMS install-binSCRIPTS \ + install-pkglibLTLIBRARIES + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ + uninstall-info-am uninstall-pkgdocDATA \ + uninstall-pkglibLTLIBRARIES + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-binSCRIPTS install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + install-pkgdocDATA install-pkglibLTLIBRARIES install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-binSCRIPTS uninstall-info-am uninstall-pkgdocDATA \ + uninstall-pkglibLTLIBRARIES + + +# To modify this target for another language, just copy, paste and +# modify the target to generate directories.h. We depend on +# config.status and Makefile.dirs, as anything changed is going to be +# reflected there. + +# This is for generating the list in C/C++ +directories.h: $(top_builddir)/config.status $(top_srcdir)/Makefile.dirs + @rm -f $@ + @echo -n "Creating $@ ..." + @echo "#ifndef __$(subst .,_,$@)__" > $@ + @echo "# define __$(subst .,_,$@)__" >> $@ + @echo "" >> $@ + @echo -e $(foreach v,$(directories),$(shell echo 'D_$(v) \"$($v)\"\\n')) \ + | sed 's/^ *D_/# define D_/' >> $@ + @echo "#endif" >> $@ + @echo " done" + +# -*-makefile-*- +# +# Generate pre-parsed C code. +%.i: %.c + $(COMPILE) -E -c $^ -o $@ + +.PRECIOUS: %.i +%.ci: %.i + -grep -v -e "^#" -e "^ *$$" $^ | indent > $@ + mv -f $@ $^ + +withsctp: withsctp.in + $(edit) $< >$@ +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/withsctp/README b/src/withsctp/README new file mode 100644 index 0000000..c7d8b97 --- /dev/null +++ b/src/withsctp/README @@ -0,0 +1,15 @@ +This is a package to let you use SCTP with your existing TCP-based binaries. + +usage: + +$ withsctp xinetd # Start xinetd stream services on SCTP. +$ withsctp telnet localhost # Make a telnet over SCTP/IP connection. + +To install, edit the top of Makefile to set your install path(s) and then + +$ make all +# make install + +This package originally written by La Monte H.P. Yarroll . +To submit fixes or bug reports see lksctp.sourceforget.net. +You can try the author or lksctp-developers@lists.sourceforget.net for support. diff --git a/src/withsctp/checksctp.c b/src/withsctp/checksctp.c new file mode 100644 index 0000000..9e50866 --- /dev/null +++ b/src/withsctp/checksctp.c @@ -0,0 +1,57 @@ +/* Does this host have SCTP? + * + * Copyright 2003 La Monte HP Yarroll + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with + * the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include + +/* IPPROTO_SCTP SHOULD be defined in + * /usr/include/linux/in.h but probably isn't. + * It is an enum element, not a #define, so we can't easily check. + */ +#define SHOULD_IPPROTO_SCTP 132 + +main() +{ + int fd; + + fd = socket(PF_INET, SOCK_STREAM, SHOULD_IPPROTO_SCTP); + + if (fd <= 0) { + perror("checksctp"); + exit(1); + } else { + fprintf(stderr, "SCTP supported\n"); + } + + close(fd); + exit(0); +} diff --git a/src/withsctp/sctp_bind.c b/src/withsctp/sctp_bind.c new file mode 100644 index 0000000..e744273 --- /dev/null +++ b/src/withsctp/sctp_bind.c @@ -0,0 +1,58 @@ +/* Wrap bind() to force the protocol for STREAM connections to SCTP. + * + * Thanks to Midgard Security Services for + * http://www.securiteam.com/tools/3D5PTR5QAE.html + * from whence I cribbed the code to find the old bind(). + * + * gcc sctp_socket.c sctp_bind.c -o sctp_socket.so -ldl -shared -O2 -s + * export LD_PRELOAD=./sctp_socket.so + * + * Copyright 2003 La Monte HP Yarroll + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with + * the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include /* for strncmp() */ +#include +#include "sctp_socket.h" + +/* IPPROTO_SCTP SHOULD be defined in + * /usr/include/linux/in.h but probably isn't. + * It is an enum element, not a #define, so we can't easily check. + */ +#define SHOULD_IPPROTO_SCTP 132 + +int +bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen) +{ + _sctp_load_libs(); + + /* STUB. The intent is to allow us to substitute an elaborate call to + * bindx() for the initial call to bind(). TBD. + */ + + return (real_bind)(sockfd, my_addr, addrlen); +} diff --git a/src/withsctp/sctp_load_libs.c b/src/withsctp/sctp_load_libs.c new file mode 100644 index 0000000..d6a521f --- /dev/null +++ b/src/withsctp/sctp_load_libs.c @@ -0,0 +1,67 @@ +/* Load the real underlying functions for withsctp and related scripts. + * + * Copyright 2003 La Monte HP Yarroll + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with + * the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "sctp_socket.h" + +int (*real_bind)(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen); +int (*real_socket)(int domain, int type, int protocol); +int (*real_setsockopt)(int s, int level, int optname, const void *optval, + socklen_t optlen); +static void *lib_handle = NULL; + +void +_sctp_load_libs(void) +{ + if (NULL != lib_handle) return; /* Only init once. */ + + if (!(lib_handle = dlopen("libc.so", RTLD_LAZY))) { + if (!(lib_handle = dlopen("libc.so.6", RTLD_LAZY))) { + fprintf(stderr, "error loading libc!\n"); + exit (1); + } + } + + if (!(real_socket = dlsym(lib_handle, "socket"))) { + fprintf(stderr, "socket() not found in libc!\n"); + exit (1); + } + + if (!(real_bind = dlsym(lib_handle, "bind"))) { + fprintf(stderr, "bind() not found in libc!\n"); + exit (1); + } + + if (!(real_setsockopt = dlsym(lib_handle, "setsockopt"))) { + fprintf(stderr, "setsockopt() not found in libc!\n"); + exit (1); + } +} diff --git a/src/withsctp/sctp_socket.c b/src/withsctp/sctp_socket.c new file mode 100644 index 0000000..37d73af --- /dev/null +++ b/src/withsctp/sctp_socket.c @@ -0,0 +1,59 @@ +/* Wrap socket() to force the protocol to SCTP for STREAM connections. + * + * Thanks to Midgard Security Services for + * http://www.securiteam.com/tools/3D5PTR5QAE.html + * from whence I cribbed the code to find the old socket(). + * + * gcc sctp_socket.c -o sctp_socket.so -ldl -shared -O2 -s + * export LD_PRELOAD=./sctp_socket.so + * + * Copyright 2003 La Monte HP Yarroll + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with + * the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include /* for strncmp() */ +#include +#include "sctp_socket.h" + +/* IPPROTO_SCTP SHOULD be defined in + * /usr/include/linux/in.h but probably isn't. + * It is an enum element, not a #define, so we can't easily check. + */ +#define SHOULD_IPPROTO_SCTP 132 + +int +socket(int domain, int type, int protocol) +{ + _sctp_load_libs(); + + if (((PF_INET == domain) || (PF_INET6 == domain)) + && (SOCK_STREAM == type)) { + protocol = SHOULD_IPPROTO_SCTP; + } + + return (real_socket)(domain, type, protocol); +} diff --git a/src/withsctp/sctp_socket.h b/src/withsctp/sctp_socket.h new file mode 100644 index 0000000..44c8226 --- /dev/null +++ b/src/withsctp/sctp_socket.h @@ -0,0 +1,69 @@ +/* Preprocessor definitions for withsctp and supporting scripts. + * + * Copyright 2003 La Monte HP Yarroll + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with + * the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Copyright 2003 La Monte HP Yarroll + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with + * the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include /* for dlopen() and company */ +#include +#include +#include +#include +#include + +extern int (*real_bind)(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen); +extern int (*real_socket)(int domain, int type, int protocol); +extern int (*real_setsockopt)(int s, int level, int optname, const void *optval, + socklen_t optlen); +extern void _sctp_load_libs(void); diff --git a/src/withsctp/sctp_sockopt.c b/src/withsctp/sctp_sockopt.c new file mode 100644 index 0000000..01b8308 --- /dev/null +++ b/src/withsctp/sctp_sockopt.c @@ -0,0 +1,56 @@ +/* Wrap socket() to force the protocol to SCTP for STREAM connections. + * + * Thanks to Midgard Security Services for + * http://www.securiteam.com/tools/3D5PTR5QAE.html + * from whence I cribbed the code to find the old socket(). + * + * Copyright 2003 La Monte HP Yarroll + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with + * the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include /* for strncmp() */ +#include +#include "sctp_socket.h" + +/* IPPROTO_SCTP SHOULD be defined in + * /usr/include/linux/in.h but probably isn't. + * It is an enum element, not a #define, so we can't easily check. + */ +#define SHOULD_IPPROTO_SCTP 132 + +int +setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) +{ + _sctp_load_libs(); + + if ((IPPROTO_TCP == level) && (TCP_NODELAY == optname)) { + level = SHOULD_IPPROTO_SCTP; + optname = SCTP_NODELAY; + } + + return (real_setsockopt)(s, level, optname, optval, optlen); +} diff --git a/src/withsctp/withsctp.in b/src/withsctp/withsctp.in new file mode 100644 index 0000000..fb5f7d0 --- /dev/null +++ b/src/withsctp/withsctp.in @@ -0,0 +1,12 @@ +#!/bin/sh +# -*- sh -*- +LIBDIR=@libdir@/@PACKAGE@ +BINDIR=@bindir@ +export LD_PRELOAD=${LIBDIR}/libwithsctp.so.1.0.10 +if ! ${BINDIR}/checksctp 2> /dev/null +then + ${BINDIR}/checksctp; + exit 1; +fi + +exec $*