Import Upstream version 1.10.0
This commit is contained in:
commit
04aa3f451d
|
@ -0,0 +1,34 @@
|
|||
Primary author of this package (when it was called pptp-linux):
|
||||
|
||||
C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
|
||||
Patches and bug-fixes by:
|
||||
|
||||
Christoph Lameter <christoph@lameter.com>
|
||||
Gordon Chaffee <chaffee@HOME.COM>
|
||||
mulix <mulix@actcom.co.il>
|
||||
James Cameron <quozl@laptop.org>
|
||||
Rein Klazes <rklazes@xs4all.nl>
|
||||
Thomas Quinot <thomas@cuivre.fr.eu.org>
|
||||
Rhialto <rhialto@azenomei.knuffel.net>
|
||||
Scott Venier <scott@scooter.cx>
|
||||
Jeff Wiedemeier <Jeff.Wiedemeier@hp.com>
|
||||
Yura Zotov <yz@altlinux.ru>
|
||||
Chris Wilson <chris@netservers.co.uk>
|
||||
Ed Marcotte <epm@cisco.com>
|
||||
Jan Pieter <jp@jp.dhs.org>
|
||||
Ed Meaney <epm@cisco.com>
|
||||
Yury Tarasievich <grog@grsu.by>
|
||||
Paul Howarth <paul@city-fan.org>
|
||||
Peter Surda <shurdeek@routehat.org>
|
||||
Nelson Ferraz <nferraz@gmail.com>
|
||||
Michael Adda <michael@hackers.co.il>
|
||||
Ilya Voronin <ivoronin@gmail.com>
|
||||
Charles Shen <cshen@cisco.com>
|
||||
Jan Just Keijser <jan.just.keijser@gmail.com>
|
||||
David Lamparter <equinox@diac24.net>
|
||||
Ruslan Atnabayeff <rfatnabayeff at gmail.com>
|
||||
|
||||
Package renamed from pptp-linux to pptp after version 1.5.0.
|
||||
|
||||
$Id: AUTHORS,v 1.21 2011/02/22 02:25:24 quozl Exp $
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 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 Lesser General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,984 @@
|
|||
Thu Jan 18 11:10:32 2018 James Cameron <quozl@laptop.org>
|
||||
|
||||
* pptp-1.10.0: released.
|
||||
[this file is not maintained, see NEWS and "git log"]
|
||||
|
||||
Tue Nov 29 16:13:57 2016 James Cameron <quozl@laptop.org>
|
||||
|
||||
* pptp-1.9.0: released.
|
||||
[this file is not maintained, see "git log"]
|
||||
|
||||
Wed Oct 23 19:04:57 2013 James Cameron <quozl@laptop.org>
|
||||
|
||||
* pptp-1.8.0: released.
|
||||
|
||||
Thu Aug 30 13:45:26 2012 Paul Howarth <paul@city-fan.org>
|
||||
|
||||
* options.pptp: fix typo in 'Encryption' comment, add notes and
|
||||
references regarding recent chapcrack exploit, note that the
|
||||
ppp_mppe kernel module will not load into the kernel if it's
|
||||
booted in FIPS mode (http://bugzilla.redhat.com/845112), and fix
|
||||
broken link to Jan Dubiec's ppp_mppe_mppc code.
|
||||
|
||||
Wed Nov 30 09:02:18 2011 Paul Howarth <paul@city-fan.org>
|
||||
|
||||
* Makefile (config.h): fix unexpected build failure with a
|
||||
highly-parallel build (-j16).
|
||||
|
||||
Thu Mar 3 12:24:15 2011 David Lamparter <david.lamparter@adyton.net>
|
||||
|
||||
* pptp.c, pptp_callmgr.c, pptp.8: add -nohostroute option to
|
||||
disable adding a host route for the pptp server to the routing
|
||||
table. Also add some documentation while at it.
|
||||
|
||||
Mon Feb 21 15:01:14 2011 David Lamparter <david.lamparter@adyton.net>
|
||||
|
||||
* pptp.c, pptp_callmgr.c, pptp_gre.c, pptp.8: add --rtmark option
|
||||
for specifying the Linux policy routing / netfilter mark.
|
||||
|
||||
Thu Sep 30 16:16:58 2010 Paul Howarth <paul@city-fan.org>
|
||||
|
||||
* pptp_ctrl.c: we could maintain a separate vector of peer call
|
||||
IDs and use that when we get a call-disconnect-notify packet to
|
||||
find our call ID and close that call, but as
|
||||
call-disconnect-notify packets are relatively rare, I've tried a
|
||||
slower but simpler approach of doing a linear search through the
|
||||
existing vector to look for the peer's call ID.
|
||||
|
||||
Tue Jun 15 15:02:28 2010 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.c (open_callmgr): fix usage of status returned by waitpid;
|
||||
it must be wrapped by WEXITSTATUS to shift bits as required.
|
||||
|
||||
Tue Jun 15 15:00:40 2010 James Cameron <quozl@laptop.org>
|
||||
|
||||
* pptp_ctrl.c (pptp_conn_is_dead): immediately destroying the
|
||||
connection and freeing the structure has led to segmentation
|
||||
faults on more recent heap implementations, since we use the
|
||||
structure after it has been freed.
|
||||
|
||||
Defer the free of the structure until after all uses of it have
|
||||
ceased, by adding a connection state for dead and terminating the
|
||||
main loop once it is detected.
|
||||
|
||||
Fri Jun 4 10:54:04 2010 Jan Just Keijser <jan.just.keijser@gmail.com>
|
||||
|
||||
* pptp_ctrl.c: check for failure return by pptp_send_ctrl_packet
|
||||
and avoid using freed struct conn.
|
||||
|
||||
Tue Nov 10 15:39:33 2009 Charles Shen <cshen@cisco.com>
|
||||
|
||||
* pptp_ctrl.c (ctrlp_disp): add call ID of outgoing call so that
|
||||
Call-Disconnect-Notify from peer causes correct disconnection
|
||||
sequence.
|
||||
|
||||
Thu Jun 25 11:39:24 2009 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* AUTHORS: maintainer mail address change, james.cameron@hp.com is
|
||||
no longer valid.
|
||||
|
||||
Mon Jun 1 14:43:00 2009 Paul Howarth <paul@city-fan.org>
|
||||
|
||||
* pptpsetup: only check for MPPE support in kernel and pppd if
|
||||
an encrypted tunnel is being created.
|
||||
|
||||
Wed Mar 25 13:38:00 2009 Paul Howarth <paul@city-fan.org>
|
||||
|
||||
* pptpsetup: retain permissions on chap-secrets file when
|
||||
deleting tunnels (http://bugzilla.redhat.com/492090).
|
||||
|
||||
Thu Jul 24 15:51:30 2008 Paul Howarth <paul@city-fan.org>
|
||||
|
||||
* routing.c, pptp_compat.c: compilation fixes for old
|
||||
distributions.
|
||||
|
||||
Thu Jul 24 15:28:32 2008 Ilya Voronin <ivoronin@gmail.com>
|
||||
|
||||
* routing.c, Makefile: fixe use of /bin/ip and all compiler
|
||||
warnings on Solaris.
|
||||
|
||||
Thu May 22 09:44:19 2008 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* routing.c: add config.h and use IP_BINARY.
|
||||
|
||||
* Makefile (IP): add pointer to IP binary, store it in config.h,
|
||||
and add dependencies to support parallel make and development.
|
||||
|
||||
Wed May 14 15:59:17 2008 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp-1.7.2 released.
|
||||
|
||||
Fri Jan 11 13:20:18 2008 Ilya Voronin <ivoronin@gmail.com>
|
||||
|
||||
* ppp_fcs.h, pptp.c, pptp_ctrl.h, pptp_gre.h, pptp_msg.h: port to
|
||||
Solaris 10/11.
|
||||
|
||||
Wed Nov 21 14:29:46 2007 Leo Savernik <l.savernik@aon.at>
|
||||
|
||||
* pptp_ctrl.c (pptp_fd_set): fix compile with an ANSI
|
||||
C89-compliant compiler.
|
||||
|
||||
Tue Aug 28 10:17:36 2007 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* README, pptp.c: assign copyright to Free Software Foundation,
|
||||
and make license explicit.
|
||||
|
||||
Signed-off-by: "C. Scott Ananian" <cscott@cscott.net>
|
||||
|
||||
Wed Apr 4 16:30:24 2007 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.8, pptp.c: add --test-type and --test-rate options.
|
||||
|
||||
* pptp_gre.c: use alternate write(2) function for sending GRE
|
||||
packets.
|
||||
|
||||
* test.c: implement reordering tests to assist with pptpd testing.
|
||||
These tests reorder the stream to simulate real-world examples.
|
||||
|
||||
Fri Dec 15 02:02:08 2006 Michael Adda <michael@hackers.co.il>
|
||||
|
||||
* pptp_gre.c: when we fail to write due to a transient error
|
||||
simply ignore it (treat it as a drop).
|
||||
|
||||
Thu Oct 12 13:52:46 2006 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_gre.c (pptp_gre_copy): select(2) may return error, and the
|
||||
code was checking the read file descriptors without checking if
|
||||
they are valid.
|
||||
|
||||
Thu Aug 17 14:36:18 2006 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* Makefile: add pptpsetup man page using pod2man.
|
||||
|
||||
Wed Aug 2 16:21:08 2006 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* routing.c, routing.h, pptp_callmgr.c (callmgr_main): add route
|
||||
to PPTP server. Experimental feature. Note that this has a
|
||||
side-effect of leaving a route to the server in place after the
|
||||
tunnel has terminated.
|
||||
|
||||
Wed Aug 2 16:19:06 2006 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.c: fix a few compilation warnings.
|
||||
|
||||
Wed Aug 2 16:02:23 2006 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptpsetup: merge updates from Nelson Ferraz as of 24th April.
|
||||
* Makefile (dist): include pptpsetup in kit.
|
||||
|
||||
Thu Apr 20 08:52:45 2006 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* Makefile (dist): remove Reference documentation as the license
|
||||
is non-free. The documentation is available from other sources.
|
||||
|
||||
Thu Apr 20 08:49:01 2006 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.8: merge Debian contribution in 1.7.0-2 by Ola Lundqvist.
|
||||
|
||||
Mon Apr 3 15:28:37 2006 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptpsetup: add script contributed by Nelson Ferraz.
|
||||
|
||||
Mon Mar 27 10:09:20 2006 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* options.pptp: add refuse-pap to default options, along with a
|
||||
comment that a server may need to use PAP or CHAP if it is not
|
||||
using MPPE.
|
||||
|
||||
Mon Feb 13 14:01:34 2006 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp-1.7.1 released.
|
||||
|
||||
Fri Feb 10 10:59:31 2006 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.c: use prctl(2) to set process name for gateway process so
|
||||
that killall(1) of pptp will affect control connection call
|
||||
manager only.
|
||||
|
||||
Mon Aug 29 15:42:03 2005 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.c: add --version feature.
|
||||
|
||||
Mon Aug 22 10:46:38 2005 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* util.c (sigpipe_assign): remove superfluous sigset variable
|
||||
and calls; they served no purpose. Reported by: Pavol Gono.
|
||||
|
||||
Sat Aug 20 23:14:25 2005 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* options.pptp: default to not require MPPE, per Red Hat Bugzilla
|
||||
#166394.
|
||||
|
||||
Thu Aug 11 10:46:32 2005 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* PROTOCOL-SECURITY: add write-up regarding protocol security risks.
|
||||
* Makefile (dist): add PROTOCOL-SECURITY write-up.
|
||||
|
||||
Wed Jul 27 20:49:30 2005 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp-1.7.0 released.
|
||||
|
||||
Mon Jul 11 13:17:37 2005 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_gre.c (decaps_gre): silently discard packets that are not
|
||||
for this call. Reported by: Alan Jenkins.
|
||||
|
||||
Thu Mar 31 17:41:17 2005 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_ctrl.c (pptp_dispatch): handle signals first, since there's
|
||||
a possibility of premature return from the function.
|
||||
|
||||
* pptp_callmgr.c (callmgr_main): terminate faster when peer closes
|
||||
control connection.
|
||||
|
||||
Thu Mar 10 11:07:52 2005 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_ctrl.c (pptp_handle_timer): when we close connection due to
|
||||
loss of echo replies, say so in the log.
|
||||
Reported by: Jean Wolter.
|
||||
|
||||
* pptp_ctrl.c: fix signal deadlock on kernel 2.6.x
|
||||
Reported by: Jean Wolter.
|
||||
|
||||
* util.c, util.h: adopt sigpipe implementation from pptpd.
|
||||
|
||||
* pptp_ctrl.c (pptp_conn_open): use sigpipe implementation instead
|
||||
of trying I/O in signal handler (which causes deadlocks).
|
||||
|
||||
* pptp_ctrl.c (pptp_fd_set): include the sigpipe in the file
|
||||
descriptor set.
|
||||
|
||||
* pptp_ctrl.c (pptp_dispatch): detect queued signals via sigpipe.
|
||||
|
||||
* pptp_ctrl.c (pptp_conn_destroy): close the sigpipe.
|
||||
|
||||
Fri Feb 18 12:38:18 2005 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp-1.6.0 released.
|
||||
|
||||
Fri Feb 18 12:38:02 2005 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* Makefile (install): move options.pptp to this package from the
|
||||
RPM spec file.
|
||||
|
||||
Tue Dec 14 08:56:07 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_ctrl.c (ctrlp_disp): fix typo. From: Avi Kivity
|
||||
<avi@argo.co.il>
|
||||
|
||||
Tue Dec 7 09:43:00 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_ctrl.c: add error propagation to the ctrlp_disp callchain,
|
||||
so that we don't double-free the connection on a stop control
|
||||
connection reply. From: Avi Kivity <avi@argo.co.il>
|
||||
|
||||
Wed Nov 10 09:49:48 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* util.{c,h}: recent compilers spew a packetload of compilation
|
||||
warnings. From: Avi Kivity <avi@argo.co.il>
|
||||
|
||||
Tue Nov 9 12:30:57 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.{8,c}, pptp_ctrl.c, pptp_options.h: add --idle-wait (time
|
||||
to wait before sending an echo request on the control connection)
|
||||
and --max-echo-wait (time to wait before giving up on lack of
|
||||
reply to an echo request). The latter is not yet implemented.
|
||||
|
||||
Tue Nov 9 12:23:48 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_callmgr.c, pptp_ctrl.{c,h}: pptp_dispatch and its
|
||||
subordinates insist on handling fatal errors by calling
|
||||
pptp_conn_destroy. unfortunately, as the comments say,
|
||||
callmgr_main uses the connection afterwards with the usual
|
||||
results. Added error propagation to the routines mentioned,
|
||||
allowing callmgr_main to have the honor of closing the connection.
|
||||
From: Avi Kivity <avi@argo.co.il>
|
||||
|
||||
Wed Oct 27 21:03:28 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_callmgr.c (callmgr_main): pptp sometimes crashes in
|
||||
pptp_fd_set and leaves a core dump. Think this is due to a signal
|
||||
being caught and longjmp'ed to callmgr_main's shutdown label after
|
||||
we are out of that function, causing garbage local variables to be
|
||||
used. From: Avi Kivity <avi@argo.co.il>
|
||||
|
||||
Wed Jul 21 16:52:01 CEST 2004 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp_ctrl.c (ctrlp_rep): Do not log sending of echo requests,
|
||||
preventing dead-locks observed with Linux 2.6 systems.
|
||||
The syslog call is not reentrant and must not be used within a
|
||||
signal handler. A better solution would probably be to get rid of
|
||||
the SIGALRM timer altogether.
|
||||
|
||||
Wed Jul 21 19:00:59 2004 Peter Surda <shurdeek@routehat.org>
|
||||
|
||||
* pptp_callmgr.c (callmgr_main): prevent kill of init.
|
||||
|
||||
Sat Jun 26 14:37:10 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_gre.c (decaps_hdlc): portability fix, use IPPROTO_IP in
|
||||
place of SOL_IP in getsockopt(). From: Thomas Quinot
|
||||
<thomas@cuivre.fr.eu.org>
|
||||
|
||||
Tue Jun 22 19:08:58 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* Makefile, AUTHORS, rename package from pptp-linux to pptp.
|
||||
|
||||
Tue Jun 22 18:08:27 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp-linux-1.5.0 released.
|
||||
|
||||
Fri Jun 11 09:28:05 2004 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pptp.8, pptp_gre.c: make the statistics work properly when
|
||||
buffering is disabled. Fix the issue with log messages claiming
|
||||
buffering when no buffering is being done.
|
||||
|
||||
Thu Jun 10 16:58:53 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.c (main): remove the sleep(3) on termination; it isn't
|
||||
really required; and causes the GRE-to-PPP gateway process to hang
|
||||
around after the connection has been terminated.
|
||||
|
||||
* pptp.c (open_callmgr): call manager was inheriting the GRE
|
||||
socket, so close it before launching the callmgr, a regression
|
||||
introduced 18th July 2002, in the patch to bind the GRE socket
|
||||
earlier.
|
||||
|
||||
Thu Jun 10 08:34:17 CEST 2004 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp_callmgr.c: fix a case when the call manager does not
|
||||
shutdown properly, a regression introduced by the changes on
|
||||
2003 Oct 22 and 23.
|
||||
|
||||
Wed Jun 9 10:08:02 2004 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pptp.8, pptp.c, pptp_gre.c, pptp_gre.h: add --nobuffer option to
|
||||
eliminate all buffering of packets, a "pptp quake patch".
|
||||
|
||||
Wed Jun 9 09:37:06 2004 Paul Howarth <paul@city-fan.org>
|
||||
|
||||
* inststr.c: fix non-setting of the command line.
|
||||
|
||||
Tue Jun 8 21:25:27 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp-linux-1.5.0-rc1 released.
|
||||
|
||||
Sat Jun 5 22:44:50 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_ctrl.c (pptp_read_some): fix for CPU loop after pppd killed
|
||||
with -9, if read() returns zero, it is because the control
|
||||
connection has closed, so destroy the connection.
|
||||
|
||||
Wed Mar 24 08:45:12 2004 Mark-Andre Hopf <mhopf@innominate.com>
|
||||
|
||||
* pptp.c: fix compile for ARM architecture.
|
||||
|
||||
Mon Mar 8 11:04:00 2004 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pptp.8: added documentation for command-line options where
|
||||
missing. Updated to reflect the use of getopt.
|
||||
|
||||
Tue Mar 2 09:53:53 2004 Peter McCurdy <pmccurdy@nit.ca>
|
||||
|
||||
* pptp.c (main, do_nothing): do not hang when a connection is
|
||||
refused. When the controlling process (pptp.c) paused while
|
||||
waiting for the child to send SIGUSR1, if the child died then the
|
||||
controlling process wouldn't ever wake up. Now if the child dies,
|
||||
SIGCHLD gets handled and the controlling process quits.
|
||||
|
||||
Tue Feb 10 20:35:18 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_gre.c (decaps_hdlc): temporarily add code that captures
|
||||
additional detail if EMSGSIZE is returned by read().
|
||||
|
||||
Fri Jan 2 10:05:17 2004 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp-linux-1.4.0 released.
|
||||
|
||||
Mon Dec 1 11:58:24 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.c (main): remove arguments debugging printf.
|
||||
|
||||
Wed Nov 26 12:22:00 2003 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pptp.c: fixed argument handling so that hostname can be supplied
|
||||
anywhere on the command line, not just at the start. pppd options
|
||||
starting with "-" but before "--" are no longer supported.
|
||||
|
||||
* pptp.c: added some spacing to improve readability, removed
|
||||
pointless "Step X" comments.
|
||||
|
||||
* pptp.c: fixed usage message: there should not be a "pppd" in the
|
||||
command line.
|
||||
|
||||
Mon Nov 10 15:39:41 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp-linux-1.4.0-rc1 released.
|
||||
|
||||
Thu Oct 23 12:48:54 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_callmgr.c (callmgr_main): if connection fails, pptp enters
|
||||
a CPU loop calling select() with no file descriptors set, and
|
||||
being given EBADF. Introduced by yesterday's modifications.
|
||||
Correct code to detect this situation and break the main loop.
|
||||
|
||||
Wed Oct 22 13:02:04 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_ctrl.c (pptp_call_open): add an assertion to prevent a call
|
||||
open attempt while the control connection is not established.
|
||||
|
||||
* pptp_callmgr.c (callmgr_main): avoid accepting a UNIX socket
|
||||
connection and therefore calling pptp_call_open() if the control
|
||||
connection has not yet been established.
|
||||
|
||||
* pptp_ctrl.c (pptp_conn_established): add function for
|
||||
pptp_callmgr.c to use to determine if the control connection has
|
||||
been established.
|
||||
|
||||
TODO: if a connection reply is not received, what happens?
|
||||
|
||||
Reported by: John BouAntoun
|
||||
|
||||
Mon Sep 8 10:33:41 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.c: fix for compile on OpenBSD. From: Waldemar Brodkorb
|
||||
|
||||
Mon Aug 18 12:12:00 2003 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pptp.c pptp_gre.c util.h: add log level control, to increase
|
||||
or reduce verbosity of log messages, for debugging and for people
|
||||
who have lossy connections.
|
||||
|
||||
Thu Aug 7 12:20:09 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_gre.c (decaps_gre): fix reporting of packet loss.
|
||||
From: Chris Wilson
|
||||
|
||||
Wed Jun 25 12:59:28 2003 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp_callmgr.c: Wait for the replies on our Call-Clear-Request's and
|
||||
Stop-Control-Connection-Request's.
|
||||
|
||||
* pptp_ctrl.c: small tweak in a message about non existant call:
|
||||
report the received call ID's.
|
||||
|
||||
Sun Jun 22 19:08:14 2003 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp_ctrl.c: Log the buffering and sending of ALL control
|
||||
messages (except Echo messages and Replies of course).
|
||||
Change the way the sending of these messages is done. The
|
||||
original way was to first put them into a buffer ( in
|
||||
pptp_send_ctrl_packet()) and at some later write the buffered
|
||||
bytes to the socket ( in pptp_write_some()). Now
|
||||
pptp_send_ctrl_packet first attempts to write the packet directly.
|
||||
Only it the write() does not write all of the bytes, the remaining
|
||||
ones are buffered. This should help to track bugs in this area (like
|
||||
one sending two Start-Control-Request's).
|
||||
|
||||
Thu Jun 19 09:09:53 2003 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp_ctrl.c: Improve logging of received control packets:
|
||||
Move duplicated code to report on Result codes and General errors
|
||||
to a separate function; Verbosely report error codes embedded in
|
||||
start-control-connection replies; Translated some French comment;
|
||||
Log when an unexpected Outgoing Call Reply is received; Log the
|
||||
receipt of ALL control messages (except in case of echo
|
||||
request/reply packets of which only the first 10 are logged);
|
||||
Shorten the name of the function "pptp_dispatch_ctrl_packet" to
|
||||
"ctrlp_disp", 25 characters is just too much in the log files.
|
||||
|
||||
Thu Jun 19 10:11:26 2003 Jan Pieter <jp@jp.dhs.org>
|
||||
|
||||
* Makefile (uninstall): include uninstall target, and a minor fix
|
||||
to dist.
|
||||
|
||||
Wed Jun 18 12:19:09 2003 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp_gre.c: Instead of logging the (a)synchronous mode
|
||||
of ppp, only issue a warning when it conflicts with the
|
||||
mode of pptp.
|
||||
Comparing two sequence numbers for(in)equality is safe even when
|
||||
a wrap-around has occurred. This contrasts with comparing for
|
||||
smaller/bigger. Remove a few unneeded tests for wrap-around.
|
||||
|
||||
Tue Jun 17 19:40:41 2003 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* dirutil.c, ppp_fcs.c, pptp.c, pptp_gre.c, util.c, vector_test.c,
|
||||
* pptp_ctrl.c, pptp_callmgr.c, vector.c : reformat code with
|
||||
standard 4 spaced indents, uniform function headings and some
|
||||
general tidying up. Patches have been separated in "diff -w"
|
||||
invariant patches that should be safe and others that may be
|
||||
not so safe.
|
||||
|
||||
Wed Jun 11 14:06:21 2003 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp_gre.c: When a timeout is specified in the select call
|
||||
make it always non-zero. Making this call block makes it likely
|
||||
that pppd will run before the select returns. This results in a
|
||||
big reduction in transmitted ack-only packets (number down from
|
||||
40% to 0.8% of received packets on my system).
|
||||
|
||||
Tue Jun 11 18:42:00 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp-linux-1.3.1 released.
|
||||
|
||||
Tue Jun 10 13:53:00 2003 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pptp_callmgr.c: fixed a bug with call manager socket naming,
|
||||
introduced since 1.2.0, which caused confusing problems when
|
||||
trying to open more than one tunnel from the same machine.
|
||||
|
||||
Tue Jun 10 18:43:34 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp-linux-1.3.0 released.
|
||||
|
||||
Tue Jun 3 19:16:52 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.8, pptp.c: change SIGHUP to SIGUSR1 for dumping stats.
|
||||
|
||||
Tue May 20 13:20:00 2003 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pptp.c: rewrote command-line usage information, to increase
|
||||
clarity and usefulness, and to describe various command-line
|
||||
options which have been added recently.
|
||||
|
||||
Fri May 23 20:52:05 2003 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp_ctrl.c: increase the verbosity of the log message at the
|
||||
receipt of a Call Disconnect Notification.
|
||||
|
||||
Mon May 12 16:56:14 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* Makefile: don't install the manpage with execute permission,
|
||||
swap LDFLAGS and LIBS so that one can say 'make LDFLAGS=-s' to
|
||||
create a stripped versions of the executables, introduce the
|
||||
optimization flag as a make variable, so that one can say 'make
|
||||
DEBUG= OPTIMIZE=-O2 LDFLAGS=-s'. From: Peter Breitenlohner
|
||||
|
||||
Tue Apr 29 19:13:33 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* Makefile (dist): remove CVS directory from distribution.
|
||||
Reported by: Ola Lundqvist
|
||||
|
||||
Tue Apr 15 10:28:00 2003 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pptp.c, pptp_gre.c, pptp_gre.h: Added GRE statistics counters
|
||||
and RTT calculation, which can be dumped to the syslog by sending
|
||||
a SIGHUP to the GRE-to-PPP gateway process.
|
||||
|
||||
Mon Apr 14 11:57:00 2003 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pptp_gre.c: Fixed one case where an ACK could be immediately
|
||||
followed by a data packet, they should be combined into a
|
||||
single packet.
|
||||
|
||||
Sat Mar 8 2003 15:19:12 2003 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp_gre.c, pqueue.c: Actually copy the packet into a new entry
|
||||
in the packet queue, fixing "unknown protocol" error messages;
|
||||
Change the program logic making it obvious that there is not a
|
||||
memory leak;
|
||||
Restore the "buffering out-of-order packet" log messages, so we
|
||||
have a chance to notice any more side effects.
|
||||
|
||||
Mon Feb 17 09:18:30 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_callmgr.c, pptp.c, Makefile: compile call manager from
|
||||
Makefile rather than include from pptp.c. From: Jan Pieter
|
||||
<jp@jp.dhs.org>
|
||||
|
||||
Sat Feb 15 21:32:42 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_ctrl.c, pptp_msg.h: move code out of .h file and into .c
|
||||
file. From: Jan Pieter <jp@jp.dhs.org>
|
||||
|
||||
Sat Feb 15 17:34:38 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.c: add include fixes for Apple MacOS X as contributed by an
|
||||
anonymous donor.
|
||||
|
||||
Sat Feb 15 14:59:20 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.c, pptp_callmgr.c, pptp_gre.c: add localbind option to
|
||||
support multiple clients from separate alias IP addresses.
|
||||
From: Yury Tarasievich, with contributions by Ed Marcotte.
|
||||
|
||||
Fri Feb 14 10:11:27 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp-linux-1.2.0 released.
|
||||
|
||||
Fri Feb 14 16:08:26 CET 2003 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp_ctrl.c, pptp_msg.h: tweak the outgoing call reply messages
|
||||
once more. Print the error text that comes with the result code.
|
||||
|
||||
* pptp.c: close all unused file descriptors belonging to the pty.
|
||||
|
||||
* pptp_gre.c: Convert received acknowledgement numbers from network
|
||||
to host order.
|
||||
|
||||
Mon Jan 20 11:46 2003 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pqueue.c, pqueue.h: changed "expires" field of pqueue entry to a
|
||||
struct timeval for microsecond accuracy (in theory =)
|
||||
|
||||
* pptp_gre.c: use queue head expiry time as the upper bound on how
|
||||
long we block waiting for data from the network or pppd
|
||||
|
||||
* pptp.c: allow setting of packet timeout with sub-second
|
||||
accuracy, print error message to stderr and exit if timeout out of
|
||||
range
|
||||
|
||||
Mon Jan 13 10:28 2003 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pqueue.c, pqueue.h: added freelist support for packet queue,
|
||||
From: Kai Poitschke <kai@poitschke.de>. Should help to
|
||||
prevent memory fragmentation and perhaps improve performance a
|
||||
little.
|
||||
|
||||
* pqueue.c: wrap some log() statements with DEBUG_CMD, should
|
||||
improve performance (thanks to Kai Poitschke)
|
||||
|
||||
* pptpd.c: bugfix for --log-string option: make a copy of the
|
||||
string with strdup, because optarg will be destroyed
|
||||
|
||||
Wed Jan 15 14:16:27 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* AUTHORS, DEVELOPERS, NEWS, README, TODO, USING: add or move CVS
|
||||
header to tail.
|
||||
* DEVELOPERS: change IRC server name to new alias.
|
||||
* AUTHORS: change a few addresses.
|
||||
* INSTALL: rewrite.
|
||||
* README, USING: review and adjust, minor changes.
|
||||
* Makefile (install): add MANDIR and man page.
|
||||
|
||||
Thu Jan 2 11:28:41 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_gre.c: fix response to dropped packets. From: Rein Klazes.
|
||||
|
||||
Thu Jan 2 09:11:33 2003 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.8: the IP address should be before the option. From: Rein
|
||||
Klazes
|
||||
|
||||
Mon Dec 30 15:57:48 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* Makefile (install): add install target.
|
||||
|
||||
Mon Dec 9 08:52:56 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_callmgr.c, pptp.c: close stderr after becoming daemon,
|
||||
otherwise ssh sessions, CGI scripts, or other programs that start
|
||||
pptp don't exit properly; they are held up until the pptp
|
||||
processes terminate and close stderr.
|
||||
|
||||
Thu Nov 21 08:41:39 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_gre.c: log return value from the read of the GRE socket as
|
||||
a signed number as well.
|
||||
|
||||
Wed Nov 20 11:21:48 CET 2002 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp_gre.c: log return value from the read of the pty as a signed
|
||||
number.
|
||||
|
||||
* pptp_ctrl.c: change the log message to clarify that error codes in a
|
||||
outgoing call reply come from the server, not the client.
|
||||
|
||||
Wed Nov 20 16:07:30 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* Makefile (dist): adjust distribution target to include new files
|
||||
since prior use.
|
||||
|
||||
Wed Nov 20 15:17:12 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_gre.c: hid many packet reordering log calls in an ifdef,
|
||||
added a hint as to cause of EIO on read of the pty.
|
||||
|
||||
Fri Oct 11 15:44 BST 2002 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pptp.c util.c util.h: added "--logstring" option to help identify
|
||||
connections in syslog output where multiple connections are made
|
||||
from the same host.
|
||||
|
||||
Wed Oct 02 10:31 BST 2002 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pptp_gre.c pqueue.c: changed some "log" statements to "warn" to
|
||||
reflect the severity of the condition, allowing much better filtering
|
||||
* util.c: changed _warn to log at WARNING, and _fatal at CRIT level
|
||||
* pptp_gre.c: disabled logging of individual accepted packets
|
||||
* pptp_gre.c: removed a potential NULL pointer dereference crash
|
||||
* pptp_gre.c: fixed the select-timeout check for packets in the queue
|
||||
* pqueue.h: increased window size to 300 following testing
|
||||
* pptp.c: added command-line parameter "--timeout" to set the
|
||||
lost packet timeout
|
||||
|
||||
Fri Aug 30 09:55:05 CEST 2002 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
pptp_gre.c: Try to send more ACK's piggy backed on data packets.
|
||||
Previously if there were any outstanding ACK's to be sent, the
|
||||
program used a non-blocking select (timeout zero) to see if
|
||||
any data packets are available. In most cases there will be none,
|
||||
since the time passed since the last read is too short and an ACK
|
||||
without data will be sent.
|
||||
This change allows one outstanding ACK, for at most 0.5 second,
|
||||
multiple outstanding ACK's are treated as before.
|
||||
Tests show that this gives a big reduction in the number of
|
||||
sent packets.
|
||||
|
||||
Fri Aug 30 09:15:35 CEST 2002 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp_gre.c: Sequence numbers of sent gre packets should start
|
||||
with 1.
|
||||
|
||||
Mon Aug 26 10:56:42 CEST 2002 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp.c pptp_gre.c pptp_gre.h: added "--sync" option to work
|
||||
in combination with the pppd sync option. In synchronous mode
|
||||
checksum calculations and (un-)escaping of control characters
|
||||
become unnecessary. This results in big CPU usage reduction.
|
||||
|
||||
Mon Aug 26 08:53:45 CEST 2002 Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
* pptp.c: fix bug in command line options parsing (misplaced break
|
||||
in switch statement).
|
||||
|
||||
Wed Aug 21 10:57:01 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.c: add handler for SIGCHLD.
|
||||
From: Peter Surda <shurdeek@panorama.sth.ac.at>
|
||||
|
||||
Thu Aug 15 09:30:00 2002 Chris Wilson <chris@netservers.co.uk>
|
||||
|
||||
* pqueue.h: increased window size following James' tests
|
||||
* pptp_gre.c: check for errors while dequeueing packets
|
||||
|
||||
Wed Aug 14 20:02:39 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp.c, pptp_gre.c, pqueue.c: packet re-ordering bugfixes
|
||||
following distributed testing:
|
||||
|
||||
- Moved daemon() call to run on GRE gateway process only, and not
|
||||
if running as pppd pty
|
||||
- Make select() timeout after 1 second if there is data in the
|
||||
queue, to prevent the queue from having to wait forever
|
||||
- Added log messages for accepting individual packets (noisy!)
|
||||
and for timeouts on missing packets
|
||||
- Fixed a bug with the packet queue (append to tail was broken)
|
||||
- Removed unused code from pqueue.c
|
||||
|
||||
From: chris@netservers.co.uk
|
||||
|
||||
Wed Aug 14 11:14:05 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pqueue.c, pqueue.h, pptp_gre.c: major changes to support packet
|
||||
re-ordering.
|
||||
|
||||
Queueing
|
||||
|
||||
Packets are added to the queue by decaps_gre if their sequence
|
||||
number is higher than expected, but within the window. The default
|
||||
window is defined as 30 packets.
|
||||
|
||||
Packets which are below the window (older than the most recent
|
||||
packet read) or above the window (too far ahead) are discarded, to
|
||||
protect against denial-of-service attacks.
|
||||
|
||||
Dequeueing
|
||||
|
||||
The new function dequeue_gre retrieves packets from the head of
|
||||
the queue which are:
|
||||
|
||||
1. Next in sequence (unwrapped or wrapped)
|
||||
|
||||
2. Older than five seconds (assuming that the intermediate packets
|
||||
have been lost by the network).
|
||||
|
||||
The function will continue to read packets from the head of the
|
||||
queue until it finds one which doesn't match these criteria, and
|
||||
then stop.
|
||||
|
||||
Limitations
|
||||
|
||||
There are some limitations with this patch:
|
||||
|
||||
- The receive window is hardcoded at 30 packets. I couldn't see
|
||||
where to get the negotiated and/or current window size from.
|
||||
|
||||
- The timeout is hardcoded at 5 seconds. A packet which was
|
||||
received and queued within the window, but which should have been
|
||||
preceded by other packets which never appeared, will be accepted
|
||||
anyway after this time (increasing the sequence number to its
|
||||
own).
|
||||
|
||||
- There may be memory leaks or other bugs in the reordering code.
|
||||
|
||||
* pqueue.c, pqueue.h, Makefile (PPTP_OBJS, PPTP_DEPS): add two new
|
||||
files to the pptp executable. pqueue.c implements the packet queue
|
||||
used by the reordering code, and pqueue.h describes its public
|
||||
interface. The queue is implemented as a linked list. This is
|
||||
required for reordering.
|
||||
|
||||
* pptp.c: Add a new command-line option, --debug. Prevents pptp
|
||||
from going into the background.
|
||||
|
||||
Change to call the daemon(3) function to change the current
|
||||
directory and close the standard file descriptors. This prevents a
|
||||
shell from hanging open if pptp is started remotely.
|
||||
|
||||
* Makefile (CFLAGS): reduce the optimisation level (gcc's -O flag)
|
||||
to zero (none), to make debugging easier.
|
||||
|
||||
* pptp.c (get_ip_address): avoid reporting h_errno value.
|
||||
|
||||
From: chris@netservers.co.uk
|
||||
|
||||
Thu Jul 18 12:26:25 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_gre.h, pptp_gre.c, pptp.c: bind the GRE socket early, by
|
||||
calling the a function pptp_gre_bind. Also changed prototype of
|
||||
pptp_gre_copy. Fixes ICMP Unreachable bug:
|
||||
<1026868263.2855.67.camel@jander> 16th July 2002.
|
||||
From: chris@netservers.co.uk
|
||||
|
||||
Thu May 30 18:28:02 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_ctrl.c (pptp_call_open): do translation to network byte
|
||||
order after limit checking of phone number.
|
||||
From: staelin@hpl.hp.com
|
||||
|
||||
2002-05-13 08:14:40 Muli Ben-Yehuda <mulix@actcom.co.il>
|
||||
|
||||
* TODO: remove 'remove setjmp/longjmp' TODO item.
|
||||
* pptp.c: change comment re volatile qualifiers.
|
||||
* pptp_callmgr.c: remove unused function 'conn_callback' and
|
||||
change comment re volatile qualifiers.
|
||||
|
||||
Thu Apr 4 09:34:10 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_ctrl.c: correct spelling error.
|
||||
From: Mary.Deck@COMPAQ.com
|
||||
|
||||
2002-03-30 13:13:52 mulix <mulix@actcom.co.il>
|
||||
|
||||
* USING: change URL for bezeq adsl howto.
|
||||
* pptp.c: (get_ip_address): if the user runs 'pptp --quirks ...'
|
||||
instead of 'pptp hostname', we'll get here and then give a verbose
|
||||
error message.
|
||||
|
||||
Mon Mar 11 10:21:00 2002 mulix <mulix@actcom.co.il>
|
||||
|
||||
* Makefile (all): make config.h before making $(PPTP_BIN).
|
||||
* Makefile (config.h): truncate the file if it exists before
|
||||
inputing to it - '>' instead of '>>'
|
||||
|
||||
Mon Mar 11 12:48:16 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* DEVELOPERS: add mailing lists.
|
||||
* Makefile (CFLAGS): remove PPPD_BINARY and PPTP_LINUX_VERSION in
|
||||
favour of a config.h file.
|
||||
* Makefile (config.h): create config.h from Makefile variables
|
||||
* Makefile (PPTP_DEPS): add config.h
|
||||
* pptp.c: include config.h
|
||||
* version.c: include config.h
|
||||
* util.c (PROGRAM_NAME): no longer used by two programs, change
|
||||
PROGRAM_NAME to default to pptp.
|
||||
* Makefile (CFLAGS): remove -DPROGRAM_NAME
|
||||
|
||||
Fri Mar 8 11:56:00 2002 mulix <mulix@actcom.co.il>
|
||||
|
||||
* TODO: remove notes about compiler warnings, as all compiler
|
||||
warnings are now gone.
|
||||
* pptp.c (main): add volatile qualifier to some variables to
|
||||
silence gcc warnings 'variable might be clobbered by longjmp or
|
||||
vfork'. add note explaining why volatile and that it should be
|
||||
removed when the longjmp is removed.
|
||||
* pptp_callmgr.c (main): likewise.
|
||||
* inststr.c (inststr): break up "ptr += strlen(++ptr)" which is
|
||||
undefined behaviour into two expressions.
|
||||
* pptp.c (main): initialize callmgr_sock to -1 since it might be
|
||||
used uninitialized otherwise.
|
||||
* pptp_ctrl.c (pptp_dispatch_ctrl_packet): #ifdef 0 two unused
|
||||
variables referring to the current packet, which should not be
|
||||
simply erased, as we might want to use them in the future.
|
||||
* util.c: add missing #include.
|
||||
|
||||
Fri Mar 8 21:11:17 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* DEVELOPERS: new file.
|
||||
|
||||
Fri Mar 8 10:12:28 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* NEWS: convert to newest first format to comply with GNU Coding
|
||||
Standards, The NEWS File.
|
||||
|
||||
Fri Mar 8 09:01:22 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_ctrl.c (pptp_make_packet): Cisco PIX is generating a
|
||||
non-complaint header with the reserved0 field not zero, causing
|
||||
the connection to stop after 60 seconds.
|
||||
From: Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
Fri Mar 8 08:56:30 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* TODO: add compiler warnings note.
|
||||
* NEWS: propogate summary of ChangeLog.
|
||||
* AUTHORS: add names from mailing list contributions.
|
||||
From: Rein Klazes <rklazes@xs4all.nl>
|
||||
* Makefile: remove pptp_callmgr binary
|
||||
* debian/copyright: adjust pointer to current release.
|
||||
* debian/rules, Makefile: remove pptp_callmgr binary now that pptp
|
||||
forks and calls it without exec.
|
||||
|
||||
Sat Mar 2 04:04:37 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* README: adopt new mailing lists and point to project web site.
|
||||
* USING: include psuedo-tty activation instructions.
|
||||
* Makefile: increment version, avoid clobbering editor backup
|
||||
files on clean.
|
||||
|
||||
Fri Mar 1 12:13:03 2002 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_gre.c: move #include <sys/types.h> higher up
|
||||
* pptp_gre.c, pptp_ctrl.c: change unsigned to unsigned int
|
||||
* pptp.c: what we need from pty.h is in libutil.h for FreeBSD and
|
||||
util.h for NetBSD (ideally this should be in autoconf)
|
||||
* pptp.c: synchronisation changes
|
||||
* orckit_quirks.c: #include <sys/types.h>
|
||||
From: rhialto@azenomei.knuffel.net
|
||||
|
||||
Fri Nov 23 14:42:07 2001 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* USING: reformat, add version header.
|
||||
|
||||
Tue Nov 20 11:01:10 2001 mulix <mulix@actcom.co.il>
|
||||
|
||||
* AUTHORS: add mulix.
|
||||
* USING: add paragraph on quirks support.
|
||||
* orckit_quirks.c: remove debugging call, rename functions and
|
||||
variables consistently.
|
||||
* pptp.c: (usage) remove debugging print.
|
||||
* pptp_ctrl.c: when calling quirks hooks, check their return
|
||||
values and warn if an error occurs.
|
||||
* pptp_quirks.c: orckit_atur3_start_ctrl_conn was renamed
|
||||
orckit_atur3_start_ctrl_conn_hook.
|
||||
From: mulix@actcom.co.il
|
||||
|
||||
Tue Nov 20 17:01:10 2001 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* orckit_quirks.c, orckit_quirks.h: add quirks handling for orckit
|
||||
adsl modems.
|
||||
* pptp_quirks.c, pptp_quirks.h: add generic quirks handling.
|
||||
* Makefile (PPTP_DEPS, PPTP_OBJS, CALLMGR_OBJS, CALLMGR_DEPS): add
|
||||
quirks sources and objects.
|
||||
* pptp_ctrl.c: add pptp_set_link, add code to adjust packets
|
||||
depending on quirks.
|
||||
* pptp.c (usage, long_options, main): add --quirks command line
|
||||
option.
|
||||
From: mulix@actcom.co.il
|
||||
|
||||
Tue Nov 20 16:45:35 2001 James Cameron <quozl@us.netrek.org>
|
||||
|
||||
* pptp_gre.c: enhance error message for bad FCS.
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
Developers Information
|
||||
|
||||
|
||||
Mailing List
|
||||
|
||||
Subscribe to the pptpclient-devel mailing list if you intend to
|
||||
contribute to this project. On this mailing list we discuss problems
|
||||
and changes.
|
||||
|
||||
https://lists.sourceforge.net/lists/listinfo/pptpclient-devel
|
||||
|
||||
|
||||
Patches
|
||||
|
||||
You may send patches by e-mail, direct or to the mailing list, or if
|
||||
you have CVS commit rights, you may use them.
|
||||
|
||||
Developers have permission (and encouragement) to adjust more than the
|
||||
file that they are submitting. Other files that may be adjusted are:
|
||||
|
||||
ChangeLog
|
||||
documentation of changes at the code level.
|
||||
|
||||
NEWS
|
||||
a history of changes as far as an end user is concerned.
|
||||
|
||||
AUTHORS
|
||||
a list of people who want credit for contributions.
|
||||
|
||||
TODO
|
||||
a list of things yet to be done.
|
||||
|
||||
See section two of Eric Raymond's Software Release Practice HOWTO for
|
||||
some useful information on good patching practice.
|
||||
|
||||
http://www.linuxdoc.org/HOWTO/Software-Release-Practice-HOWTO/
|
||||
|
||||
|
||||
CVS Commits Mailing List
|
||||
|
||||
Subscribe to the pptpclient-commits mailing list and you will receive
|
||||
messages from the CVS server when another developer commits.
|
||||
|
||||
https://lists.sourceforge.net/lists/listinfo/pptpclient-commits
|
||||
|
||||
|
||||
CVS Tags
|
||||
|
||||
There are two types of tags. Upstream source and release tags.
|
||||
|
||||
Upstream source tags are set by the person who brings in the upstream
|
||||
version of ppp or ppp-mppe, and are not expected to move. This is
|
||||
because we are not the authoritative maintainer for those two
|
||||
packages; we're just generating a package ourselves.
|
||||
|
||||
Upstream source tags at the moment are
|
||||
|
||||
openssl-0_9_6
|
||||
openssl-mppe-0_9_6
|
||||
ppp-2_4_0
|
||||
ppp-2_4_1
|
||||
ppp-mppe-2_4_0
|
||||
ppp-mppe-2_4_1
|
||||
|
||||
Release tags are set by the release engineer who makes the releases.
|
||||
Only he is to move these tags.
|
||||
|
||||
Release tags at the moment are
|
||||
|
||||
pptp-linux-1_0_3-1
|
||||
pptp-linux-1_1_0-rc1
|
||||
pptp-linux-1_1_0-rc2
|
||||
pptp-linux-1_1_0-rc3
|
||||
ppp-mppe-2_4_0-3
|
||||
ppp-mppe-2_4_1-rc1
|
||||
|
||||
|
||||
Internet Relay Chat
|
||||
|
||||
Developers who use IRC on a regular basis are welcome to add the
|
||||
project's channel to their list of autojoin channels.
|
||||
|
||||
Server: irc.freenode.net
|
||||
Channel: #pptp
|
||||
|
||||
|
||||
$Id: DEVELOPERS,v 1.4 2003/01/15 05:29:20 quozl Exp $
|
|
@ -0,0 +1,23 @@
|
|||
Call Manager is a single-threaded application.
|
||||
It's easier that way.
|
||||
Nothing blocks except a select() call.
|
||||
|
||||
The pptp code provides an fd_set for us to watch, and a function
|
||||
to call to see if a given event pertains to the pptp code.
|
||||
Each CALL connection goes in the exceptions set, and is watched for close.
|
||||
We need a separate list of these, to check against the fd_set when
|
||||
an event happens.
|
||||
|
||||
Writes get copied in a queue, and are only written if the select says we
|
||||
can.
|
||||
|
||||
Reads go in another queue -- non-blocking! -- and messages are made from
|
||||
the queue as we are able.
|
||||
|
||||
We register callbacks on significant events (any and all of them, if
|
||||
we please) which can trigger a close on a user unix socket, for
|
||||
example.
|
||||
|
||||
Nomenclature:
|
||||
inet_read|write ... TCP port 1723 PPTP control connection
|
||||
unix_read|write ... Call manager Unix socket to pppd/gre.
|
|
@ -0,0 +1,53 @@
|
|||
pptp called as:
|
||||
pptp hostname [[pptp options] --] [pppd options]
|
||||
|
||||
The pptp program does:
|
||||
|
||||
gethostbyname([hostname]) to get ip number.
|
||||
|
||||
Try to open unix domain socket at /var/run/pptp/ip.num.ber.here.
|
||||
If not found, launch call manager for that ip address.
|
||||
|
||||
Call manager opens unix domain socket at /var/run/pptp/ip.num.ber.here, does:
|
||||
1) Open connection to the ip address using port 1723 protocol.
|
||||
2) accept unix domain socket connection.
|
||||
[wait for any pptp call request to this ip]
|
||||
3) On receiving a connection, open CALL to ip.address using port 1723.
|
||||
2) send callID over unix domain socket for gre encapsulation.
|
||||
3) Keepalive the socket. When either side closes socket, send
|
||||
call-close message to ip.address using port 1723.
|
||||
4) on close of last call, send connection close using port 1723,
|
||||
close the unix domain socket at /var/run/pptp/ip.num.ber.here,
|
||||
and exit.
|
||||
|
||||
Once call manager is opened (fork when done to return status to parent),
|
||||
the main process forks.
|
||||
Parent) launch gre-copy task. Holds call manager socket.
|
||||
Child) launch pppd with command-line options.
|
||||
|
||||
Killing any of the three threads should cleanly shutdown system. HOW?
|
||||
Send pid of parent and child to call manager after fork over
|
||||
Unix-domain socket.
|
||||
|
||||
Alternatively pptp may be launched by pppd. One advantage is that
|
||||
many existing tools for managing serial ppp connections can be used with
|
||||
pptp connections as well. Another is some pppd options can only be used
|
||||
this way. In particular the options "persist" and "demand" may be of use.
|
||||
|
||||
Add the following option to your pppd options script:
|
||||
|
||||
pty "<insert.path.to>/pptp hostname --nolaunchpppd [--phone phone-nr]"
|
||||
|
||||
and start the connection like any other pppd connection. Note that
|
||||
old versions of pppd may not support the pty option.
|
||||
|
||||
The following options are understood by pptp:
|
||||
|
||||
--phone phone-number
|
||||
Specify the phone number for the connection. This is required
|
||||
by a number of ADSL services.
|
||||
|
||||
--nolaunchpppd
|
||||
Needed if pptp is to be launched by pppd. See above
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
pptp uses very few linux-specific features, and should be easily
|
||||
portable to most Unix systems.
|
||||
|
||||
Two things to watch:
|
||||
1)
|
||||
The code in pty.[ch] to find a free pty/tty pair. This was
|
||||
conceptually borrowed from the xterm sources, which need to
|
||||
do more or less the same thing. *But* the xterm sources had
|
||||
a heck of a lot more system-specific #defines to cover all
|
||||
the eccentric unix variants out there. If you are porting
|
||||
this code to a non-unix system, I would recommend downloading
|
||||
the xterm sources to find out how pty.[ch] should look for
|
||||
your system. Xterm is in the standard X distribution, or
|
||||
you can download SRRMs from ftp.redhat.com.
|
||||
|
||||
Configure the xterm sources for your machine, and then preprocess
|
||||
main.c with these configuration options. E.g. I did:
|
||||
|
||||
[cananian@cananian xterm-sb_right-ansi-3d]# make main.o
|
||||
rm -f main.o
|
||||
gcc -c -O2 -fno-strength-reduce -m486 -I/usr/X11R6/include
|
||||
-Dlinux -D__i386__ -D_POSIX_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE
|
||||
-DX_LOCALE -DFUNCPROTO=15 -DNARROWPROTO -DUTMP -DUSE_TTY_GROUP
|
||||
-DOSMAJORVERSION=2 -DOSMINORVERSION=0 main.c
|
||||
|
||||
So the appropriate preprocessing command would be:
|
||||
|
||||
[cananian@cananian xterm-sb_right-ansi-3d]# gcc -E -O2
|
||||
-fno-strength-reduce -m486 -I/usr/X11R6/include -Dlinux -D__i386__
|
||||
-D_POSIX_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -DX_LOCALE
|
||||
-DFUNCPROTO=15 -DNARROWPROTO -DUTMP -DUSE_TTY_GROUP
|
||||
-DOSMAJORVERSION=2 -DOSMINORVERSION=0 main.c > main.CPP
|
||||
|
||||
Grok through the sources to figure out how the ptys are allocated on
|
||||
your machine. I suspect many people will want to look carefully at
|
||||
the function pty_search(), but there are architectures that have
|
||||
other, built-in, functions for doing the same thing.
|
||||
|
||||
Add the code to pty.[ch] with the proper #ifdefs, mail a patch back
|
||||
to me at <cananian@alumni.princeton.edu> and you're good to go!
|
||||
|
||||
2) The pptp_gre_copy function opens an IP protocol socket with:
|
||||
|
||||
s = socket(AF_INET, SOCK_RAW, PPTP_PROTO);
|
||||
|
||||
where PPTP_PROTO is #define'd in the code to be 47. I *think* that
|
||||
this should work across Unix variants, but if your system has a
|
||||
different method for opening a non-TCP, raw-IP-protocol-47 socket,
|
||||
then you'll have to make some changes here, and perhaps in
|
||||
decaps_gre and encaps_gre as well.
|
||||
|
||||
OK. Those are the only two potential non-portabilities I can think
|
||||
of. I should really be using automake/autoconf, of course, as well.
|
||||
--Scott 15Dec1997
|
||||
--------------------------------------------------------------------
|
||||
C. Scott Ananian <cananian@alumni.princeton.edu>
|
|
@ -0,0 +1,45 @@
|
|||
Installation Instructions - Brief
|
||||
|
||||
1. install pppd (with MPPE if you require it),
|
||||
2. if pppd is not in /usr/sbin, edit Makefile, variable PPPD,
|
||||
3. 'make'
|
||||
4. 'make install'
|
||||
|
||||
|
||||
Installation Instructions - Detailed
|
||||
|
||||
1. install PPP, and make sure it is working.
|
||||
|
||||
On most distributions, use the package called ppp or pppd.
|
||||
|
||||
If your PPTP server requires MPPE, make sure the pppd program
|
||||
has been built with MPPE and MS-CHAP support. PPP from
|
||||
version 2.4.2 onwards has this support. PPP may require
|
||||
kernel support for MPPE, which may require patching your
|
||||
kernel.
|
||||
|
||||
2. verify that the pppd program is in the /usr/sbin/ directory.
|
||||
|
||||
On some distributions, it is in /usr/bin, or somewhere else.
|
||||
If it isn't in the default directory, edit the Makefile, and
|
||||
change the PPPD variable to point at the pppd program.
|
||||
|
||||
You may even want to run a separate pppd program with MPPE
|
||||
support.
|
||||
|
||||
3. compile
|
||||
|
||||
Type 'make'. This should generate the 'pptp' executable.
|
||||
|
||||
4. install binaries
|
||||
|
||||
Type 'make install' to have the program and the manual page
|
||||
installed.
|
||||
|
||||
|
||||
Further information
|
||||
|
||||
http://pptpclient.sourceforge.net/
|
||||
|
||||
|
||||
$Id: INSTALL,v 1.2 2003/01/15 05:29:20 quozl Exp $
|
|
@ -0,0 +1,175 @@
|
|||
# $Id: Makefile,v 1.51 2011/11/29 22:05:07 quozl Exp $
|
||||
VERSION=1.10.0
|
||||
RELEASE=
|
||||
|
||||
#################################################################
|
||||
# CHANGE THIS LINE to point to the location of binaries
|
||||
PPPD = /usr/sbin/pppd
|
||||
# Solaris
|
||||
# PPPD = /usr/bin/pppd
|
||||
IP = /bin/ip
|
||||
#################################################################
|
||||
|
||||
BINDIR=$(DESTDIR)/usr/sbin
|
||||
MANDIR=$(DESTDIR)/usr/share/man/man8
|
||||
PPPDIR=$(DESTDIR)/etc/ppp
|
||||
|
||||
CC = gcc
|
||||
RM = rm -f
|
||||
OPTIMIZE= -O -Wuninitialized
|
||||
DEBUG = -g
|
||||
INCLUDE =
|
||||
# CFLAGS = -Wall $(OPTIMIZE) $(DEBUG) $(INCLUDE)
|
||||
# Solaris
|
||||
# CFLAGS += -D_XPG4_2 -D__EXTENSIONS__
|
||||
LIBS = -lutil
|
||||
# Solaris 10
|
||||
# LIBS = -lnsl -lsocket -lresolv
|
||||
# Solaris Nevada build 14 or above
|
||||
# LIBS = -lnsl -lsocket
|
||||
# LDFLAGS =
|
||||
|
||||
PPTP_BIN = pptp
|
||||
|
||||
PPTP_OBJS = pptp.o pptp_gre.o ppp_fcs.o \
|
||||
pptp_ctrl.o dirutil.o vector.o \
|
||||
util.o version.o test-redirections.o \
|
||||
pptp_quirks.o orckit_quirks.o pqueue.o pptp_callmgr.o routing.o \
|
||||
pptp_compat.o
|
||||
|
||||
PPTP_DEPS = pptp_callmgr.h pptp_gre.h ppp_fcs.h util.h test-redirections.h \
|
||||
pptp_quirks.h orckit_quirks.h config.h pqueue.h routing.h
|
||||
|
||||
all: config.h $(PPTP_BIN) pptpsetup.8
|
||||
|
||||
$(PPTP_BIN): $(PPTP_OBJS) $(PPTP_DEPS)
|
||||
$(CC) -o $(PPTP_BIN) $(PPTP_OBJS) $(LDFLAGS) $(LIBS)
|
||||
|
||||
pptpsetup.8: pptpsetup
|
||||
pod2man --section=8 $? > $@
|
||||
|
||||
config.h:
|
||||
( \
|
||||
echo "/* text added by Makefile target config.h */"; \
|
||||
echo "#define PPTP_LINUX_VERSION \"$(VERSION)$(RELEASE)\""; \
|
||||
echo "#define PPPD_BINARY \"$(PPPD)\""; \
|
||||
echo "#define IP_BINARY \"$(IP)\"" \
|
||||
) > config.h
|
||||
|
||||
vector_test: vector_test.o vector.o
|
||||
$(CC) -o vector_test vector_test.o vector.o
|
||||
./vector_test
|
||||
|
||||
clean:
|
||||
$(RM) *.o config.h pptpsetup.8
|
||||
|
||||
clobber: clean
|
||||
$(RM) $(PPTP_BIN) vector_test
|
||||
|
||||
distclean: clobber
|
||||
|
||||
test: vector_test
|
||||
|
||||
install:
|
||||
mkdir -p $(BINDIR)
|
||||
install -o root -m 555 pptp $(BINDIR)
|
||||
install -o root -m 555 pptpsetup $(BINDIR)
|
||||
mkdir -p $(MANDIR)
|
||||
install -m 644 pptp.8 $(MANDIR)
|
||||
install -m 644 pptpsetup.8 $(MANDIR)
|
||||
mkdir -p $(PPPDIR)
|
||||
install -m 644 options.pptp $(PPPDIR)
|
||||
|
||||
uninstall:
|
||||
$(RM) $(BINDIR)/pptp $(MANDIR)/pptp.8
|
||||
|
||||
dist: clobber
|
||||
$(RM) pptp-$(VERSION)$(RELEASE).tar.gz
|
||||
$(RM) -r pptp-$(VERSION)
|
||||
mkdir pptp-$(VERSION)
|
||||
cp --recursive ChangeLog Makefile *.c *.h options.pptp pptp.8 \
|
||||
pptpsetup Documentation AUTHORS COPYING INSTALL NEWS \
|
||||
README DEVELOPERS TODO USING PROTOCOL-SECURITY \
|
||||
pptp-$(VERSION)/
|
||||
$(RM) -r pptp-$(VERSION)/CVS pptp-$(VERSION)/*/CVS
|
||||
tar czf pptp-$(VERSION)$(RELEASE).tar.gz pptp-$(VERSION)
|
||||
$(RM) -r pptp-$(VERSION)
|
||||
md5sum pptp-$(VERSION)$(RELEASE).tar.gz
|
||||
|
||||
deb:
|
||||
chmod +x debian/rules
|
||||
fakeroot dpkg-buildpackage -us -uc
|
||||
mv ../pptp_$(VERSION)-0_i386.deb .
|
||||
|
||||
WEB=~/public_html/external/mine/pptp/pptpconfig
|
||||
release:
|
||||
cp pptp_$(VERSION)-0_i386.deb $(WEB)
|
||||
cd $(WEB);make
|
||||
|
||||
# The following include file dependencies were generated using
|
||||
# "makedepend -w0 *.c", then manually removing out of tree entries.
|
||||
# DO NOT DELETE
|
||||
|
||||
dirutil.o: dirutil.h
|
||||
orckit_quirks.o: pptp_msg.h
|
||||
orckit_quirks.o: pptp_compat.h
|
||||
orckit_quirks.o: pptp_options.h
|
||||
orckit_quirks.o: pptp_ctrl.h
|
||||
orckit_quirks.o: util.h
|
||||
ppp_fcs.o: ppp_fcs.h
|
||||
ppp_fcs.o: pptp_compat.h
|
||||
pptp.o: config.h
|
||||
pptp.o: pptp_callmgr.h
|
||||
pptp.o: pptp_gre.h
|
||||
pptp.o: pptp_compat.h
|
||||
pptp.o: version.h
|
||||
pptp.o: util.h
|
||||
pptp.o: pptp_quirks.h
|
||||
pptp.o: pptp_msg.h
|
||||
pptp.o: pptp_ctrl.h
|
||||
pptp.o: pqueue.h
|
||||
pptp.o: pptp_options.h
|
||||
pptp_callmgr.o: pptp_callmgr.h
|
||||
pptp_callmgr.o: pptp_ctrl.h
|
||||
pptp_callmgr.o: pptp_compat.h
|
||||
pptp_callmgr.o: pptp_msg.h
|
||||
pptp_callmgr.o: dirutil.h
|
||||
pptp_callmgr.o: vector.h
|
||||
pptp_callmgr.o: util.h
|
||||
pptp_callmgr.o: routing.h
|
||||
pptp_compat.o: pptp_compat.h
|
||||
pptp_compat.o: util.h
|
||||
pptp_ctrl.o: pptp_msg.h
|
||||
pptp_ctrl.o: pptp_compat.h
|
||||
pptp_ctrl.o: pptp_ctrl.h
|
||||
pptp_ctrl.o: pptp_options.h
|
||||
pptp_ctrl.o: vector.h
|
||||
pptp_ctrl.o: util.h
|
||||
pptp_ctrl.o: pptp_quirks.h
|
||||
pptp_gre.o: ppp_fcs.h
|
||||
pptp_gre.o: pptp_compat.h
|
||||
pptp_gre.o: pptp_msg.h
|
||||
pptp_gre.o: pptp_gre.h
|
||||
pptp_gre.o: util.h
|
||||
pptp_gre.o: pqueue.h
|
||||
pptp_gre.o: test-redirections.h
|
||||
pptp_quirks.o: orckit_quirks.h
|
||||
pptp_quirks.o: pptp_options.h
|
||||
pptp_quirks.o: pptp_ctrl.h
|
||||
pptp_quirks.o: pptp_compat.h
|
||||
pptp_quirks.o: pptp_msg.h
|
||||
pptp_quirks.o: pptp_quirks.h
|
||||
pqueue.o: util.h
|
||||
pqueue.o: pqueue.h
|
||||
routing.o: routing.h
|
||||
routing.o: config.h
|
||||
test-redirections.o: util.h
|
||||
test-redirections.o: test-redirections.h
|
||||
util.o: util.h
|
||||
vector.o: pptp_ctrl.h
|
||||
vector.o: pptp_compat.h
|
||||
vector.o: vector.h
|
||||
vector_test.o: vector.h
|
||||
vector_test.o: pptp_ctrl.h
|
||||
vector_test.o: pptp_compat.h
|
||||
version.o: config.h
|
|
@ -0,0 +1,180 @@
|
|||
Release 1.10.0: (18th January 2018)
|
||||
|
||||
- assign copyright of contributed pptpsetup and routing.c to FSF,
|
||||
- remove inststr in favour of prctrl PR_SET_NAME,
|
||||
- vector tests; include in make, fix code rot, fix return status,
|
||||
- pqueue; include missing sys/types.h,
|
||||
- pptpsetup; prevent world-readable peers file, use three-argument
|
||||
append, allow password trailing spaces, split prints to
|
||||
chap-secrets, allow passwords with quotes, use absolute path to
|
||||
pptp,
|
||||
- remove uid from ip route get output; iproute2-4.10 and later may
|
||||
emit uid,
|
||||
|
||||
Release 1.9.0: (29th November 2016)
|
||||
|
||||
- close a memory leak in pqueue,
|
||||
- avoid spurious error about /bin/ip on FreeBSD,
|
||||
- fix compiler warnings,
|
||||
- avoid clobbering heap (RHBZ #1183627),
|
||||
- fix use after free in call close request handler,
|
||||
- make clean to clean pptpsetup.8 (Debian #831032),
|
||||
- add --missing-window option (Debian #680455, Ubuntu #681617),
|
||||
- randomise call-id (Debian #721963),
|
||||
- replace gethostbyname(3) with getaddrinfo(3),
|
||||
- fix typo in pptp_ctrl manpage,
|
||||
- place pptpsetup manpage in correct section,
|
||||
- don't set build flags; use defaults,
|
||||
- remove pptpsetup.8 from source as it is generated,
|
||||
- fix for (null) in "pptp: GRE-to-PPP gateway on (null)".
|
||||
|
||||
Release 1.8.0: (23rd October 2013)
|
||||
|
||||
- options file, fix option documentation and links [Howarth]
|
||||
- fix many warnings [Howarth]
|
||||
- fix parallel build failure [Howarth]
|
||||
- fix call disconnect notify [Howarth]
|
||||
- add --nohostroute option to disable routing calls [Lamparter]
|
||||
- add --rtmark option for Linux policy routing [Lamparter]
|
||||
- move free of conn struct out of main loop [Cameron]
|
||||
- avoid using conn struct after it is freed [Keijser]
|
||||
- correct response to call disconnect notify [Shen]
|
||||
- avoid superfluous MPPE capability checks in pptpsetup [Howarth]
|
||||
- retain permissions on chap-secrets, closes RH BZ #492090 [Howarth]
|
||||
- compilation fixes for older distributions of Linux [Howarth]
|
||||
- port routing change feature for Solaris [Voronin]
|
||||
- add IP_BINARY [Cameron]
|
||||
- add include file build dependencies [Cameron]
|
||||
|
||||
Release 1.7.2: (14th May 2008)
|
||||
|
||||
- port for Solaris 10/11 [Voronin]
|
||||
- make copyright and license clearer [Cameron/Ananian]
|
||||
- add packet reordering test code for pptpd testing [Cameron]
|
||||
- ignore transient send errors [Adda]
|
||||
- fix flaw in return status check of select in GRE pipe (possibly
|
||||
fixes Debian Bug #427586) [Cameron]
|
||||
- add route to PPTP server [Cameron]
|
||||
- remove non-free reference documentation [Cameron]
|
||||
- fix quoting and pppd options [Lundqvist]
|
||||
- pptpsetup script with man page (Debian Bug #167216) [Ferraz]
|
||||
|
||||
Release 1.7.1: (13th February 2006)
|
||||
|
||||
- use prctl(2) to set process name [Cameron]
|
||||
- add --version option [Cameron]
|
||||
- remove superfluous sigset [Cameron/Gono]
|
||||
- default options file to not require MPPE (#166394) [Howarth]
|
||||
- add PROTOCOL-SECURITY discussion [Cameron/Mueller]
|
||||
|
||||
Release 1.7.0: (27th July 2005)
|
||||
|
||||
- silently discard packets not for the call [Cameron/Jenkins]
|
||||
- adopt sigpipe for use with SIGALRM on control connection [Wolter/Cameron]
|
||||
- fixes known valgrind heap violations in 1.6.0 [Cameron/Thorne]
|
||||
- properly report control connection echo reply loss [Wolter]
|
||||
|
||||
Release 1.6.0: (18th February 2005)
|
||||
|
||||
- fix double-free on stop control connection reply [Kivity]
|
||||
- add --idle-wait option [Cameron]
|
||||
- fix segfault on fatal connection error [Kivity]
|
||||
- prevent a possible signal race [Kivity]
|
||||
- prevent kill of init [Shurdeek]
|
||||
- portability fix for non-Linux systems [Quinot]
|
||||
- rename package from pptp-linux to pptp [Cameron]
|
||||
|
||||
Release 1.5.0: (22nd June 2004)
|
||||
|
||||
- fix statistics when buffering disabled [Wilson]
|
||||
- do not inherit the GRE socket [Cameron]
|
||||
- fix a case of non-shutdown of call manager [Klazes]
|
||||
- add --nobuffer option to eliminate all buffering of packets [Wilson]
|
||||
- fix corruption of command line as shown by ps [Howarth]
|
||||
- fix CPU loop after pppd killed [Cameron]
|
||||
- fix compile for ARM architecture [Hopf]
|
||||
- add documentation for command-line options [Wilson]
|
||||
- do not hang when a connection is refused [McCurdy]
|
||||
- better describe a cause of EMSGSIZE [Cameron]
|
||||
|
||||
Release 1.4.0: (2nd January 2004)
|
||||
|
||||
- support options before hostname [Wilson]
|
||||
- defer OCRQ until after SCCRP [Cameron]
|
||||
- include uninstall target [Pieter]
|
||||
- only issue a warning if sync mode is different to pppd [Klazes]
|
||||
- reformat and tidy code [Klazes]
|
||||
- reduce transmitted ack-only packets from 40% to 0.8% [Klazes]
|
||||
|
||||
Release 1.3.1: (11th June 2003)
|
||||
|
||||
- fixed bug introduced since 1.2.0 that prevented simultaneous tunnels.
|
||||
|
||||
Release 1.3.0: (10th June 2003)
|
||||
|
||||
- rewrite command usage text.
|
||||
- increase call disconnect notification log message verbosity.
|
||||
- inherit more make command line options.
|
||||
- remove execute permissions on man page.
|
||||
- fixed inefficient acknowledgement immediately followed by data packet.
|
||||
- added statistics for link quality monitoring.
|
||||
- remove include of callmgr, do separate compile.
|
||||
- remove duplicate messages caused by code in header file.
|
||||
- compilation fixes for Apple MacOS X.
|
||||
- support multiple clients on alias IP addresses.
|
||||
|
||||
Release 1.2.0: (14th February 2003)
|
||||
|
||||
- subsecond packet timeout to improve performance on fast links.
|
||||
- rewrite INSTALL.
|
||||
- add man page to install target.
|
||||
- fix response to dropped packets.
|
||||
- fix man page, address must be before options.
|
||||
- adopt man page contributed by Thomas Quinot.
|
||||
- close stderr to prevent holding open ssh sessions.
|
||||
- minor hint added in case of EIO on read() of pty.
|
||||
- support synchronous HDLC ppp encoding. Synchronous mode results in an
|
||||
important improvement of the CPU efficiency.
|
||||
- handle out-of-order packets arriving on the GRE socket by buffering.
|
||||
- bind GRE socket early to prevent ICMP Unreachable response by client.
|
||||
|
||||
Release 1.1.0: (20th March 2002)
|
||||
|
||||
- New release engineer.
|
||||
- allow activation as a psuedo-tty child process from pppd.
|
||||
This allows on demand pptp links or automatically reconnect.
|
||||
- ADSL modem quirks handler by mulix@actcom.co.il.
|
||||
Workarounds for Orckit ADSL modem.
|
||||
- workaround for Cisco PIX connection drop after 60 seconds.
|
||||
- enhance bad FCS error message.
|
||||
- ported to FreeBSD and NetBSD.
|
||||
- integrated call manager into pptp binary.
|
||||
- many bugfixes improving stability.
|
||||
|
||||
Release 1.0.3: (7th May 2001)
|
||||
|
||||
- New maintaining team.
|
||||
- Various bug fixes from the Debian package and FreeBSD port.
|
||||
- Incorporate patch to support erroneous return code with
|
||||
Alcatel ADSL 1000 modems.
|
||||
- Fix incorrect call id error.
|
||||
- New command line option: --phone (specify phone number).
|
||||
(Needed by the Dutch Mxstream ADSL service.)
|
||||
Contributed by Rein Klazes <rklazes@xs4all.nl>
|
||||
|
||||
Release 1.0.2:
|
||||
|
||||
- Fixed some warnings.
|
||||
- glibc patches by Christoph Lameter <christoph@lameter.com>
|
||||
- Race condition fix by Gordon Chaffee <chaffee@HOME.COM>
|
||||
|
||||
Release 1.0.1:
|
||||
|
||||
- Added versioning information to sources and makefile.
|
||||
- Bugfixes to pptp_ctrl.c.
|
||||
|
||||
Release 1.0.0:
|
||||
|
||||
- This is the first public release of the pptp-linux package.
|
||||
|
||||
$Id: NEWS,v 1.71 2011/11/29 22:05:07 quozl Exp $
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
Protocol Security
|
||||
|
||||
Summary
|
||||
|
||||
by Peter Mueller
|
||||
|
||||
PPTP is known to be a faulty protocol. The designers of the protocol,
|
||||
Microsoft, recommend not to use it due to the inherent risks. Lots of
|
||||
people use PPTP anyway due to ease of use, but that doesn't mean it is
|
||||
any less hazardous. The maintainers of PPTP Client and Poptop
|
||||
recommend using OpenVPN (SSL based) or IPSec instead.
|
||||
|
||||
(Posted on [1]2005-08-10 to the [2]mailing list)
|
||||
_________________________________________________________________
|
||||
|
||||
Why not use PPTP?
|
||||
|
||||
by James Cameron
|
||||
|
||||
The point to point tunneling protocol (PPTP) is not secure enough for
|
||||
some information security policies.
|
||||
|
||||
It's the nature of the MSCHAP V2 authentication, how it can be broken
|
||||
trivially by capture of the datastream, and how MPPE depends on the
|
||||
MSCHAP tokens for cryptographic keys. MPPE is also only 128-bit,
|
||||
reasonably straightforward to attack, and the keys used at each end
|
||||
are the same, which lowers the effort required to succeed. The obvious
|
||||
lack of two-factor authentication, instead relying on a single
|
||||
username and password, is also a risk. The increasing use of domestic
|
||||
wireless systems makes information capture more likely.
|
||||
|
||||
However, that doesn't mean people don't accept the risks. There are
|
||||
many corporations and individuals using PPTP with full knowledge of
|
||||
these risks. Some use mitigating controls, and some don't.
|
||||
|
||||
Many people seem to judge the security of a protocol by the
|
||||
availability of the implementation, the ease of installation, or the
|
||||
level of documentation on our web site. Improving the documentation is
|
||||
the purpose of this web site, and we aren't doing that in order to say
|
||||
anything about the risks of the software! Any judgement of security
|
||||
should be rigorously applied to the design and implementation alone.
|
||||
|
||||
PPTP on Linux, and Microsoft's PPTP, both implement fixes for
|
||||
vulnerabilities that were detected years ago in Microsoft's PPTP. But
|
||||
there remain the design vulnerabilities that cannot be fixed without
|
||||
changing the design. The changes needed would break interoperability.
|
||||
We can't change the Linux PPTP design, because it would stop working
|
||||
with Microsoft PPTP. They can't change their design, because it would
|
||||
stop working with all the other components out there, such as Nortel
|
||||
and Cisco, embedded routers, ADSL modems and their own Windows
|
||||
installed base.
|
||||
|
||||
The only option then is to deprecate the product and promote the
|
||||
replacement. Microsoft promote something else. Our choice for Open
|
||||
Source systems is OpenVPN or IPsec.
|
||||
|
||||
Level of acceptance isn't a good indicator of risk either. Some have
|
||||
said that the shipping of MSCHAP V2, MPPE and PPTP in Linux
|
||||
distributions is an indication of design security, but that's not the
|
||||
reason. It's for interoperability. As an example, see how Linux
|
||||
distributions still ship telnet, ftp, and rsh, even though these
|
||||
components are insecure because they reveal the password in cleartext
|
||||
in the network packets. The same can be said of many other components
|
||||
and packages.
|
||||
|
||||
Our recommendations are;
|
||||
|
||||
1. do not implement PPTP between open source systems, because there's
|
||||
no justification, better security can be had from OpenVPN or
|
||||
IPsec,
|
||||
|
||||
2. do not implement PPTP servers unless the justification is that the
|
||||
clients must not have to install anything to get going (Microsoft
|
||||
PPTP is included already), and be aware of the risks of
|
||||
information interception,
|
||||
|
||||
3. do not implement PPTP clients unless the justification is that the
|
||||
server only provides PPTP, and there's nothing better that can be
|
||||
used, and again be aware of the risks of information interception.
|
||||
|
||||
(Posted on [3]2005-08-10 to the [2]mailing list)
|
||||
|
||||
References
|
||||
|
||||
1. http://marc.theaimsgroup.com/?l=poptop-server&m=112369621702624&w=2
|
||||
2. http://pptpclient.sourceforge.net/contact.phtml#list
|
||||
3. http://marc.theaimsgroup.com/?l=poptop-server&m=112365342910897&w=2
|
|
@ -0,0 +1,49 @@
|
|||
pptp
|
||||
|
||||
pptp is an implementation of the PPTP protocol for Linux and
|
||||
other Unix systems.
|
||||
|
||||
Copyright (C) 2000 Free Software Foundation
|
||||
|
||||
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.
|
||||
|
||||
You can find notes on installing in the file INSTALL, usage notes in
|
||||
the file USING, design notes in the Documentation directory, and the
|
||||
standards documents used to implement pptp can be found in the
|
||||
Reference directory.
|
||||
|
||||
New versions and additional documentation can be found on the PPTP
|
||||
Client project page, at http://pptpclient.sourceforge.net/
|
||||
|
||||
Discussion of this code occurs on the mailing list for the PPTP Client
|
||||
project on SourceForge. To subscribe, visit the project's mailing
|
||||
lists page, or
|
||||
|
||||
http://lists.sourceforge.net/lists/listinfo/pptpclient-devel
|
||||
|
||||
Discussion of this code used to occur on the mailing list
|
||||
pptp@debs.fuller.edu, subscribe by sending "subscribe" in the body on
|
||||
an email to pptp-request@debs.fuller.edu, or look at
|
||||
http://debs.fuller.edu. Christoph Lameter was the list organizer.
|
||||
|
||||
Re-organization and patches are of course greatly welcomed.
|
||||
See the file TODO.
|
||||
|
||||
James Cameron <james.cameron@hp.com> (maintainer, release engineer)
|
||||
C. Scott Ananian <cananian@alumni.princeton.edu> (original author)
|
||||
|
||||
|
||||
$Id: README,v 1.6 2011/11/10 23:31:27 quozl Exp $
|
|
@ -0,0 +1,115 @@
|
|||
18th September 2006
|
||||
|
||||
https://sourceforge.net/tracker/?func=detail&atid=407155&aid=1560433&group_id=33063
|
||||
|
||||
Feature request, add code to attempt multiple IPs in a round-robin DNS
|
||||
rotation.
|
||||
|
||||
12th September 2006
|
||||
|
||||
https://sourceforge.net/tracker/?func=detail&atid=407152&aid=1556506&group_id=33063
|
||||
|
||||
Add call-id as quirk or command-line option.
|
||||
|
||||
13th February 2006
|
||||
|
||||
pty write may block, which prevents read, according to patch #502930 on
|
||||
SourceForge. Generally a lack of flow control. We don't implement flow
|
||||
control well.
|
||||
|
||||
8th April 2005
|
||||
|
||||
On Thu, Apr 07, 2005 at 07:36:41AM -0700, Roark Hennessy wrote:
|
||||
> I find in order to get the tunnel working I have to do a
|
||||
> route add -host <target_vpn_addr> gateway <my-netgear-wireless-router> dev
|
||||
+ethN
|
||||
> Can this be done automatically in the config somewhere?
|
||||
|
||||
Not everybody needs this in order to get the tunnel working, it depends
|
||||
on the configuration of the server, and it is problematic calculating
|
||||
the correct route to add. However, the GUI PPTP client (pptpconfig)
|
||||
does this automatically, and when done unnecessarily it seems harmless.
|
||||
|
||||
I'll take a patch that implements the same thing in C within pptp, so
|
||||
that people who don't use the GUI get it done for them.
|
||||
|
||||
Here's what the pptpconfig.php program does;
|
||||
|
||||
- the IP address of the PPTP server is obtained from the name, using
|
||||
gethostbyname(),
|
||||
|
||||
- the command "ip route get $ip | head -1" is executed, where $ip is the
|
||||
IP address determined above, and the result of the command is stored;
|
||||
it is a route specification of the path to the server before the
|
||||
tunnel is started,
|
||||
|
||||
- in routing_start(), an "ip route add" command is done using the route
|
||||
specification obtained above,
|
||||
|
||||
- when the tunnel is shutdown, an "ip route del" command is done using
|
||||
the same route specification.
|
||||
|
||||
I would prefer that the patch implements this by embedding the
|
||||
equivalent syscalls within the pptp program, rather than use system() or
|
||||
popen() to execute the /usr/sbin/ip program.
|
||||
|
||||
I would also prefer that there be a command line option for disabling
|
||||
the feature.
|
||||
|
||||
--
|
||||
|
||||
10th March 2005
|
||||
|
||||
- call manager is not being reused as it was designed to be; if a
|
||||
tunnel is started within a minute of a tunnel being stopped, it does
|
||||
not succeed; symptom is LCP ConfReq's without any traffic from the
|
||||
server.
|
||||
|
||||
--
|
||||
|
||||
- finish --max-echo-wait
|
||||
|
||||
11th August 2004
|
||||
|
||||
- add two configurable timeouts for echo generation and echo reply timeout,
|
||||
requested by Tobias Brox.
|
||||
|
||||
- ship .spec with tarball.
|
||||
|
||||
13th February 2004
|
||||
|
||||
- timeout connect earlier, with option to extend timeout.
|
||||
|
||||
20th May 2003
|
||||
|
||||
- GRE stats to a pipe or shared memory, for GUI to use
|
||||
|
||||
15th February 2003
|
||||
|
||||
- pptp.8 update man page for new options
|
||||
- pptp.c long_options array should use NULL for second last arg, not 0
|
||||
- pptp.c use getopt_long more simply, e.g. set flags in option array
|
||||
|
||||
1st May 2002
|
||||
|
||||
- log failure of write() to raw socket, as Ryan Murray
|
||||
<rmurray@debian.org> has encountered an EPERM situation that was not
|
||||
being logged.
|
||||
|
||||
12th February 2002
|
||||
|
||||
- clean up -T errors in pptp-command,
|
||||
|
||||
23rd December 2000
|
||||
|
||||
Things to do:
|
||||
Autoconf/automake this beastie.
|
||||
Fix do_gre_copy semantics to properly handle multiple calls.
|
||||
Like the call manager, there should only be one gre-copy process
|
||||
per connection. This process needs to funnel packets to different
|
||||
output tty's, though, depending on the call-id embedded in the
|
||||
GRE encapsulation. pptp.c must then be modified to use an
|
||||
already-existing gre-copy process in the same way it uses an
|
||||
already-existing call manager.
|
||||
|
||||
$Id: TODO,v 1.29 2006/09/18 01:50:05 quozl Exp $
|
|
@ -0,0 +1,98 @@
|
|||
Usage Notes
|
||||
|
||||
pptp is started as a psuedo-tty child process using pppd's pty option:
|
||||
|
||||
pppd call provider [pppd-options] \
|
||||
pty "/usr/sbin/pptp hostname --nolaunchpppd [pptp-options]"
|
||||
|
||||
where hostname is the host name or IP address of the PPTP server.
|
||||
|
||||
pptp can also start pppd itself:
|
||||
|
||||
pptp hostname [pptp-options] [pppd-options]
|
||||
|
||||
Note the unusual order of arguments, the hostname comes before the
|
||||
pptp options, and the pppd options come last.
|
||||
|
||||
So, for example:
|
||||
|
||||
pptp my.pptp.host debug name cananian \
|
||||
remotename ntdialup 172.18.0.2:172.18.0.3
|
||||
|
||||
route add -net 172.18.0.0 netmask 255.255.0.0 gw 172.18.0.3
|
||||
|
||||
You will see three pptp-related processes in your process list: a call
|
||||
manager, a GRE/PPP en/decapsulator, and pppd. To shut down the pptp
|
||||
connection, kill the pppd process.
|
||||
|
||||
NOTE THAT PPTP MUST BE RUN AS ROOT. This is so that it can generate
|
||||
GRE packets using a raw socket.
|
||||
|
||||
Most trouble with pptp will probably be due to incorrect pppd
|
||||
configuration. Be sure you thoroughly understand MS-CHAP support in
|
||||
pppd. Use the 'debug' option to pppd to log connection information;
|
||||
this will help you trouble-shoot the pppd side of pptp.
|
||||
|
||||
See the project web site for diagnosis assistance.
|
||||
|
||||
QUIRKS HANDLING:
|
||||
|
||||
Some ADSL providers and some ADSL hardware are buggy or not conforming
|
||||
to the RFC, and require special handling. To this end, pptp supports
|
||||
a 'quirks' mechanism. Currently, only '--quirks BEZEQ_ISRAEL' is
|
||||
defined, for connecting to Bezeq (the Israeli phone company) ADSL
|
||||
service.
|
||||
|
||||
Only *some* of the equipment used by Bezeq needs this option, but even
|
||||
the equipment that does not need it works fine with it. If you use
|
||||
Bezeq, you probably want the '--quirks BEZEQ_ISRAEL' switch.
|
||||
|
||||
More information on Bezeq's ADSL service can be found at
|
||||
http://vipe.technion.il/~mulix/adsl-howto.txt and
|
||||
http://damyen.technion.ac.il/~dani/adsl-howto.txt.
|
||||
|
||||
TESTING MULTIPLE TUNNELS:
|
||||
|
||||
For testing of PPTP servers, the client can be used to establish
|
||||
multiple tunnels from multiple IP addresses. The addresses must be
|
||||
routable; this is something you'd do on a local area network.
|
||||
|
||||
1. use an address pool on a concentrator.
|
||||
|
||||
2. write an ip-up script (e.g. /etc/ppp/ip-up.local or /etc/ppp/ip-up.d)
|
||||
|
||||
#!/bin/sh
|
||||
export PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
REALDEVICE=$1
|
||||
PEERADDR=$6
|
||||
ifconfig ${REALDEVICE} dstaddr ${PEERADDR}
|
||||
|
||||
The script performs an "ifconfig pppx dstaddr xx.xx.xx.xx" where
|
||||
xx.xx.xx.xx is the private address of the concentrator so that the
|
||||
routing works without having to do iptables or ipchains. The address
|
||||
used is given on the pptp command line.
|
||||
|
||||
3. create distinct source interfaces with:
|
||||
|
||||
ifconfig eth0:n xx.xx.xx.xx netmask yy.yy.yy.yy
|
||||
|
||||
Where "n" is the alias interface number, "xx.xx.xx.xx" is the new
|
||||
address, and "yy.yy.yy.yy" is the network mask.
|
||||
|
||||
4. connect with
|
||||
|
||||
pptp concentrator --bind xx.xx.xx.xx name \
|
||||
xx remotename yy ipparam yy.yy.yy.yy
|
||||
^ (private address of concentrator).
|
||||
|
||||
Where "xx.xx.xx.xx" is the address of the source interface, "xx" is
|
||||
the local name of the tunnel, "yy" is the remote name of the tunnel,
|
||||
and "yy.yy.yy.yy" is the private address of the concentrator. This is
|
||||
passed to the ip-up script as the sixth argument.
|
||||
|
||||
See also the following test scripts;
|
||||
|
||||
test-multiple-tunnels-1.sh creates multiple source interfaces
|
||||
test-multiple-tunnels-2.sh creates multiple tunnels
|
||||
|
||||
$Id: USING,v 1.6 2003/02/15 04:32:50 quozl Exp $
|
|
@ -0,0 +1,68 @@
|
|||
/* dirutil.c ... directory utilities.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: dirutil.c,v 1.2 2003/06/17 17:25:47 reink Exp $
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "dirutil.h"
|
||||
|
||||
/* Returned malloc'ed string representing basename */
|
||||
char *basenamex(char *pathname)
|
||||
{
|
||||
char *dup = strdup(pathname);
|
||||
char *ptr = strrchr(stripslash(dup), '/');
|
||||
if (ptr == NULL) return dup;
|
||||
ptr = strdup(ptr+1);
|
||||
free(dup);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Return malloc'ed string representing directory name (no trailing slash) */
|
||||
char *dirname(char *pathname)
|
||||
{
|
||||
char *dup = strdup(pathname);
|
||||
char *ptr = strrchr(stripslash(dup), '/');
|
||||
if (ptr == NULL) { free(dup); return strdup("."); }
|
||||
if (ptr == dup && dup[0] == '/') ptr++;
|
||||
*ptr = '\0';
|
||||
return dup;
|
||||
}
|
||||
|
||||
/* In-place modify a string to remove trailing slashes. Returns arg.
|
||||
* stripslash("/") returns "/";
|
||||
*/
|
||||
char *stripslash(char *pathname) {
|
||||
int len = strlen(pathname);
|
||||
while (len > 1 && pathname[len - 1] == '/')
|
||||
pathname[--len] = '\0';
|
||||
return pathname;
|
||||
}
|
||||
|
||||
/* ensure dirname exists, creating it if necessary. */
|
||||
int make_valid_path(char *dir, mode_t mode)
|
||||
{
|
||||
struct stat st;
|
||||
char *tmp = NULL, *path = stripslash(strdup(dir));
|
||||
int retval;
|
||||
if (stat(path, &st) == 0) { /* file exists */
|
||||
if (S_ISDIR(st.st_mode)) { retval = 1; goto end; }
|
||||
else { retval = 0; goto end; } /* not a directory. Oops. */
|
||||
}
|
||||
/* Directory doesn't exist. Let's make it. */
|
||||
/* Make parent first. */
|
||||
if (!make_valid_path(tmp = dirname(path), mode)) { retval = 0; goto end; }
|
||||
/* Now make this 'un. */
|
||||
if (mkdir(path, mode) < 0) { retval = 0; goto end; }
|
||||
/* Success. */
|
||||
retval = 1;
|
||||
|
||||
end:
|
||||
if (tmp != NULL) free(tmp);
|
||||
if (path != NULL) free(path);
|
||||
return retval;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/* dirutil.h ... directory utilities.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: dirutil.h,v 1.1 2000/12/23 08:19:51 scott Exp $
|
||||
*/
|
||||
|
||||
/* Returned malloc'ed string representing basename */
|
||||
char *basenamex(char *pathname);
|
||||
/* Return malloc'ed string representing directory name (no trailing slash) */
|
||||
char *dirname(char *pathname);
|
||||
/* In-place modify a string to remove trailing slashes. Returns arg. */
|
||||
char *stripslash(char *pathname);
|
||||
/* ensure dirname exists, creating it if necessary. */
|
||||
int make_valid_path(char *dirname, mode_t mode);
|
|
@ -0,0 +1,59 @@
|
|||
###############################################################################
|
||||
# $Id: options.pptp,v 1.4 2012/08/30 21:34:13 quozl Exp $
|
||||
#
|
||||
# Sample PPTP PPP options file /etc/ppp/options.pptp
|
||||
# Options used by PPP when a connection is made by a PPTP client.
|
||||
# This file can be referred to by an /etc/ppp/peers file for the tunnel.
|
||||
# Changes are effective on the next connection. See "man pppd".
|
||||
#
|
||||
# You are expected to change this file to suit your system. As
|
||||
# packaged, it requires PPP 2.4.2 or later from http://ppp.samba.org/
|
||||
# and the kernel MPPE module available from the CVS repository also on
|
||||
# http://ppp.samba.org/, which is packaged for DKMS as kernel_ppp_mppe.
|
||||
###############################################################################
|
||||
|
||||
# Lock the port
|
||||
lock
|
||||
|
||||
# Authentication
|
||||
# We don't need the tunnel server to authenticate itself
|
||||
noauth
|
||||
|
||||
# We won't do PAP, EAP, CHAP, or MSCHAP, but we will accept MSCHAP-V2
|
||||
# (you may need to remove these refusals if the server is not using MPPE)
|
||||
refuse-pap
|
||||
refuse-eap
|
||||
refuse-chap
|
||||
refuse-mschap
|
||||
|
||||
# Compression
|
||||
# Turn off compression protocols we know won't be used
|
||||
nobsdcomp
|
||||
nodeflate
|
||||
|
||||
# Encryption
|
||||
# (There have been multiple versions of PPP with encryption support,
|
||||
# choose which of the following sections you will use. Note that MPPE
|
||||
# requires the use of MSCHAP-V2 during authentication)
|
||||
#
|
||||
# Note that using PPTP with MPPE and MSCHAP-V2 should be considered
|
||||
# insecure:
|
||||
# http://marc.info/?l=pptpclient-devel&m=134372640219039&w=2
|
||||
# https://github.com/moxie0/chapcrack/blob/master/README.md
|
||||
# http://technet.microsoft.com/en-us/security/advisory/2743314
|
||||
|
||||
# http://ppp.samba.org/ the PPP project version of PPP by Paul Mackarras
|
||||
# ppp-2.4.2 or later with MPPE only, kernel module ppp_mppe.o
|
||||
# If the kernel is booted in FIPS mode (fips=1), the ppp_mppe.ko module
|
||||
# is not allowed and PPTP-MPPE is not available.
|
||||
# {{{
|
||||
# Require MPPE 128-bit encryption
|
||||
#require-mppe-128
|
||||
# }}}
|
||||
|
||||
# http://mppe-mppc.alphacron.de/ fork from PPP project by Jan Dubiec
|
||||
# ppp-2.4.2 or later with MPPE and MPPC, kernel module ppp_mppe_mppc.o
|
||||
# {{{
|
||||
# Require MPPE 128-bit encryption
|
||||
#mppe required,stateless
|
||||
# }}}
|
|
@ -0,0 +1,86 @@
|
|||
/* orckit_quirks.c ...... fix quirks in orckit adsl modems
|
||||
* mulix <mulix@actcom.co.il>
|
||||
*
|
||||
* $Id: orckit_quirks.c,v 1.4 2011/12/19 07:13:30 quozl Exp $
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include "pptp_msg.h"
|
||||
#include "pptp_options.h"
|
||||
#include "pptp_ctrl.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
|
||||
/* return 0 on success, non zero otherwise */
|
||||
int
|
||||
orckit_atur3_build_hook(struct pptp_out_call_rqst* packet)
|
||||
{
|
||||
unsigned int name_length = 10;
|
||||
|
||||
struct pptp_out_call_rqst fixed_packet = {
|
||||
PPTP_HEADER_CTRL(PPTP_OUT_CALL_RQST),
|
||||
0, /* hton16(call->callid) */
|
||||
0, /* hton16(call->sernum) */
|
||||
hton32(PPTP_BPS_MIN), hton32(PPTP_BPS_MAX),
|
||||
hton32(PPTP_BEARER_DIGITAL), hton32(PPTP_FRAME_ANY),
|
||||
hton16(PPTP_WINDOW), 0, hton16(name_length), 0,
|
||||
{'R','E','L','A','Y','_','P','P','P','1',0}, {0}
|
||||
};
|
||||
|
||||
if (!packet)
|
||||
return -1;
|
||||
|
||||
memcpy(packet, &fixed_packet, sizeof(*packet));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return 0 on success, non zero otherwise */
|
||||
int
|
||||
orckit_atur3_set_link_hook(struct pptp_set_link_info* packet,
|
||||
int peer_call_id)
|
||||
{
|
||||
struct pptp_set_link_info fixed_packet = {
|
||||
PPTP_HEADER_CTRL(PPTP_SET_LINK_INFO),
|
||||
hton16(peer_call_id),
|
||||
0,
|
||||
0xffffffff,
|
||||
0xffffffff};
|
||||
|
||||
if (!packet)
|
||||
return -1;
|
||||
|
||||
memcpy(packet, &fixed_packet, sizeof(*packet));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return 0 on success, non 0 otherwise */
|
||||
int
|
||||
orckit_atur3_start_ctrl_conn_hook(struct pptp_start_ctrl_conn* packet)
|
||||
{
|
||||
struct pptp_start_ctrl_conn fixed_packet = {
|
||||
{0, 0, 0, 0 , 0}, /* we'll set the header later */
|
||||
hton16(PPTP_VERSION), 0, 0,
|
||||
hton32(PPTP_FRAME_ASYNC), hton32(PPTP_BEARER_ANALOG),
|
||||
hton16(0) /* max channels */,
|
||||
hton16(0x6021),
|
||||
{'R','E','L','A','Y','_','P','P','P','1',0}, /* hostname */
|
||||
{'M','S',' ','W','i','n',' ','N','T',0} /* vendor */
|
||||
};
|
||||
|
||||
if (!packet)
|
||||
return -1;
|
||||
|
||||
/* grab the header from the original packet, since we dont
|
||||
know if this is a request or a reply */
|
||||
memcpy(&fixed_packet.header, &packet->header, sizeof(struct pptp_header));
|
||||
|
||||
/* and now overwrite the full packet, effectively preserving the header */
|
||||
memcpy(packet, &fixed_packet, sizeof(*packet));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/* orckit_quirks.h ...... fix quirks in orckit adsl modems
|
||||
* mulix <mulix@actcom.co.il>
|
||||
*
|
||||
* $Id: orckit_quirks.h,v 1.2 2001/11/23 03:42:51 quozl Exp $
|
||||
*/
|
||||
|
||||
#ifndef INC_ORCKIT_QUIRKS_H_
|
||||
#define INC_ORCKIT_QUIRKS_H_
|
||||
|
||||
#include "pptp_options.h"
|
||||
#include "pptp_ctrl.h"
|
||||
#include "pptp_msg.h"
|
||||
|
||||
/* return 0 on success, non zero otherwise */
|
||||
int
|
||||
orckit_atur3_build_hook(struct pptp_out_call_rqst* packt);
|
||||
|
||||
/* return 0 on success, non zero otherwise */
|
||||
int
|
||||
orckit_atur3_set_link_hook(struct pptp_set_link_info* packet,
|
||||
int peer_call_id);
|
||||
|
||||
/* return 0 on success, non zero otherwise */
|
||||
int
|
||||
orckit_atur3_start_ctrl_conn_hook(struct pptp_start_ctrl_conn* packet);
|
||||
|
||||
#endif /* INC_ORCKIT_QUIRKS_H_ */
|
|
@ -0,0 +1,116 @@
|
|||
/* Fast Frame Check Sequence (FCS) Implementation, for HDLC-like framing of
|
||||
* PPP. Adapted by C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
* from RFC1662:
|
||||
*
|
||||
* C.2. 16-bit FCS Computation Method
|
||||
*
|
||||
* The following code provides a table lookup computation for
|
||||
* calculating the Frame Check Sequence as data arrives at the
|
||||
* interface. This implementation is based on [7], [8], and [9].
|
||||
*
|
||||
* [7] Perez, "Byte-wise CRC Calculations", IEEE Micro, June 1983.
|
||||
*
|
||||
* [8] Morse, G., "Calculating CRC's by Bits and Bytes", Byte,
|
||||
* September 1986.
|
||||
*
|
||||
* [9] LeVan, J., "A Fast CRC", Byte, November 1987.
|
||||
*
|
||||
* $Id: ppp_fcs.c,v 1.2 2003/06/17 17:25:47 reink Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
#include "ppp_fcs.h"
|
||||
#define ASSERT(x) assert(x)
|
||||
|
||||
/*
|
||||
* u16 represents an unsigned 16-bit number. Adjust the typedef for
|
||||
* your hardware.
|
||||
*/
|
||||
typedef u_int16_t u16;
|
||||
|
||||
/*
|
||||
* FCS lookup table as calculated by the table generator.
|
||||
*/
|
||||
static u16 fcstab[256] = {
|
||||
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
|
||||
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
|
||||
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
|
||||
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
|
||||
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
|
||||
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
|
||||
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
|
||||
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
|
||||
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
|
||||
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
|
||||
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
|
||||
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
|
||||
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
|
||||
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
|
||||
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
|
||||
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
|
||||
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
|
||||
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
|
||||
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
|
||||
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
|
||||
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
|
||||
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
|
||||
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
|
||||
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
|
||||
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
|
||||
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
|
||||
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
|
||||
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
|
||||
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
|
||||
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
|
||||
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
|
||||
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
|
||||
};
|
||||
|
||||
#ifndef PPPINITFCS16
|
||||
#define PPPINITFCS16 0xffff /* Initial FCS value */
|
||||
#endif
|
||||
#ifndef PPPGOODFCS16
|
||||
#define PPPGOODFCS16 0xf0b8 /* Good final FCS value */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Calculate a new fcs given the current fcs and the new data.
|
||||
*/
|
||||
u16 pppfcs16(u16 fcs, void *_cp, int len)
|
||||
{
|
||||
register unsigned char *cp = (unsigned char *)_cp;
|
||||
/* don't worry about the efficiency of these asserts here. gcc will
|
||||
* recognise that the asserted expressions are constant and remove them.
|
||||
* Whether they are usefull is another question.
|
||||
*/
|
||||
ASSERT(sizeof (u16) == 2);
|
||||
ASSERT(((u16) -1) > 0);
|
||||
while (len--)
|
||||
fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff];
|
||||
return (fcs);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* How to use the fcs
|
||||
*/
|
||||
tryfcs16(cp, len)
|
||||
register unsigned char *cp;
|
||||
register int len;
|
||||
{
|
||||
u16 trialfcs;
|
||||
|
||||
/* add on output */
|
||||
trialfcs = pppfcs16( PPPINITFCS16, cp, len );
|
||||
trialfcs ^= 0xffff; /* complement */
|
||||
cp[len] = (trialfcs & 0x00ff); /* least significant byte first */
|
||||
cp[len+1] = ((trialfcs >> 8) & 0x00ff);
|
||||
|
||||
/* check on input */
|
||||
trialfcs = pppfcs16( PPPINITFCS16, cp, len + 2 );
|
||||
if ( trialfcs == PPPGOODFCS16 )
|
||||
printf("Good FCS\n");
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,12 @@
|
|||
/* ppp_fcs.h ... header file for PPP-HDLC FCS
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: ppp_fcs.h,v 1.2 2008/02/19 05:05:03 quozl Exp $
|
||||
*/
|
||||
|
||||
#include "pptp_compat.h"
|
||||
|
||||
#define PPPINITFCS16 0xffff /* Initial FCS value */
|
||||
#define PPPGOODFCS16 0xf0b8 /* Good final FCS value */
|
||||
|
||||
u_int16_t pppfcs16(u_int16_t fcs, void *cp, int len);
|
|
@ -0,0 +1,240 @@
|
|||
.\" SH section heading
|
||||
.\" SS subsection heading
|
||||
.\" LP paragraph
|
||||
.\" IP indented paragraph
|
||||
.\" TP hanging label
|
||||
.TH PPTP 8
|
||||
.\" NAME should be all caps, SECTION should be 1-8, maybe w/ subsection
|
||||
.\" other parms are allowed: see man(7), man(1)
|
||||
.SH NAME
|
||||
pptp \- PPTP driver
|
||||
.SH SYNOPSIS
|
||||
.B pptp
|
||||
.I "<pptp-server-IP> <pptp-options> [ppp-options] ..."
|
||||
.SH "DESCRIPTION"
|
||||
.LP
|
||||
.B pptp
|
||||
establishes the client side of a Virtual Private Network (VPN) using
|
||||
the Point-to-Point Tunneling Protocol (PPTP). Use this program to
|
||||
connect to an employer's PPTP based VPN, or to certain cable and ADSL
|
||||
service providers.
|
||||
.LP
|
||||
By default, \fBpptp\fR establishes the PPTP call to the PPTP server,
|
||||
and then starts an instance of \fBpppd\fR to manage the data transfer.
|
||||
However, \fBpptp\fR can also be run as a connection manager within
|
||||
\fBpppd\fR.
|
||||
.SH OPTIONS
|
||||
.LP
|
||||
The first non\-option argument on the \fBpptp\fR command line must be the host
|
||||
name or IP address of the PPTP server.
|
||||
.LP
|
||||
All long options (starting with "\-\-")
|
||||
are interpreted as pptp options, and a fatal error occurs if an
|
||||
unrecognised option is used.
|
||||
.LP
|
||||
All command\-line arguments which do not start
|
||||
with "\-" are interpreted as ppp options, and passed as is to \fBpppd\fR unless
|
||||
\fB\-\-nolaunchpppd\fR is given.
|
||||
.TP
|
||||
.B \-\-phone <number>
|
||||
Pass <number> to remote host as phone number
|
||||
.TP
|
||||
.B \-\-nolaunchpppd
|
||||
Do not launch
|
||||
.B pppd
|
||||
but use stdin as the network connection. Use this flag when including
|
||||
.B pptp
|
||||
as a
|
||||
.B pppd
|
||||
connection process using the
|
||||
.B pty
|
||||
option. See EXAMPLES.
|
||||
.TP
|
||||
.B \-\-quirks <quirk>
|
||||
Work around a buggy PPTP implementation, adopts special case handling for
|
||||
particular PPTP servers and ADSL modems.
|
||||
Currently recognised values are BEZEQ_ISRAEL only
|
||||
.TP
|
||||
.B \-\-debug
|
||||
Run in foreground (for debugging with gdb)
|
||||
.TP
|
||||
.B \-\-sync
|
||||
Enable Synchronous HDLC (pppd must use it too)
|
||||
.TP
|
||||
.B \-\-timeout <secs>
|
||||
Time to wait for reordered packets (0.01 to 10 secs)
|
||||
.TP
|
||||
.B \-\-nobuffer
|
||||
Completely disables buffering and reordering of packets.
|
||||
Any \-\-timeout specified will be ignored.
|
||||
.TP
|
||||
.B \-\-idle-wait <secs>
|
||||
Time to wait before sending a control connection echo request.
|
||||
The RFC2637 default is 60 seconds.
|
||||
.TP
|
||||
.B \-\-max-echo-wait <secs>
|
||||
Time to wait for an echo reply before closing the control connection.
|
||||
The RFC2637 default is 60 seconds.
|
||||
.TP
|
||||
.B \-\-logstring <name>
|
||||
Use <name> instead of 'anon' in syslog messages
|
||||
.TP
|
||||
.B \-\-localbind <addr>
|
||||
Bind to specified IP address instead of wildcard
|
||||
.TP
|
||||
.B \-\-rtmark <n>
|
||||
Use specified policy routing mark for all packets.
|
||||
This causes both the TCP control connection's packets as well as the
|
||||
GRE packets to bear the given policy routing / netfilter mark. This
|
||||
can be used with
|
||||
.I ip rule
|
||||
(from iproute2) to use a separate routing table for the pptp client.
|
||||
|
||||
(requires root privileges or the CAP_NET_ADMIN capability.)
|
||||
.TP
|
||||
.B \-\-nohostroute
|
||||
Do not configure a host route pointing towards the PPTP server.
|
||||
(cf. ROUTING below)
|
||||
|
||||
.TP
|
||||
.B \-\-loglevel <level>
|
||||
Sets the debugging level (0=low, 1=default, 2=high)
|
||||
|
||||
.TP
|
||||
.B \-\-test-type <n>
|
||||
Enable packet reordering tests that damage the integrity of the packet
|
||||
stream to the server. Use this only when testing servers. Zero is
|
||||
the default, and means that packets are sent in the correct order. A
|
||||
value of one (1) causes a single swap between two packets, such that
|
||||
the sequence numbers might be 1 2 3 4 6 5 7 8 9. A value of two (2)
|
||||
causes ten packets to be buffered, then sent out of order but
|
||||
ascending, such that the sequence numbers might be 1 2 3 4 16 6 7 8 9
|
||||
10 11 12 13 14 15 17 18 19 20. A value of three (3) causes ten
|
||||
packets to be buffered, then sent in the reverse order, like this; 1 2
|
||||
3 4 16 15 14 13 12 11 10 9 8 7 6 5 17 18 19 20.
|
||||
|
||||
.TP
|
||||
.B \-\-test-rate <n>
|
||||
Sets the number of packets to pass before causing a reordering test.
|
||||
Default is 100. Has no effect if test-type is zero. The result of
|
||||
test types 2 and 3 are undefined if this value is less than ten.
|
||||
|
||||
|
||||
.SH "ROUTING"
|
||||
When PPTP is used in conjunction with a default route on top of the
|
||||
tunnel (or just any route encompassing the PPTP server),
|
||||
the mechanics of routing would cause the PPTP packets themselves
|
||||
to be routed over the tunnel. This would result in an encapsulation
|
||||
loop, destroying connectivity.
|
||||
|
||||
.B pptp
|
||||
by default works around this by looking up the route towards the
|
||||
PPTP server at startup and configures a host route with that data.
|
||||
This essentially "freezes" routing for PPTP packets at the startup
|
||||
configuration. This behaviour can be disabled with
|
||||
.B --nohostroute
|
||||
if undesired (like when using
|
||||
.B --rtmark
|
||||
to implement policy routing).
|
||||
|
||||
.B NB:
|
||||
the route added by
|
||||
.B pptp
|
||||
is currently not deleted at exit!
|
||||
|
||||
.SH "QUIRKS"
|
||||
|
||||
.TP
|
||||
.B BEZEQ_ISRAEL
|
||||
modifies packets to interoperate with Orckit ADSL modems on the BEZEQ
|
||||
network in Israel.
|
||||
|
||||
.SH "EXAMPLES"
|
||||
|
||||
.B Connection to a Microsoft Windows VPN Server
|
||||
|
||||
.BR
|
||||
pppd noauth nobsdcomp nodeflate require\-mppe\-128 name domain\\\\\\\\username remotename PPTP pty "pptp 10.0.0.5 \-\-nolaunchpppd"
|
||||
.PP
|
||||
Note that the \fBchap\-secrets\fR file used by \fBpppd\fR must include an entry for domain\\\\username
|
||||
|
||||
.SH "STATISTICS"
|
||||
The pptp process collects statistics when sending and receiving
|
||||
GRE packets. They are intended to be useful for debugging poor PPTP
|
||||
performance and for general monitoring of link quality. The statistics
|
||||
are cumulative since the pptp process was started.
|
||||
.PP
|
||||
The statistics can be viewed by sending a SIGUSR1 signal to the
|
||||
"GRE-to-PPP Gateway" process, which will cause it to dump them
|
||||
to the system logs (at the LOG_NOTICE level). A better way to present
|
||||
the statistics to applications is being sought (e.g. SNMP?).
|
||||
.PP
|
||||
The following statistics are collected at the time of writing (April 2003):
|
||||
.TP
|
||||
.B rx accepted
|
||||
the number of GRE packets successfully passed to PPP
|
||||
.TP
|
||||
.B rx lost
|
||||
the number of packets never received, and presumed lost in the network
|
||||
.TP
|
||||
.B rx under win
|
||||
the number of packets which were duplicates or had old sequence numbers
|
||||
(this might be caused by a packet-reordering network if your reordering
|
||||
timeout is set too low)
|
||||
.TP
|
||||
.B rx over win
|
||||
the number of packets which were too far ahead in the sequence to be
|
||||
reordered (might be caused by loss of more than 300 packets in a row)
|
||||
.TP
|
||||
.B rx buffered
|
||||
the number of packets which were slightly ahead of sequence, and were
|
||||
either buffered for reordering, or if buffering is disabled, accepted
|
||||
immediately (resulting in the intermediate packets being discarded).
|
||||
.TP
|
||||
.B rx OS errors
|
||||
the number of times where the operating system reported an error when
|
||||
we tried to read a packet
|
||||
.TP
|
||||
.B rx truncated
|
||||
the number of times we received a packet which was shorter than the
|
||||
length implied by the GRE header
|
||||
.TP
|
||||
.B rx invalid
|
||||
the number of times we received a packet which had invalid or unsupported
|
||||
flags set in the header, wrong version, or wrong protocol.
|
||||
.TP
|
||||
.B rx acks
|
||||
the number of pure acknowledgements received (without data). Too many
|
||||
of these will waste bandwidth, and might be solved by tuning the remote host.
|
||||
.TP
|
||||
.B tx sent
|
||||
the number of GRE packets sent with data
|
||||
.TP
|
||||
.B tx failed
|
||||
the number of packets we tried to send, but the OS reported an error
|
||||
.TP
|
||||
.B tx short
|
||||
the number of times the OS would not let us write a complete packet
|
||||
.TP
|
||||
.B tx acks
|
||||
the number of times we sent a pure ack, without data
|
||||
.TP
|
||||
.B tx oversize
|
||||
the number of times we couldn't send a packet because it was over
|
||||
PACKET_MAX bytes long
|
||||
.TP
|
||||
.B round trip
|
||||
the estimated round-trip time in milliseconds
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.IR pppd (8)
|
||||
.PP
|
||||
Documentation in
|
||||
.IR /usr/share/doc/pptp
|
||||
.SH AUTHOR
|
||||
This manual page was written by James Cameron
|
||||
<james.cameron@hp.com> from text contributed by Thomas Quinot
|
||||
<thomas@debian.org>, for the Debian GNU/Linux system.
|
||||
The description of the available statistics was written by Chris Wilson
|
||||
<chris@netservers.co.uk>. Updates for the Debian distribution by
|
||||
Ola Lundqvist <opal@debian.org>.
|
|
@ -0,0 +1,614 @@
|
|||
/*
|
||||
an implementation of the PPTP protocol
|
||||
Copyright (C) 2000 Free Software Foundation
|
||||
|
||||
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.
|
||||
|
||||
pptp.c ... client shell to launch call managers, data handlers, and
|
||||
the pppd from the command line.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#if defined(__FreeBSD__)
|
||||
#include <libutil.h>
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#include <util.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <util.h>
|
||||
#elif defined (__SVR4) && defined (__sun)
|
||||
#else
|
||||
#include <pty.h>
|
||||
#endif
|
||||
#ifdef USER_PPP
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/un.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/param.h>
|
||||
#if defined(__APPLE__)
|
||||
#include "getopt.h"
|
||||
#else
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include "config.h"
|
||||
#include "pptp_callmgr.h"
|
||||
#include "pptp_gre.h"
|
||||
#include "version.h"
|
||||
#if defined(__linux__)
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
#include "util.h"
|
||||
#include "pptp_quirks.h"
|
||||
#include "pqueue.h"
|
||||
#include "pptp_options.h"
|
||||
#include "pptp_compat.h"
|
||||
|
||||
#ifndef PPPD_BINARY
|
||||
#define PPPD_BINARY "pppd"
|
||||
#endif
|
||||
|
||||
int syncppp = 0;
|
||||
int log_level = 1;
|
||||
int disable_buffer = 0;
|
||||
int test_type = 0;
|
||||
int test_rate = 100;
|
||||
int missing_window = MISSING_WINDOW;
|
||||
|
||||
struct in_addr get_ip_address(char *name);
|
||||
int open_callmgr(struct in_addr inetaddr, char *phonenr, int argc,char **argv,char **envp, int pty_fd, int gre_fd);
|
||||
void launch_callmgr(struct in_addr inetaddr, char *phonenr, int argc,char **argv,char **envp);
|
||||
int get_call_id(int sock, pid_t gre, pid_t pppd,
|
||||
u_int16_t *call_id, u_int16_t *peer_call_id);
|
||||
void launch_pppd(char *ttydev, int argc, char **argv);
|
||||
|
||||
/*** print usage and exit *****************************************************/
|
||||
void usage(char *progname)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s\n"
|
||||
|
||||
"Copyright (C) 2000 Free Software Foundation\n\n"
|
||||
|
||||
"This program comes with ABSOLUTELY NO WARRANTY; for details see source.\n"
|
||||
"This is free software, and you are welcome to redistribute it under certain\n"
|
||||
"conditions; see source for details.\n\n"
|
||||
|
||||
"Usage:\n"
|
||||
" %s <hostname> [<pptp options>] [[--] <pppd options>]\n"
|
||||
"\n"
|
||||
"Or using pppd's pty option: \n"
|
||||
" pppd pty \"%s <hostname> --nolaunchpppd <pptp options>\"\n"
|
||||
"\n"
|
||||
"Available pptp options:\n"
|
||||
" --version Display version number and exit\n"
|
||||
" --phone <number> Pass <number> to remote host as phone number\n"
|
||||
" --nolaunchpppd Do not launch pppd, for use as a pppd pty\n"
|
||||
" --quirks <quirk> Work around a buggy PPTP implementation\n"
|
||||
" Currently recognised values are BEZEQ_ISRAEL only\n"
|
||||
" --debug Run in foreground (for debugging with gdb)\n"
|
||||
" --sync Enable Synchronous HDLC (pppd must use it too)\n"
|
||||
" --timeout <secs> Time to wait for reordered packets (0.01 to 10 secs)\n"
|
||||
" --nobuffer Disable packet buffering and reordering completely\n"
|
||||
" --idle-wait Time to wait before sending echo request\n"
|
||||
" --max-echo-wait Time to wait before giving up on lack of reply\n"
|
||||
" --logstring <name> Use <name> instead of 'anon' in syslog messages\n"
|
||||
" --localbind <addr> Bind to specified IP address instead of wildcard\n"
|
||||
#ifdef SO_MARK
|
||||
" --rtmark <n> Use specified policy routing mark for all packets\n"
|
||||
#endif
|
||||
" --nohostroute Do not add host route towards <hostname>\n"
|
||||
" --loglevel <level> Sets the debugging level (0=low, 1=default, 2=high)\n"
|
||||
" --test-type <type> Damage the packet stream by reordering\n"
|
||||
" --test-rate <n> Do the test every n packets\n"
|
||||
" --missing-window <n> Enable 'missing window' validation and set packet\n"
|
||||
" polerance (300=default, 6000=recommended)\n",
|
||||
|
||||
version, progname, progname);
|
||||
log("%s called with wrong arguments, program not started.", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if defined (__SVR4) && defined (__sun)
|
||||
struct in_addr localbind = { .s_addr = INADDR_ANY };
|
||||
#else
|
||||
struct in_addr localbind = { INADDR_NONE };
|
||||
#endif
|
||||
int rtmark = 0;
|
||||
int nohostroute = 0;
|
||||
static int signaled = 0;
|
||||
|
||||
/*** do nothing signal handler ************************************************/
|
||||
void do_nothing(int sig)
|
||||
{
|
||||
/* do nothing signal handler. Better than SIG_IGN. */
|
||||
signaled = sig;
|
||||
}
|
||||
|
||||
sigjmp_buf env;
|
||||
|
||||
/*** signal handler ***********************************************************/
|
||||
void sighandler(int sig __attribute__ ((unused)))
|
||||
{
|
||||
siglongjmp(env, 1);
|
||||
}
|
||||
|
||||
/*** report statistics signal handler (SIGUSR1) *******************************/
|
||||
void sigstats(int sig __attribute__ ((unused)))
|
||||
{
|
||||
syslog(LOG_NOTICE, "GRE statistics:\n");
|
||||
#define LOG(name,value) syslog(LOG_NOTICE, name "\n", stats .value)
|
||||
LOG("rx accepted = %d", rx_accepted);
|
||||
LOG("rx lost = %d", rx_lost);
|
||||
LOG("rx under win = %d", rx_underwin);
|
||||
LOG("rx over win = %d", rx_overwin);
|
||||
LOG("rx buffered = %d", rx_buffered);
|
||||
LOG("rx OS errors = %d", rx_errors);
|
||||
LOG("rx truncated = %d", rx_truncated);
|
||||
LOG("rx invalid = %d", rx_invalid);
|
||||
LOG("rx acks = %d", rx_acks);
|
||||
LOG("tx sent = %d", tx_sent);
|
||||
LOG("tx failed = %d", tx_failed);
|
||||
LOG("tx short = %d", tx_short);
|
||||
LOG("tx acks = %d", tx_acks);
|
||||
LOG("tx oversize = %d", tx_oversize);
|
||||
LOG("round trip = %d usecs", rtt);
|
||||
#undef LOG
|
||||
}
|
||||
|
||||
/*** main *********************************************************************/
|
||||
/* TODO: redesign to avoid longjmp/setjmp. Several variables here
|
||||
have a volatile qualifier to silence warnings from gcc < 3.0.
|
||||
Remove the volatile qualifiers if longjmp/setjmp are removed.
|
||||
*/
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
struct in_addr inetaddr;
|
||||
volatile int callmgr_sock = -1;
|
||||
char ttydev[PATH_MAX];
|
||||
char *pty_name;
|
||||
int pty_fd, tty_fd, gre_fd, rc;
|
||||
volatile pid_t parent_pid, child_pid;
|
||||
u_int16_t call_id, peer_call_id;
|
||||
char buf[128];
|
||||
int pppdargc;
|
||||
char **pppdargv;
|
||||
char phonenrbuf[65]; /* maximum length of field plus one for the trailing
|
||||
* '\0' */
|
||||
char * volatile phonenr = NULL;
|
||||
volatile int launchpppd = 1, debug = 0;
|
||||
|
||||
while(1){
|
||||
/* structure with all recognised options for pptp */
|
||||
static struct option long_options[] = {
|
||||
{"phone", 1, 0, 0},
|
||||
{"nolaunchpppd", 0, 0, 0},
|
||||
{"quirks", 1, 0, 0},
|
||||
{"debug", 0, 0, 0},
|
||||
{"sync", 0, 0, 0},
|
||||
{"timeout", 1, 0, 0},
|
||||
{"logstring", 1, 0, 0},
|
||||
{"localbind", 1, 0, 0},
|
||||
{"loglevel", 1, 0, 0},
|
||||
{"nobuffer", 0, 0, 0},
|
||||
{"idle-wait", 1, 0, 0},
|
||||
{"max-echo-wait", 1, 0, 0},
|
||||
{"version", 0, 0, 0},
|
||||
{"test-type", 1, 0, 0},
|
||||
{"test-rate", 1, 0, 0},
|
||||
{"rtmark", 1, 0, 0},
|
||||
{"nohostroute", 0, 0, 0},
|
||||
{"missing-window", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
int option_index = 0;
|
||||
int c;
|
||||
c = getopt_long (argc, argv, "", long_options, &option_index);
|
||||
if (c == -1) break; /* no more options */
|
||||
switch (c) {
|
||||
case 0:
|
||||
if (option_index == 0) { /* --phone specified */
|
||||
strncpy(phonenrbuf,optarg,sizeof(phonenrbuf));
|
||||
phonenrbuf[sizeof(phonenrbuf) - 1] = '\0';
|
||||
phonenr = phonenrbuf;
|
||||
} else if (option_index == 1) {/* --nolaunchpppd specified */
|
||||
launchpppd = 0;
|
||||
} else if (option_index == 2) {/* --quirks specified */
|
||||
if (set_quirk_index(find_quirk(optarg)))
|
||||
usage(argv[0]);
|
||||
} else if (option_index == 3) {/* --debug */
|
||||
debug = 1;
|
||||
} else if (option_index == 4) {/* --sync specified */
|
||||
syncppp = 1;
|
||||
} else if (option_index == 5) {/* --timeout */
|
||||
float new_packet_timeout = atof(optarg);
|
||||
if (new_packet_timeout < 0.0099 ||
|
||||
new_packet_timeout > 10) {
|
||||
fprintf(stderr, "Packet timeout %s (%f) out of range: "
|
||||
"should be between 0.01 and 10 seconds\n",
|
||||
optarg, new_packet_timeout);
|
||||
log("Packet timeout %s (%f) out of range: should be"
|
||||
"between 0.01 and 10 seconds", optarg,
|
||||
new_packet_timeout);
|
||||
exit(2);
|
||||
} else {
|
||||
packet_timeout_usecs = new_packet_timeout * 1000000;
|
||||
}
|
||||
} else if (option_index == 6) {/* --logstring */
|
||||
log_string = strdup(optarg);
|
||||
} else if (option_index == 7) {/* --localbind */
|
||||
if (inet_pton(AF_INET, optarg, (void *) &localbind) < 1) {
|
||||
fprintf(stderr, "Local bind address %s invalid\n",
|
||||
optarg);
|
||||
log("Local bind address %s invalid\n", optarg);
|
||||
exit(2);
|
||||
}
|
||||
} else if (option_index == 8) { /* --loglevel */
|
||||
log_level = atoi(optarg);
|
||||
if (log_level < 0 || log_level > 2)
|
||||
usage(argv[0]);
|
||||
} else if (option_index == 9) { /* --nobuffer */
|
||||
disable_buffer = 1;
|
||||
} else if (option_index == 10) { /* --idle-wait */
|
||||
int x = atoi(optarg);
|
||||
if (x < 0) {
|
||||
fprintf(stderr, "--idle-wait must not be negative\n");
|
||||
log("--idle-wait must not be negative\n");
|
||||
exit(2);
|
||||
} else {
|
||||
idle_wait = x;
|
||||
}
|
||||
} else if (option_index == 11) { /* --max-echo-wait */
|
||||
int x = atoi(optarg);
|
||||
if (x < 0) {
|
||||
fprintf(stderr, "--max-echo-wait must not be negative\n");
|
||||
log("--max-echo-wait must not be negative\n");
|
||||
exit(2);
|
||||
} else {
|
||||
max_echo_wait = x;
|
||||
}
|
||||
fprintf(stderr, "--max-echo-wait ignored, not yet implemented\n");
|
||||
} else if (option_index == 12) { /* --version */
|
||||
fprintf(stdout, "%s\n", version);
|
||||
exit(0);
|
||||
} else if (option_index == 13) { /* --test-type */
|
||||
test_type = atoi(optarg);
|
||||
} else if (option_index == 14) { /* --test-rate */
|
||||
test_rate = atoi(optarg);
|
||||
} else if (option_index == 15) { /* --rtmark */
|
||||
#ifdef SO_MARK
|
||||
rtmark = atoi(optarg);
|
||||
#else
|
||||
fprintf(stderr, "--rtmark support was missing when "
|
||||
"this binary was compiled.\n");
|
||||
exit(2);
|
||||
#endif
|
||||
} else if (option_index == 16) { /* --nohostroute */
|
||||
nohostroute = 1;
|
||||
} else if (option_index == 17) { /* --missing window */
|
||||
int x = atoi(optarg);
|
||||
if (x <= 0) {
|
||||
fprintf(stderr, "--missing-window must be integer "
|
||||
"greater than zero\n");
|
||||
log("--missing-window must be integer "
|
||||
"greater than zero\n");
|
||||
exit(2);
|
||||
} else if (x < 300) {
|
||||
fprintf(stderr, "--missing-window is set very low: "
|
||||
"default=300, recommended=6000 - proceeding");
|
||||
log("--missing-window is set very low: "
|
||||
"default=300, recommended=6000 - proceeding\n");
|
||||
} else {
|
||||
fprintf(stderr, "--missing-window validation is active "
|
||||
"and set to: %d\n", x);
|
||||
log("--missing-window validation is active "
|
||||
"and set to: %d\n", x);
|
||||
missing_window = x;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '?': /* unrecognised option */
|
||||
/* fall through */
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* at least one argument is required */
|
||||
if (argc <= optind)
|
||||
usage(argv[0]);
|
||||
|
||||
/* Get IP address for the hostname in argv[1] */
|
||||
inetaddr = get_ip_address(argv[optind]);
|
||||
optind++;
|
||||
|
||||
/* Find the ppp options, extract phone number */
|
||||
pppdargc = argc - optind;
|
||||
pppdargv = argv + optind;
|
||||
log("The synchronous pptp option is %sactivated\n", syncppp ? "" : "NOT ");
|
||||
|
||||
/* Now we have the peer address, bind the GRE socket early,
|
||||
before starting pppd. This prevents the ICMP Unreachable bug
|
||||
documented in <1026868263.2855.67.camel@jander> */
|
||||
gre_fd = pptp_gre_bind(inetaddr);
|
||||
if (gre_fd < 0) {
|
||||
fatal("Cannot bind GRE socket, aborting.");
|
||||
}
|
||||
|
||||
/* Find an open pty/tty pair. */
|
||||
if(launchpppd){
|
||||
rc = openpty (&pty_fd, &tty_fd, ttydev, NULL, NULL);
|
||||
if (rc < 0) {
|
||||
fatal("Could not find free pty.");
|
||||
}
|
||||
|
||||
/* fork and wait. */
|
||||
signal(SIGUSR1, do_nothing); /* don't die */
|
||||
signal(SIGCHLD, do_nothing); /* don't ignore SIGCHLD */
|
||||
parent_pid = getpid();
|
||||
switch (child_pid = fork()) {
|
||||
case -1:
|
||||
fatal("Could not fork pppd process");
|
||||
case 0: /* I'm the child! */
|
||||
close (tty_fd);
|
||||
signal(SIGUSR1, SIG_DFL);
|
||||
child_pid = getpid();
|
||||
break;
|
||||
default: /* parent */
|
||||
close (pty_fd);
|
||||
/*
|
||||
* There is still a very small race condition here. If a signal
|
||||
* occurs after signaled is checked but before pause is called,
|
||||
* things will hang.
|
||||
*/
|
||||
if (!signaled) {
|
||||
pause(); /* wait for the signal */
|
||||
}
|
||||
|
||||
if (signaled == SIGCHLD)
|
||||
fatal("Child process died");
|
||||
|
||||
launch_pppd(ttydev, pppdargc, pppdargv); /* launch pppd */
|
||||
perror("Error");
|
||||
fatal("Could not launch pppd");
|
||||
}
|
||||
} else { /* ! launchpppd */
|
||||
pty_fd = tty_fd = STDIN_FILENO;
|
||||
/* close unused file descriptor, that is redirected to the pty */
|
||||
close(STDOUT_FILENO);
|
||||
child_pid = getpid();
|
||||
parent_pid = 0; /* don't kill pppd */
|
||||
}
|
||||
|
||||
do {
|
||||
/*
|
||||
* Open connection to call manager (Launch call manager if necessary.)
|
||||
*/
|
||||
callmgr_sock = open_callmgr(inetaddr, phonenr, argc, argv, envp,
|
||||
pty_fd, gre_fd);
|
||||
/* Exchange PIDs, get call ID */
|
||||
} while (get_call_id(callmgr_sock, parent_pid, child_pid,
|
||||
&call_id, &peer_call_id) < 0);
|
||||
|
||||
/* Send signal to wake up pppd task */
|
||||
if (launchpppd) {
|
||||
kill(parent_pid, SIGUSR1);
|
||||
sleep(2);
|
||||
/* become a daemon */
|
||||
if (!debug && daemon(0, 0) != 0) {
|
||||
perror("daemon");
|
||||
}
|
||||
} else {
|
||||
/* re-open stderr as /dev/null to release it */
|
||||
file2fd("/dev/null", "wb", STDERR_FILENO);
|
||||
}
|
||||
|
||||
pty_name = ttyname(pty_fd);
|
||||
snprintf(buf, sizeof(buf), "pptp: GRE-to-PPP gateway on %s",
|
||||
pty_name ? pty_name : "(null)");
|
||||
#ifdef PR_SET_NAME
|
||||
rc = prctl(PR_SET_NAME, "pptpgw", 0, 0, 0);
|
||||
if (rc != 0) perror("prctl");
|
||||
#endif
|
||||
if (sigsetjmp(env, 1)!= 0) goto shutdown;
|
||||
|
||||
signal(SIGINT, sighandler);
|
||||
signal(SIGTERM, sighandler);
|
||||
signal(SIGKILL, sighandler);
|
||||
signal(SIGCHLD, sighandler);
|
||||
signal(SIGUSR1, sigstats);
|
||||
|
||||
/* Do GRE copy until close. */
|
||||
pptp_gre_copy(call_id, peer_call_id, pty_fd, gre_fd);
|
||||
|
||||
shutdown:
|
||||
/* on close, kill all. */
|
||||
if(launchpppd)
|
||||
kill(parent_pid, SIGTERM);
|
||||
close(pty_fd);
|
||||
close(callmgr_sock);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*** get the ipaddress coming from the command line ***************************/
|
||||
struct in_addr get_ip_address(char *name)
|
||||
{
|
||||
int rc;
|
||||
struct in_addr retval;
|
||||
struct addrinfo hints, *ai;
|
||||
|
||||
memset(&hints, '\0', sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
hints.ai_flags = AI_ADDRCONFIG; /* Unknown in OpenBSD. */
|
||||
#endif
|
||||
|
||||
if ( (rc = getaddrinfo(name, NULL, &hints, &ai)) )
|
||||
fatal("getaddrinfo(): %s", gai_strerror(rc));
|
||||
|
||||
if (ai->ai_addr->sa_family != AF_INET) /* Should never happen. */
|
||||
fatal("Host '%s' possesses no IPv4 address", name);
|
||||
|
||||
memcpy(&retval.s_addr,
|
||||
&(((struct sockaddr_in *) ai->ai_addr)->sin_addr.s_addr),
|
||||
sizeof(retval.s_addr));
|
||||
freeaddrinfo(ai);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*** start the call manager ***************************************************/
|
||||
int open_callmgr(struct in_addr inetaddr, char *phonenr, int argc, char **argv,
|
||||
char **envp, int pty_fd, int gre_fd)
|
||||
{
|
||||
/* Try to open unix domain socket to call manager. */
|
||||
union {
|
||||
struct sockaddr a;
|
||||
struct sockaddr_un u;
|
||||
} where;
|
||||
const int NUM_TRIES = 3;
|
||||
int i, fd;
|
||||
pid_t pid;
|
||||
int status;
|
||||
/* Open socket */
|
||||
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
fatal("Could not create unix domain socket: %s", strerror(errno));
|
||||
}
|
||||
/* Make address */
|
||||
callmgr_name_unixsock(&where.u, inetaddr, localbind);
|
||||
for (i = 0; i < NUM_TRIES; i++) {
|
||||
if (connect(fd, &where.a, sizeof(where)) < 0) {
|
||||
/* couldn't connect. We'll have to launch this guy. */
|
||||
|
||||
unlink (where.u.sun_path); /* FIXME: potential race condition */
|
||||
|
||||
/* fork and launch call manager process */
|
||||
switch (pid = fork()) {
|
||||
case -1: /* failure */
|
||||
fatal("fork() to launch call manager failed.");
|
||||
case 0: /* child */
|
||||
{
|
||||
close (fd);
|
||||
/* close the pty and gre in the call manager */
|
||||
close(pty_fd);
|
||||
close(gre_fd);
|
||||
launch_callmgr(inetaddr, phonenr, argc, argv, envp);
|
||||
}
|
||||
default: /* parent */
|
||||
waitpid(pid, &status, 0);
|
||||
if (WEXITSTATUS(status) != 0)
|
||||
fatal("Call manager exited with error %d", status);
|
||||
break;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
else return fd;
|
||||
}
|
||||
close(fd);
|
||||
fatal("Could not launch call manager after %d tries.", i);
|
||||
return -1; /* make gcc happy */
|
||||
}
|
||||
|
||||
/*** call the call manager main ***********************************************/
|
||||
void launch_callmgr(struct in_addr inetaddr, char *phonenr, int argc __attribute__ ((unused)),
|
||||
char**argv,char**envp)
|
||||
{
|
||||
char *my_argv[3] = { argv[0], inet_ntoa(inetaddr), phonenr };
|
||||
char buf[128];
|
||||
snprintf(buf, sizeof(buf), "pptp: call manager for %s", my_argv[1]);
|
||||
#ifdef PR_SET_NAME
|
||||
int rc;
|
||||
rc = prctl(PR_SET_NAME, "pptpcm", 0, 0, 0);
|
||||
if (rc != 0) perror("prctl");
|
||||
#endif
|
||||
exit(callmgr_main(3, my_argv, envp));
|
||||
}
|
||||
|
||||
/*** exchange data with the call manager *************************************/
|
||||
/* XXX need better error checking XXX */
|
||||
int get_call_id(int sock, pid_t gre, pid_t pppd,
|
||||
u_int16_t *call_id, u_int16_t *peer_call_id)
|
||||
{
|
||||
u_int16_t m_call_id, m_peer_call_id;
|
||||
/* write pid's to socket */
|
||||
/* don't bother with network byte order, because pid's are meaningless
|
||||
* outside the local host.
|
||||
*/
|
||||
int rc;
|
||||
rc = write(sock, &gre, sizeof(gre));
|
||||
if (rc != sizeof(gre))
|
||||
return -1;
|
||||
rc = write(sock, &pppd, sizeof(pppd));
|
||||
if (rc != sizeof(pppd))
|
||||
return -1;
|
||||
rc = read(sock, &m_call_id, sizeof(m_call_id));
|
||||
if (rc != sizeof(m_call_id))
|
||||
return -1;
|
||||
rc = read(sock, &m_peer_call_id, sizeof(m_peer_call_id));
|
||||
if (rc != sizeof(m_peer_call_id))
|
||||
return -1;
|
||||
/*
|
||||
* XXX FIXME ... DO ERROR CHECKING & TIME-OUTS XXX
|
||||
* (Rhialto: I am assuming for now that timeouts are not relevant
|
||||
* here, because the read and write calls would return -1 (fail) when
|
||||
* the peer goes away during the process. We know it is (or was)
|
||||
* running because the connect() call succeeded.)
|
||||
* (James: on the other hand, if the route to the peer goes away, we
|
||||
* wouldn't get told by read() or write() for quite some time.)
|
||||
*/
|
||||
*call_id = m_call_id;
|
||||
*peer_call_id = m_peer_call_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** execvp pppd **************************************************************/
|
||||
void launch_pppd(char *ttydev, int argc, char **argv)
|
||||
{
|
||||
char *new_argv[argc + 4];/* XXX if not using GCC, hard code a limit here. */
|
||||
char str_pppd[] = PPPD_BINARY;
|
||||
char str_direct[] __attribute__ ((unused)) = "-direct";
|
||||
char str_38400[] = "38400";
|
||||
int i = 0, j;
|
||||
new_argv[i++] = str_pppd;
|
||||
#ifdef USER_PPP
|
||||
new_argv[i++] = str_direct;
|
||||
/* ppp expects to have stdin connected to ttydev */
|
||||
if ((j = open(ttydev, O_RDWR)) == -1)
|
||||
fatal("Cannot open %s: %s", ttydev, strerror(errno));
|
||||
if (dup2(j, 0) == -1)
|
||||
fatal("dup2 failed: %s", strerror(errno));
|
||||
close(j);
|
||||
#else
|
||||
new_argv[i++] = ttydev;
|
||||
new_argv[i++] = str_38400;
|
||||
#endif
|
||||
for (j = 0; j < argc; j++)
|
||||
new_argv[i++] = argv[j];
|
||||
new_argv[i] = NULL;
|
||||
execvp(new_argv[0], new_argv);
|
||||
}
|
|
@ -0,0 +1,416 @@
|
|||
/* pptp_callmgr.c ... Call manager for PPTP connections.
|
||||
* Handles TCP port 1723 protocol.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: pptp_callmgr.c,v 1.27 2011/12/19 07:18:09 quozl Exp $
|
||||
*/
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if defined (__SVR4) && defined (__sun)
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "pptp_callmgr.h"
|
||||
#include "pptp_ctrl.h"
|
||||
#include "pptp_msg.h"
|
||||
#include "dirutil.h"
|
||||
#include "vector.h"
|
||||
#include "util.h"
|
||||
#include "routing.h"
|
||||
|
||||
extern struct in_addr localbind; /* from pptp.c */
|
||||
extern int rtmark;
|
||||
extern int nohostroute;
|
||||
|
||||
int open_inetsock(struct in_addr inetaddr);
|
||||
int open_unixsock(struct in_addr inetaddr);
|
||||
void close_inetsock(int fd, struct in_addr inetaddr);
|
||||
void close_unixsock(int fd, struct in_addr inetaddr);
|
||||
|
||||
sigjmp_buf callmgr_env;
|
||||
|
||||
void callmgr_sighandler(int sig __attribute__ ((unused))) {
|
||||
/* TODO: according to signal(2), siglongjmp() is unsafe used here */
|
||||
siglongjmp (callmgr_env, 1);
|
||||
}
|
||||
|
||||
void callmgr_do_nothing(int sig __attribute__ ((unused))) {
|
||||
/* do nothing signal handler */
|
||||
}
|
||||
|
||||
struct local_callinfo {
|
||||
int unix_sock;
|
||||
pid_t pid[2];
|
||||
};
|
||||
|
||||
struct local_conninfo {
|
||||
VECTOR * call_list;
|
||||
fd_set * call_set;
|
||||
};
|
||||
|
||||
/* Call callback */
|
||||
void call_callback(PPTP_CONN *conn, PPTP_CALL *call, enum call_state state)
|
||||
{
|
||||
struct local_callinfo *lci;
|
||||
struct local_conninfo *conninfo;
|
||||
u_int16_t call_id[2];
|
||||
switch(state) {
|
||||
case CALL_OPEN_DONE:
|
||||
/* okey dokey. This means that the call_id and peer_call_id are
|
||||
* now valid, so lets send them on to our friends who requested
|
||||
* this call. */
|
||||
lci = pptp_call_closure_get(conn, call); assert(lci != NULL);
|
||||
pptp_call_get_ids(conn, call, &call_id[0], &call_id[1]);
|
||||
write(lci->unix_sock, &call_id, sizeof(call_id));
|
||||
/* Our duty to the fatherland is now complete. */
|
||||
break;
|
||||
case CALL_OPEN_FAIL:
|
||||
case CALL_CLOSE_RQST:
|
||||
case CALL_CLOSE_DONE:
|
||||
/* don't need to do anything here, except make sure tables
|
||||
* are sync'ed */
|
||||
log("Closing connection (call state)");
|
||||
conninfo = pptp_conn_closure_get(conn);
|
||||
lci = pptp_call_closure_get(conn, call);
|
||||
assert(lci != NULL && conninfo != NULL);
|
||||
if (vector_contains(conninfo->call_list, lci->unix_sock)) {
|
||||
vector_remove(conninfo->call_list, lci->unix_sock);
|
||||
close(lci->unix_sock);
|
||||
FD_CLR(lci->unix_sock, conninfo->call_set);
|
||||
if(lci->pid[0] > 1) kill(lci->pid[0], SIGTERM);
|
||||
if(lci->pid[1] > 1) kill(lci->pid[1], SIGTERM);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
log("Unhandled call callback state [%d].", (int) state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NOTE ABOUT 'VOLATILE':
|
||||
* several variables here get a volatile qualifier to silence warnings
|
||||
* from older (before 3.0) gccs. if the longjmp stuff is removed,
|
||||
* the volatile qualifiers should be removed as well.
|
||||
*****************************************************************************/
|
||||
|
||||
/*** Call Manager *************************************************************/
|
||||
int callmgr_main(int argc, char **argv, char **envp __attribute__ ((unused)))
|
||||
{
|
||||
struct in_addr inetaddr;
|
||||
int inet_sock, unix_sock;
|
||||
fd_set call_set;
|
||||
PPTP_CONN * conn;
|
||||
VECTOR * call_list;
|
||||
int max_fd = 0;
|
||||
volatile int first = 1;
|
||||
int retval;
|
||||
int i;
|
||||
char * volatile phonenr;
|
||||
/* Step 0: Check arguments */
|
||||
if (argc < 2)
|
||||
fatal("Usage: %s ip.add.ress.here [--phone <phone number>]", argv[0]);
|
||||
phonenr = argc == 3 ? argv[2] : NULL;
|
||||
if (inet_aton(argv[1], &inetaddr) == 0)
|
||||
fatal("Invalid IP address: %s", argv[1]);
|
||||
if (!nohostroute) {
|
||||
routing_init(inet_ntoa(inetaddr));
|
||||
routing_start();
|
||||
}
|
||||
/* Step 1: Open sockets. */
|
||||
if ((inet_sock = open_inetsock(inetaddr)) < 0)
|
||||
fatal("Could not open control connection to %s", argv[1]);
|
||||
if ((unix_sock = open_unixsock(inetaddr)) < 0)
|
||||
fatal("Could not open unix socket for %s", argv[1]);
|
||||
/* Step 1b: FORK and return status to calling process. */
|
||||
switch (fork()) {
|
||||
case 0: /* child. stick around. */
|
||||
break;
|
||||
case -1: /* failure. Fatal. */
|
||||
fatal("Could not fork.");
|
||||
default: /* Parent. Return status to caller. */
|
||||
exit(0);
|
||||
}
|
||||
/* re-open stderr as /dev/null to release it */
|
||||
file2fd("/dev/null", "wb", STDERR_FILENO);
|
||||
/* Step 1c: Clean up unix socket on TERM */
|
||||
if (sigsetjmp(callmgr_env, 1) != 0)
|
||||
goto cleanup;
|
||||
signal(SIGINT, callmgr_sighandler);
|
||||
signal(SIGTERM, callmgr_sighandler);
|
||||
signal(SIGPIPE, callmgr_do_nothing);
|
||||
signal(SIGUSR1, callmgr_do_nothing); /* signal state change
|
||||
wake up accept */
|
||||
/* Step 2: Open control connection and register callback */
|
||||
if ((conn = pptp_conn_open(inet_sock, 1, NULL/* callback */)) == NULL) {
|
||||
close(unix_sock); close(inet_sock); fatal("Could not open connection.");
|
||||
}
|
||||
FD_ZERO(&call_set);
|
||||
call_list = vector_create();
|
||||
{
|
||||
struct local_conninfo *conninfo = malloc(sizeof(*conninfo));
|
||||
if (conninfo == NULL) {
|
||||
close(unix_sock); close(inet_sock); fatal("No memory.");
|
||||
}
|
||||
conninfo->call_list = call_list;
|
||||
conninfo->call_set = &call_set;
|
||||
pptp_conn_closure_put(conn, conninfo);
|
||||
}
|
||||
if (sigsetjmp(callmgr_env, 1) != 0) goto shutdown;
|
||||
/* Step 3: Get FD_SETs */
|
||||
max_fd = unix_sock;
|
||||
do {
|
||||
int rc;
|
||||
fd_set read_set = call_set, write_set;
|
||||
if (pptp_conn_is_dead(conn)) break;
|
||||
FD_ZERO (&write_set);
|
||||
if (pptp_conn_established(conn)) {
|
||||
FD_SET (unix_sock, &read_set);
|
||||
if (unix_sock > max_fd) max_fd = unix_sock;
|
||||
}
|
||||
pptp_fd_set(conn, &read_set, &write_set, &max_fd);
|
||||
for (; max_fd > 0 ; max_fd--) {
|
||||
if (FD_ISSET (max_fd, &read_set) ||
|
||||
FD_ISSET (max_fd, &write_set))
|
||||
break;
|
||||
}
|
||||
/* Step 4: Wait on INET or UNIX event */
|
||||
if ((rc = select(max_fd + 1, &read_set, &write_set, NULL, NULL)) <0) {
|
||||
if (errno == EBADF) break;
|
||||
/* a signal or somesuch. */
|
||||
continue;
|
||||
}
|
||||
/* Step 5a: Handle INET events */
|
||||
rc = pptp_dispatch(conn, &read_set, &write_set);
|
||||
if (rc < 0)
|
||||
break;
|
||||
/* Step 5b: Handle new connection to UNIX socket */
|
||||
if (FD_ISSET(unix_sock, &read_set)) {
|
||||
/* New call! */
|
||||
union {
|
||||
struct sockaddr a;
|
||||
struct sockaddr_un u;
|
||||
} from;
|
||||
socklen_t len = sizeof(from.u);
|
||||
PPTP_CALL * call;
|
||||
struct local_callinfo *lci;
|
||||
int s;
|
||||
/* Accept the socket */
|
||||
FD_CLR (unix_sock, &read_set);
|
||||
if ((s = accept(unix_sock, &from.a, &len)) < 0) {
|
||||
warn("Socket not accepted: %s", strerror(errno));
|
||||
goto skip_accept;
|
||||
}
|
||||
/* Allocate memory for local call information structure. */
|
||||
if ((lci = malloc(sizeof(*lci))) == NULL) {
|
||||
warn("Out of memory."); close(s); goto skip_accept;
|
||||
}
|
||||
lci->unix_sock = s;
|
||||
/* Give the initiator time to write the PIDs while we open
|
||||
* the call */
|
||||
call = pptp_call_open(conn, call_callback, phonenr);
|
||||
/* Read and store the associated pids */
|
||||
read(s, &lci->pid[0], sizeof(lci->pid[0]));
|
||||
read(s, &lci->pid[1], sizeof(lci->pid[1]));
|
||||
/* associate the local information with the call */
|
||||
pptp_call_closure_put(conn, call, (void *) lci);
|
||||
/* The rest is done on callback. */
|
||||
/* Keep alive; wait for close */
|
||||
retval = vector_insert(call_list, s, call); assert(retval);
|
||||
if (s > max_fd) max_fd = s;
|
||||
FD_SET(s, &call_set);
|
||||
first = 0;
|
||||
}
|
||||
skip_accept: /* Step 5c: Handle socket close */
|
||||
for (i = 0; i < max_fd + 1; i++)
|
||||
if (FD_ISSET(i, &read_set)) {
|
||||
/* close it */
|
||||
PPTP_CALL * call;
|
||||
retval = vector_search(call_list, i, &call);
|
||||
if (retval) {
|
||||
struct local_callinfo *lci =
|
||||
pptp_call_closure_get(conn, call);
|
||||
log("Closing connection (unhandled)");
|
||||
if(lci->pid[0] > 1) kill(lci->pid[0], SIGTERM);
|
||||
if(lci->pid[1] > 1) kill(lci->pid[1], SIGTERM);
|
||||
free(lci);
|
||||
/* soft shutdown. Callback will do hard shutdown later */
|
||||
pptp_call_close(conn, call);
|
||||
vector_remove(call_list, i);
|
||||
}
|
||||
FD_CLR(i, &call_set);
|
||||
close(i);
|
||||
}
|
||||
} while (vector_size(call_list) > 0 || first);
|
||||
shutdown:
|
||||
{
|
||||
int rc;
|
||||
fd_set read_set, write_set;
|
||||
struct timeval tv;
|
||||
signal(SIGINT, callmgr_do_nothing);
|
||||
signal(SIGTERM, callmgr_do_nothing);
|
||||
/* warn("Shutdown"); */
|
||||
/* kill all open calls */
|
||||
for (i = 0; i < vector_size(call_list); i++) {
|
||||
PPTP_CALL *call = vector_get_Nth(call_list, i);
|
||||
struct local_callinfo *lci = pptp_call_closure_get(conn, call);
|
||||
log("Closing connection (shutdown)");
|
||||
pptp_call_close(conn, call);
|
||||
if(lci->pid[0] > 1) kill(lci->pid[0], SIGTERM);
|
||||
if(lci->pid[1] > 1) kill(lci->pid[1], SIGTERM);
|
||||
}
|
||||
/* attempt to dispatch these messages */
|
||||
FD_ZERO(&read_set);
|
||||
FD_ZERO(&write_set);
|
||||
pptp_fd_set(conn, &read_set, &write_set, &max_fd);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
select(max_fd + 1, &read_set, &write_set, NULL, &tv);
|
||||
rc = pptp_dispatch(conn, &read_set, &write_set);
|
||||
if (rc > 0) {
|
||||
/* wait for a respond, a timeout because there might not be one */
|
||||
FD_ZERO(&read_set);
|
||||
FD_ZERO(&write_set);
|
||||
pptp_fd_set(conn, &read_set, &write_set, &max_fd);
|
||||
tv.tv_sec = 2;
|
||||
tv.tv_usec = 0;
|
||||
select(max_fd + 1, &read_set, &write_set, NULL, &tv);
|
||||
rc = pptp_dispatch(conn, &read_set, &write_set);
|
||||
if (rc > 0) {
|
||||
if (i > 0) sleep(2);
|
||||
/* no more open calls. Close the connection. */
|
||||
pptp_conn_close(conn, PPTP_STOP_LOCAL_SHUTDOWN);
|
||||
/* wait for a respond, a timeout because there might not be one */
|
||||
FD_ZERO(&read_set);
|
||||
FD_ZERO(&write_set);
|
||||
pptp_fd_set(conn, &read_set, &write_set, &max_fd);
|
||||
tv.tv_sec = 2;
|
||||
tv.tv_usec = 0;
|
||||
select(max_fd + 1, &read_set, &write_set, NULL, &tv);
|
||||
pptp_dispatch(conn, &read_set, &write_set);
|
||||
if (rc > 0) sleep(2);
|
||||
}
|
||||
}
|
||||
/* with extreme prejudice */
|
||||
pptp_conn_destroy(conn);
|
||||
pptp_conn_free(conn);
|
||||
vector_destroy(call_list);
|
||||
}
|
||||
cleanup:
|
||||
signal(SIGINT, callmgr_do_nothing);
|
||||
signal(SIGTERM, callmgr_do_nothing);
|
||||
close_inetsock(inet_sock, inetaddr);
|
||||
close_unixsock(unix_sock, inetaddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** open_inetsock ************************************************************/
|
||||
int open_inetsock(struct in_addr inetaddr)
|
||||
{
|
||||
union {
|
||||
struct sockaddr a;
|
||||
struct sockaddr_in i;
|
||||
} dest, src;
|
||||
int s;
|
||||
dest.i.sin_family = AF_INET;
|
||||
dest.i.sin_port = htons(PPTP_PORT);
|
||||
dest.i.sin_addr = inetaddr;
|
||||
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
warn("socket: %s", strerror(errno));
|
||||
return s;
|
||||
}
|
||||
#ifdef SO_MARK
|
||||
if (rtmark) {
|
||||
if (setsockopt(s, SOL_SOCKET, SO_MARK, &rtmark, sizeof(rtmark))) {
|
||||
warn("setsockopt(SO_MARK): %s", strerror(errno));
|
||||
close(s); return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (localbind.s_addr != INADDR_NONE) {
|
||||
bzero(&src, sizeof(src));
|
||||
src.i.sin_family = AF_INET;
|
||||
src.i.sin_addr = localbind;
|
||||
if (bind(s, &src.a, sizeof(src.i)) != 0) {
|
||||
warn("bind: %s", strerror(errno));
|
||||
close(s); return -1;
|
||||
}
|
||||
}
|
||||
if (connect(s, &dest.a, sizeof(dest.i)) < 0) {
|
||||
warn("connect: %s", strerror(errno));
|
||||
close(s); return -1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*** open_unixsock ************************************************************/
|
||||
int open_unixsock(struct in_addr inetaddr)
|
||||
{
|
||||
union {
|
||||
struct sockaddr a;
|
||||
struct sockaddr_un u;
|
||||
} where;
|
||||
struct stat st;
|
||||
char *dir;
|
||||
int s;
|
||||
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
warn("socket: %s", strerror(errno));
|
||||
return s;
|
||||
}
|
||||
callmgr_name_unixsock( &where.u, inetaddr, localbind);
|
||||
if (stat(where.u.sun_path, &st) >= 0) {
|
||||
warn("Call manager for %s is already running.", inet_ntoa(inetaddr));
|
||||
close(s); return -1;
|
||||
}
|
||||
/* Make sure path is valid. */
|
||||
dir = dirname(where.u.sun_path);
|
||||
if (!make_valid_path(dir, 0770))
|
||||
fatal("Could not make path to %s: %s", where.u.sun_path, strerror(errno));
|
||||
free(dir);
|
||||
if (bind(s, &where.a, sizeof(where.u)) < 0) {
|
||||
warn("bind: %s", strerror(errno));
|
||||
close(s); return -1;
|
||||
}
|
||||
chmod(where.u.sun_path, 0777);
|
||||
listen(s, 127);
|
||||
return s;
|
||||
}
|
||||
|
||||
/*** close_inetsock ***********************************************************/
|
||||
void close_inetsock(int fd, struct in_addr inetaddr __attribute__ ((unused)))
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/*** close_unixsock ***********************************************************/
|
||||
void close_unixsock(int fd, struct in_addr inetaddr)
|
||||
{
|
||||
struct sockaddr_un where;
|
||||
close(fd);
|
||||
callmgr_name_unixsock(&where, inetaddr, localbind);
|
||||
unlink(where.sun_path);
|
||||
}
|
||||
|
||||
/*** make a unix socket address ***********************************************/
|
||||
void callmgr_name_unixsock(struct sockaddr_un *where,
|
||||
struct in_addr inetaddr,
|
||||
struct in_addr localbind)
|
||||
{
|
||||
char localaddr[16];
|
||||
where->sun_family = AF_UNIX;
|
||||
strcpy(localaddr, inet_ntoa(localbind));
|
||||
snprintf(where->sun_path, sizeof(where->sun_path),
|
||||
PPTP_SOCKET_PREFIX "%s:%s", localaddr, inet_ntoa(inetaddr));
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/* pptp_callmgr.h ... Call manager for PPTP connections.
|
||||
* Handles TCP port 1723 protocol.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: pptp_callmgr.h,v 1.3 2003/02/17 00:22:17 quozl Exp $
|
||||
*/
|
||||
|
||||
#define PPTP_SOCKET_PREFIX "/var/run/pptp/"
|
||||
|
||||
int callmgr_main(int argc, char**argv, char**envp);
|
||||
void callmgr_name_unixsock(struct sockaddr_un *where,
|
||||
struct in_addr inetaddr,
|
||||
struct in_addr localbind);
|
|
@ -0,0 +1,93 @@
|
|||
/* pptp_compat.c ... Compatibility functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#if defined (__SVR4) && defined (__sun) /* Solaris */
|
||||
#include <stropts.h>
|
||||
#endif
|
||||
#include <strings.h>
|
||||
#include "pptp_compat.h"
|
||||
#include <stdio.h>
|
||||
#include "util.h"
|
||||
|
||||
#if defined (__SVR4) && defined (__sun) /* Solaris */
|
||||
/*
|
||||
* daemon implementation from uClibc
|
||||
*/
|
||||
int daemon(int nochdir, int noclose)
|
||||
{
|
||||
int fd;
|
||||
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
return (-1);
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
if (setsid() == -1)
|
||||
return (-1);
|
||||
|
||||
if (!nochdir)
|
||||
chdir("/");
|
||||
|
||||
if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
|
||||
dup2(fd, STDIN_FILENO);
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
dup2(fd, STDERR_FILENO);
|
||||
if (fd > 2)
|
||||
close (fd);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* openpty implementation based on pts(7D) example
|
||||
*/
|
||||
int openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize * winp) {
|
||||
int fdm,fds;
|
||||
char * slavename;
|
||||
|
||||
/* open master */
|
||||
if ( (fdm = open("/dev/ptmx", O_RDWR)) == -1 )
|
||||
return -1;
|
||||
|
||||
/* grant access to the slave pseudo-terminal device */
|
||||
if ( grantpt(fdm) == -1 )
|
||||
return -1;
|
||||
|
||||
/* unlock a pseudo-terminal master/slave pair */
|
||||
if ( unlockpt(fdm) == -1 )
|
||||
return -1;
|
||||
|
||||
/* get name of the slave pseudo-terminal device */
|
||||
if ( (slavename = ptsname(fdm)) == NULL )
|
||||
return -1;
|
||||
|
||||
if ( (fds = open(slavename, O_RDWR)) == -1 ) {
|
||||
free(slavename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ioctl(fds, I_PUSH, "ptem"); /* push ptem */
|
||||
ioctl(fds, I_PUSH, "ldterm"); /* push ldterm*/
|
||||
|
||||
if ( name != NULL )
|
||||
strcpy(name,slavename);
|
||||
|
||||
*amaster = fdm;
|
||||
*aslave = fds;
|
||||
|
||||
free(slavename);
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif /* Solaris */
|
|
@ -0,0 +1,18 @@
|
|||
/* pptp_compat.h ... Compatibility functions
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined (__SVR4) && defined (__sun) /* Solaris */
|
||||
#include <sys/termios.h>
|
||||
|
||||
#define u_int8_t uint8_t
|
||||
#define u_int16_t uint16_t
|
||||
#define u_int32_t uint32_t
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE 0xffffffffU
|
||||
#endif
|
||||
|
||||
int daemon(int nochdir, int noclose);
|
||||
int openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize * winp);
|
||||
#endif /* Solaris */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,60 @@
|
|||
/* pptp_ctrl.h ... handle PPTP control connection.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: pptp_ctrl.h,v 1.7 2010/06/15 05:04:32 quozl Exp $
|
||||
*/
|
||||
|
||||
#ifndef INC_PPTP_CTRL_H
|
||||
#define INC_PPTP_CTRL_H
|
||||
#include <sys/types.h>
|
||||
#include "pptp_compat.h"
|
||||
|
||||
typedef struct PPTP_CONN PPTP_CONN;
|
||||
typedef struct PPTP_CALL PPTP_CALL;
|
||||
|
||||
enum call_state { CALL_OPEN_RQST, CALL_OPEN_DONE, CALL_OPEN_FAIL,
|
||||
CALL_CLOSE_RQST, CALL_CLOSE_DONE };
|
||||
enum conn_state { CONN_OPEN_RQST, CONN_OPEN_DONE, CONN_OPEN_FAIL,
|
||||
CONN_CLOSE_RQST, CONN_CLOSE_DONE };
|
||||
|
||||
typedef void (*pptp_call_cb)(PPTP_CONN*, PPTP_CALL*, enum call_state);
|
||||
typedef void (*pptp_conn_cb)(PPTP_CONN*, enum conn_state);
|
||||
|
||||
/* if 'isclient' is true, then will send 'conn open' packet to other host.
|
||||
* not necessary if this is being opened by a server process after
|
||||
* receiving a conn_open packet from client.
|
||||
*/
|
||||
PPTP_CONN * pptp_conn_open(int inet_sock, int isclient,
|
||||
pptp_conn_cb callback);
|
||||
PPTP_CALL * pptp_call_open(PPTP_CONN * conn,
|
||||
pptp_call_cb callback, char *phonenr);
|
||||
int pptp_conn_established(PPTP_CONN * conn);
|
||||
/* soft close. Will callback on completion. */
|
||||
void pptp_call_close(PPTP_CONN * conn, PPTP_CALL * call);
|
||||
/* hard close. */
|
||||
void pptp_call_destroy(PPTP_CONN *conn, PPTP_CALL *call);
|
||||
int pptp_conn_is_dead(PPTP_CONN * conn);
|
||||
void pptp_conn_free(PPTP_CONN * conn);
|
||||
/* soft close. Will callback on completion. */
|
||||
void pptp_conn_close(PPTP_CONN * conn, u_int8_t close_reason);
|
||||
/* hard close */
|
||||
void pptp_conn_destroy(PPTP_CONN * conn);
|
||||
|
||||
/* Add file descriptors used by pptp to fd_set. */
|
||||
void pptp_fd_set(PPTP_CONN * conn, fd_set * read_set, fd_set * write_set, int *max_fd);
|
||||
/* handle any pptp file descriptors set in fd_set, and clear them */
|
||||
int pptp_dispatch(PPTP_CONN * conn, fd_set * read_set, fd_set * write_set);
|
||||
|
||||
/* Get info about connection, call */
|
||||
void pptp_call_get_ids(PPTP_CONN * conn, PPTP_CALL * call,
|
||||
u_int16_t * call_id, u_int16_t * peer_call_id);
|
||||
/* Arbitrary user data about this call/connection.
|
||||
* It is the caller's responsibility to free this data before calling
|
||||
* pptp_call|conn_close()
|
||||
*/
|
||||
void * pptp_conn_closure_get(PPTP_CONN * conn);
|
||||
void pptp_conn_closure_put(PPTP_CONN * conn, void *cl);
|
||||
void * pptp_call_closure_get(PPTP_CONN * conn, PPTP_CALL * call);
|
||||
void pptp_call_closure_put(PPTP_CONN * conn, PPTP_CALL * call, void *cl);
|
||||
|
||||
#endif /* INC_PPTP_CTRL_H */
|
|
@ -0,0 +1,559 @@
|
|||
/* pptp_gre.c -- encapsulate PPP in PPTP-GRE.
|
||||
* Handle the IP Protocol 47 portion of PPTP.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: pptp_gre.c,v 1.49 2011/12/19 07:18:09 quozl Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if defined (__SVR4) && defined (__sun)
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include "ppp_fcs.h"
|
||||
#include "pptp_msg.h"
|
||||
#include "pptp_gre.h"
|
||||
#include "util.h"
|
||||
#include "pqueue.h"
|
||||
#include "test-redirections.h"
|
||||
|
||||
/* globals from pptp.c */
|
||||
extern struct in_addr localbind;
|
||||
extern int rtmark;
|
||||
|
||||
#define PACKET_MAX 8196
|
||||
/* test for a 32 bit counter overflow */
|
||||
#define WRAPPED( curseq, lastseq) \
|
||||
((((curseq) & 0xffffff00) == 0) && \
|
||||
(((lastseq) & 0xffffff00 ) == 0xffffff00))
|
||||
|
||||
static u_int32_t ack_sent, ack_recv;
|
||||
static u_int32_t seq_sent, seq_recv;
|
||||
static u_int16_t pptp_gre_call_id, pptp_gre_peer_call_id;
|
||||
gre_stats_t stats;
|
||||
|
||||
typedef int (*callback_t)(int cl, void *pack, unsigned int len);
|
||||
|
||||
/* decaps_hdlc gets all the packets possible with ONE blocking read */
|
||||
/* returns <0 if read() call fails */
|
||||
int decaps_hdlc(int fd, callback_t callback, int cl);
|
||||
int encaps_hdlc(int fd, void *pack, unsigned int len);
|
||||
int decaps_gre (int fd, callback_t callback, int cl);
|
||||
int encaps_gre (int fd, void *pack, unsigned int len);
|
||||
int dequeue_gre(callback_t callback, int cl);
|
||||
|
||||
/* test redirection function pointers */
|
||||
struct test_redirections *my;
|
||||
|
||||
unsigned char dest[2 * PACKET_MAX + 2]; /* largest expansion possible */
|
||||
|
||||
#undef PRINT_PACKETS
|
||||
#ifdef PRINT_PACKETS
|
||||
|
||||
#include <stdio.h>
|
||||
void print_packet(int fd, void *pack, unsigned int len)
|
||||
{
|
||||
unsigned char *b = (unsigned char *)pack;
|
||||
unsigned int i,j;
|
||||
static FILE *out = NULL;
|
||||
|
||||
if (out == NULL) out = fdopen(fd, "w");
|
||||
fprintf(out,"-- begin packet (%u) --\n", len);
|
||||
for (i = 0; i < len; i += 16) {
|
||||
for (j = 0; j < 8; j++)
|
||||
if (i + 2 * j + 1 < len)
|
||||
fprintf(out, "%02x%02x ",
|
||||
(unsigned int) b[i + 2 * j],
|
||||
(unsigned int) b[i + 2 * j + 1]);
|
||||
else if (i + 2 * j < len)
|
||||
fprintf(out, "%02x ", (unsigned int) b[i + 2 * j]);
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
fprintf(out, "-- end packet --\n");
|
||||
fflush(out);
|
||||
}
|
||||
#endif /* PRINT_PACKETS */
|
||||
|
||||
/*** time_now_usecs ***********************************************************/
|
||||
uint64_t time_now_usecs(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return (tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
}
|
||||
|
||||
/*** Open IP protocol socket **************************************************/
|
||||
int pptp_gre_bind(struct in_addr inetaddr)
|
||||
{
|
||||
union {
|
||||
struct sockaddr a;
|
||||
struct sockaddr_in i;
|
||||
} loc_addr, src_addr;
|
||||
int s = socket(AF_INET, SOCK_RAW, PPTP_PROTO);
|
||||
if (s < 0) { warn("socket: %s", strerror(errno)); return -1; }
|
||||
#ifdef SO_MARK
|
||||
if (rtmark) {
|
||||
if (setsockopt(s, SOL_SOCKET, SO_MARK, &rtmark, sizeof(rtmark))) {
|
||||
warn("setsockopt(SO_MARK): %s", strerror(errno));
|
||||
close(s); return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (localbind.s_addr != INADDR_NONE) {
|
||||
bzero(&loc_addr, sizeof(loc_addr));
|
||||
loc_addr.i.sin_family = AF_INET;
|
||||
loc_addr.i.sin_addr = localbind;
|
||||
if (bind(s, &loc_addr.a, sizeof(loc_addr.i)) != 0) {
|
||||
warn("bind: %s", strerror(errno)); close(s); return -1;
|
||||
}
|
||||
}
|
||||
src_addr.i.sin_family = AF_INET;
|
||||
src_addr.i.sin_addr = inetaddr;
|
||||
src_addr.i.sin_port = 0;
|
||||
if (connect(s, &src_addr.a, sizeof(src_addr.i)) < 0) {
|
||||
warn("connect: %s", strerror(errno)); close(s); return -1;
|
||||
}
|
||||
my = test_redirections();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*** pptp_gre_copy ************************************************************/
|
||||
void pptp_gre_copy(u_int16_t call_id, u_int16_t peer_call_id,
|
||||
int pty_fd, int gre_fd)
|
||||
{
|
||||
int max_fd;
|
||||
pptp_gre_call_id = call_id;
|
||||
pptp_gre_peer_call_id = peer_call_id;
|
||||
/* Pseudo-terminal already open. */
|
||||
ack_sent = ack_recv = seq_sent = seq_recv = 0;
|
||||
/* weird select semantics */
|
||||
max_fd = gre_fd;
|
||||
if (pty_fd > max_fd) max_fd = pty_fd;
|
||||
/* Dispatch loop */
|
||||
for (;;) { /* until error happens on gre_fd or pty_fd */
|
||||
struct timeval tv = {0, 0};
|
||||
struct timeval *tvp;
|
||||
fd_set rfds;
|
||||
int retval;
|
||||
pqueue_t *head;
|
||||
int block_usecs = -1; /* wait forever */
|
||||
/* watch terminal and socket for input */
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(gre_fd, &rfds);
|
||||
FD_SET(pty_fd, &rfds);
|
||||
/*
|
||||
* if there are multiple pending ACKs, then do a minimal timeout;
|
||||
* else if there is a single pending ACK then timeout after 0,5 seconds;
|
||||
* else block until data is available.
|
||||
*/
|
||||
if (ack_sent != seq_recv) {
|
||||
if (ack_sent + 1 == seq_recv) /* u_int wrap-around safe */
|
||||
block_usecs = 500000;
|
||||
else
|
||||
/* don't use zero, this will force a resceduling */
|
||||
/* when calling select(), giving pppd a chance to */
|
||||
/* run. */
|
||||
block_usecs = 1;
|
||||
}
|
||||
/* otherwise block_usecs == -1, which means wait forever */
|
||||
/*
|
||||
* If there is a packet in the queue, then don't wait longer than
|
||||
* the time remaining until it expires.
|
||||
*/
|
||||
head = pqueue_head();
|
||||
if (head != NULL) {
|
||||
int expiry_time = pqueue_expiry_time(head);
|
||||
if (block_usecs == -1 || expiry_time < block_usecs)
|
||||
block_usecs = expiry_time;
|
||||
}
|
||||
if (block_usecs == -1) {
|
||||
tvp = NULL;
|
||||
} else {
|
||||
tvp = &tv;
|
||||
tv.tv_usec = block_usecs;
|
||||
tv.tv_sec = tv.tv_usec / 1000000;
|
||||
tv.tv_usec %= 1000000;
|
||||
}
|
||||
retval = select(max_fd + 1, &rfds, NULL, NULL, tvp);
|
||||
if (retval > 0 && FD_ISSET(pty_fd, &rfds)) {
|
||||
if (decaps_hdlc(pty_fd, encaps_gre, gre_fd) < 0)
|
||||
break;
|
||||
} else if (retval == 0 && ack_sent != seq_recv) {
|
||||
/* if outstanding ack */
|
||||
/* send ack with no payload */
|
||||
encaps_gre(gre_fd, NULL, 0);
|
||||
}
|
||||
if (retval > 0 && FD_ISSET(gre_fd, &rfds)) {
|
||||
if (decaps_gre (gre_fd, encaps_hdlc, pty_fd) < 0)
|
||||
break;
|
||||
}
|
||||
if (dequeue_gre (encaps_hdlc, pty_fd) < 0)
|
||||
break;
|
||||
}
|
||||
/* Close up when done. */
|
||||
close(gre_fd);
|
||||
close(pty_fd);
|
||||
}
|
||||
|
||||
#define HDLC_FLAG 0x7E
|
||||
#define HDLC_ESCAPE 0x7D
|
||||
#define HDLC_TRANSPARENCY 0x20
|
||||
|
||||
/* ONE blocking read per call; dispatches all packets possible */
|
||||
/* returns 0 on success, or <0 on read failure */
|
||||
int decaps_hdlc(int fd, int (*cb)(int cl, void *pack, unsigned int len), int cl)
|
||||
{
|
||||
unsigned char buffer[PACKET_MAX];
|
||||
ssize_t start = 0, end;
|
||||
int status;
|
||||
static unsigned int len = 0, escape = 0;
|
||||
static unsigned char copy[PACKET_MAX];
|
||||
static int checkedsync = 0;
|
||||
/* start is start of packet. end is end of buffer data */
|
||||
/* this is the only blocking read we will allow */
|
||||
if ((end = read (fd, buffer, sizeof(buffer))) <= 0) {
|
||||
int saved_errno = errno;
|
||||
warn("short read (%zd): %s", end, strerror(saved_errno));
|
||||
switch (saved_errno) {
|
||||
case EMSGSIZE: {
|
||||
socklen_t optval, optlen = sizeof(optval);
|
||||
warn("transmitted GRE packet triggered an ICMP destination unreachable, fragmentation needed, or exceeds the MTU of the network interface");
|
||||
#define IP_MTU 14
|
||||
if(getsockopt(fd, IPPROTO_IP, IP_MTU, &optval, &optlen) < 0)
|
||||
warn("getsockopt: %s", strerror(errno));
|
||||
warn("getsockopt: IP_MTU: %d\n", optval);
|
||||
return 0;
|
||||
}
|
||||
case EIO:
|
||||
warn("pppd may have shutdown, see pppd log");
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/* warn if the sync options of ppp and pptp don't match */
|
||||
if( !checkedsync) {
|
||||
checkedsync = 1;
|
||||
if( buffer[0] == HDLC_FLAG){
|
||||
if( syncppp )
|
||||
warn( "pptp --sync option is active, "
|
||||
"yet the ppp mode is asynchronous!\n");
|
||||
}
|
||||
else if( !syncppp )
|
||||
warn( "The ppp mode is synchronous, "
|
||||
"yet no pptp --sync option is specified!\n");
|
||||
}
|
||||
/* in synchronous mode there are no hdlc control characters nor checksum
|
||||
* bytes. Find end of packet with the length information in the PPP packet
|
||||
*/
|
||||
if ( syncppp ){
|
||||
while ( start + 8 < end) {
|
||||
len = ntoh16(*(short int *)(buffer + start + 6)) + 4;
|
||||
/* note: the buffer may contain an incomplete packet at the end
|
||||
* this packet will be read again at the next read() */
|
||||
if ( start + len <= end)
|
||||
if ((status = cb (cl, buffer + start, len)) < 0)
|
||||
return status; /* error-check */
|
||||
start += len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* asynchronous mode */
|
||||
while (start < end) {
|
||||
/* Copy to 'copy' and un-escape as we go. */
|
||||
while (buffer[start] != HDLC_FLAG) {
|
||||
if ((escape == 0) && buffer[start] == HDLC_ESCAPE) {
|
||||
escape = HDLC_TRANSPARENCY;
|
||||
} else {
|
||||
if (len < PACKET_MAX)
|
||||
copy [len++] = buffer[start] ^ escape;
|
||||
escape = 0;
|
||||
}
|
||||
start++;
|
||||
if (start >= end)
|
||||
return 0; /* No more data, but the frame is not complete yet. */
|
||||
}
|
||||
/* found flag. skip past it */
|
||||
start++;
|
||||
/* check for over-short packets and silently discard, as per RFC1662 */
|
||||
if ((len < 4) || (escape != 0)) {
|
||||
len = 0; escape = 0;
|
||||
continue;
|
||||
}
|
||||
/* check, then remove the 16-bit FCS checksum field */
|
||||
if (pppfcs16 (PPPINITFCS16, copy, len) != PPPGOODFCS16)
|
||||
warn("Bad Frame Check Sequence during PPP to GRE decapsulation");
|
||||
len -= sizeof(u_int16_t);
|
||||
/* so now we have a packet of length 'len' in 'copy' */
|
||||
if ((status = cb (cl, copy, len)) < 0)
|
||||
return status; /* error-check */
|
||||
/* Great! Let's do more! */
|
||||
len = 0; escape = 0;
|
||||
}
|
||||
return 0;
|
||||
/* No more data to process. */
|
||||
}
|
||||
|
||||
/*** Make stripped packet into HDLC packet ************************************/
|
||||
int encaps_hdlc(int fd, void *pack, unsigned int len)
|
||||
{
|
||||
unsigned char *source = (unsigned char *)pack;
|
||||
unsigned int pos = 0, i;
|
||||
u_int16_t fcs;
|
||||
/* in synchronous mode there is little to do */
|
||||
if ( syncppp )
|
||||
return write(fd, source, len);
|
||||
/* asynchronous mode */
|
||||
/* Compute the FCS */
|
||||
fcs = pppfcs16(PPPINITFCS16, source, len) ^ 0xFFFF;
|
||||
/* start character */
|
||||
dest[pos++] = HDLC_FLAG;
|
||||
/* escape the payload */
|
||||
for (i = 0; i < len + 2; i++) {
|
||||
/* wacked out assignment to add FCS to end of source buffer */
|
||||
unsigned char c =
|
||||
(i < len)?source[i]:(i == len)?(fcs & 0xFF):((fcs >> 8) & 0xFF);
|
||||
if (pos >= sizeof(dest)) break; /* truncate on overflow */
|
||||
if ( (c < 0x20) || (c == HDLC_FLAG) || (c == HDLC_ESCAPE) ) {
|
||||
dest[pos++] = HDLC_ESCAPE;
|
||||
if (pos < sizeof(dest))
|
||||
dest[pos++] = c ^ 0x20;
|
||||
} else
|
||||
dest[pos++] = c;
|
||||
}
|
||||
/* tack on the end-flag */
|
||||
if (pos < sizeof(dest))
|
||||
dest[pos++] = HDLC_FLAG;
|
||||
/* now write this packet */
|
||||
return write(fd, dest, pos);
|
||||
}
|
||||
|
||||
/*** decaps_gre ***************************************************************/
|
||||
int decaps_gre (int fd, callback_t callback, int cl)
|
||||
{
|
||||
unsigned char buffer[PACKET_MAX + 64 /*ip header*/];
|
||||
struct pptp_gre_header *header;
|
||||
int status, ip_len = 0;
|
||||
static int first = 1;
|
||||
unsigned int headersize;
|
||||
unsigned int payload_len;
|
||||
u_int32_t seq;
|
||||
|
||||
if ((status = read (fd, buffer, sizeof(buffer))) <= 0) {
|
||||
warn("short read (%d): %s", status, strerror(errno));
|
||||
stats.rx_errors++;
|
||||
return -1;
|
||||
}
|
||||
/* strip off IP header, if present */
|
||||
if ((buffer[0] & 0xF0) == 0x40)
|
||||
ip_len = (buffer[0] & 0xF) * 4;
|
||||
header = (struct pptp_gre_header *)(buffer + ip_len);
|
||||
/* verify packet (else discard) */
|
||||
if ( /* version should be 1 */
|
||||
((ntoh8(header->ver) & 0x7F) != PPTP_GRE_VER) ||
|
||||
/* PPTP-GRE protocol for PPTP */
|
||||
(ntoh16(header->protocol) != PPTP_GRE_PROTO)||
|
||||
/* flag C should be clear */
|
||||
PPTP_GRE_IS_C(ntoh8(header->flags)) ||
|
||||
/* flag R should be clear */
|
||||
PPTP_GRE_IS_R(ntoh8(header->flags)) ||
|
||||
/* flag K should be set */
|
||||
(!PPTP_GRE_IS_K(ntoh8(header->flags))) ||
|
||||
/* routing and recursion ctrl = 0 */
|
||||
((ntoh8(header->flags)&0xF) != 0)) {
|
||||
/* if invalid, discard this packet */
|
||||
warn("Discarding GRE: %X %X %X %X %X %X",
|
||||
ntoh8(header->ver)&0x7F, ntoh16(header->protocol),
|
||||
PPTP_GRE_IS_C(ntoh8(header->flags)),
|
||||
PPTP_GRE_IS_R(ntoh8(header->flags)),
|
||||
PPTP_GRE_IS_K(ntoh8(header->flags)),
|
||||
ntoh8(header->flags) & 0xF);
|
||||
stats.rx_invalid++;
|
||||
return 0;
|
||||
}
|
||||
/* silently discard packets not for this call */
|
||||
if (ntoh16(header->call_id) != pptp_gre_call_id) return 0;
|
||||
/* test if acknowledgement present */
|
||||
if (PPTP_GRE_IS_A(ntoh8(header->ver))) {
|
||||
u_int32_t ack = (PPTP_GRE_IS_S(ntoh8(header->flags)))?
|
||||
header->ack:header->seq; /* ack in different place if S = 0 */
|
||||
ack = ntoh32( ack);
|
||||
if (ack > ack_recv) ack_recv = ack;
|
||||
/* also handle sequence number wrap-around */
|
||||
if (WRAPPED(ack,ack_recv)) ack_recv = ack;
|
||||
if (ack_recv == stats.pt.seq) {
|
||||
int rtt = time_now_usecs() - stats.pt.time;
|
||||
stats.rtt = (stats.rtt + rtt) / 2;
|
||||
}
|
||||
}
|
||||
/* test if payload present */
|
||||
if (!PPTP_GRE_IS_S(ntoh8(header->flags)))
|
||||
return 0; /* ack, but no payload */
|
||||
headersize = sizeof(*header);
|
||||
payload_len = ntoh16(header->payload_len);
|
||||
seq = ntoh32(header->seq);
|
||||
/* no ack present? */
|
||||
if (!PPTP_GRE_IS_A(ntoh8(header->ver))) headersize -= sizeof(header->ack);
|
||||
/* check for incomplete packet (length smaller than expected) */
|
||||
if (status - headersize < payload_len) {
|
||||
warn("discarding truncated packet (expected %d, got %d bytes)",
|
||||
payload_len, status - headersize);
|
||||
stats.rx_truncated++;
|
||||
return 0;
|
||||
}
|
||||
/* check for expected sequence number */
|
||||
if ( first || (seq == seq_recv + 1)) { /* wrap-around safe */
|
||||
if ( log_level >= 2 )
|
||||
log("accepting packet %d", seq);
|
||||
stats.rx_accepted++;
|
||||
first = 0;
|
||||
seq_recv = seq;
|
||||
return callback(cl, buffer + ip_len + headersize, payload_len);
|
||||
/* out of order, check if the number is too low and discard the packet.
|
||||
* (handle sequence number wrap-around, and try to do it right) */
|
||||
} else if ( seq < seq_recv + 1 || WRAPPED(seq_recv, seq) ) {
|
||||
if ( log_level >= 1 )
|
||||
log("discarding duplicate or old packet %d (expecting %d)",
|
||||
seq, seq_recv + 1);
|
||||
stats.rx_underwin++;
|
||||
/* sequence number too high, is it reasonably close? */
|
||||
} else if ( (seq < seq_recv + missing_window ||
|
||||
WRAPPED(seq, seq_recv + missing_window)) ||
|
||||
(missing_window == -1) ) {
|
||||
stats.rx_buffered++;
|
||||
if ( log_level >= 1 )
|
||||
log("%s packet %d (expecting %d, lost or reordered)",
|
||||
disable_buffer ? "accepting" : "buffering",
|
||||
seq, seq_recv+1);
|
||||
if ( disable_buffer ) {
|
||||
seq_recv = seq;
|
||||
stats.rx_lost += seq - seq_recv - 1;
|
||||
return callback(cl, buffer + ip_len + headersize, payload_len);
|
||||
} else {
|
||||
pqueue_add(seq, buffer + ip_len + headersize, payload_len);
|
||||
}
|
||||
/* no, packet must be discarded */
|
||||
} else {
|
||||
if ( log_level >= 1 )
|
||||
warn("discarding bogus packet %d (expecting %d)",
|
||||
seq, seq_recv + 1);
|
||||
stats.rx_overwin++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** dequeue_gre **************************************************************/
|
||||
int dequeue_gre (callback_t callback, int cl)
|
||||
{
|
||||
pqueue_t *head;
|
||||
int status;
|
||||
/* process packets in the queue that either are expected or have
|
||||
* timed out. */
|
||||
head = pqueue_head();
|
||||
while ( head != NULL &&
|
||||
( (head->seq == seq_recv + 1) || /* wrap-around safe */
|
||||
(pqueue_expiry_time(head) <= 0)
|
||||
)
|
||||
) {
|
||||
/* if it is timed out... */
|
||||
if (head->seq != seq_recv + 1 ) { /* wrap-around safe */
|
||||
stats.rx_lost += head->seq - seq_recv - 1;
|
||||
if (log_level >= 2)
|
||||
log("timeout waiting for %d packets", head->seq - seq_recv - 1);
|
||||
}
|
||||
if (log_level >= 2)
|
||||
log("accepting %d from queue", head->seq);
|
||||
seq_recv = head->seq;
|
||||
status = callback(cl, head->packet, head->packlen);
|
||||
pqueue_del(head);
|
||||
if (status < 0)
|
||||
return status;
|
||||
head = pqueue_head();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** encaps_gre ***************************************************************/
|
||||
int encaps_gre (int fd, void *pack, unsigned int len)
|
||||
{
|
||||
union {
|
||||
struct pptp_gre_header header;
|
||||
unsigned char buffer[PACKET_MAX + sizeof(struct pptp_gre_header)];
|
||||
} u;
|
||||
static u_int32_t seq = 1; /* first sequence number sent must be 1 */
|
||||
unsigned int header_len;
|
||||
int rc;
|
||||
/* package this up in a GRE shell. */
|
||||
u.header.flags = hton8 (PPTP_GRE_FLAG_K);
|
||||
u.header.ver = hton8 (PPTP_GRE_VER);
|
||||
u.header.protocol = hton16(PPTP_GRE_PROTO);
|
||||
u.header.payload_len = hton16(len);
|
||||
u.header.call_id = hton16(pptp_gre_peer_call_id);
|
||||
/* special case ACK with no payload */
|
||||
if (pack == NULL) {
|
||||
if (ack_sent != seq_recv) {
|
||||
u.header.ver |= hton8(PPTP_GRE_FLAG_A);
|
||||
u.header.payload_len = hton16(0);
|
||||
/* ack is in odd place because S == 0 */
|
||||
u.header.seq = hton32(seq_recv);
|
||||
ack_sent = seq_recv;
|
||||
rc = (*my->write)(fd, &u.header,
|
||||
sizeof(u.header) - sizeof(u.header.seq));
|
||||
if (rc < 0) {
|
||||
if (errno == ENOBUFS)
|
||||
rc = 0; /* Simply ignore it */
|
||||
stats.tx_failed++;
|
||||
} else if ((size_t)rc < sizeof(u.header) - sizeof(u.header.seq)) {
|
||||
stats.tx_short++;
|
||||
} else {
|
||||
stats.tx_acks++;
|
||||
}
|
||||
return rc;
|
||||
} else return 0; /* we don't need to send ACK */
|
||||
} /* explicit brace to avoid ambiguous `else' warning */
|
||||
/* send packet with payload */
|
||||
u.header.flags |= hton8(PPTP_GRE_FLAG_S);
|
||||
u.header.seq = hton32(seq);
|
||||
if (ack_sent != seq_recv) { /* send ack with this message */
|
||||
u.header.ver |= hton8(PPTP_GRE_FLAG_A);
|
||||
u.header.ack = hton32(seq_recv);
|
||||
ack_sent = seq_recv;
|
||||
header_len = sizeof(u.header);
|
||||
} else { /* don't send ack */
|
||||
header_len = sizeof(u.header) - sizeof(u.header.ack);
|
||||
}
|
||||
if (header_len + len >= sizeof(u.buffer)) {
|
||||
stats.tx_oversize++;
|
||||
return 0; /* drop this, it's too big */
|
||||
}
|
||||
/* copy payload into buffer */
|
||||
memcpy(u.buffer + header_len, pack, len);
|
||||
/* record and increment sequence numbers */
|
||||
seq_sent = seq; seq++;
|
||||
#ifdef PRINT_PACKETS
|
||||
print_packet(2, u.buffer, header_len + len);
|
||||
#endif
|
||||
/* write this baby out to the net */
|
||||
rc = (*my->write)(fd, u.buffer, header_len + len);
|
||||
if (rc < 0) {
|
||||
if (errno == ENOBUFS)
|
||||
rc = 0; /* Simply ignore it */
|
||||
stats.tx_failed++;
|
||||
} else if ((size_t)rc < header_len + len) {
|
||||
stats.tx_short++;
|
||||
} else {
|
||||
stats.tx_sent++;
|
||||
stats.pt.seq = seq_sent;
|
||||
stats.pt.time = time_now_usecs();
|
||||
}
|
||||
return rc;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/* pptp_gre.h -- encapsulate PPP in PPTP-GRE.
|
||||
* Handle the IP Protocol 47 portion of PPTP.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: pptp_gre.h,v 1.6 2008/02/19 05:05:03 quozl Exp $
|
||||
*/
|
||||
|
||||
#include "pptp_compat.h"
|
||||
|
||||
int pptp_gre_bind(struct in_addr inetaddr);
|
||||
void pptp_gre_copy(u_int16_t call_id, u_int16_t peer_call_id,
|
||||
int pty_fd, int gre_fd);
|
||||
|
||||
extern int syncppp;
|
||||
extern int disable_buffer;
|
||||
|
||||
typedef struct pack_track {
|
||||
uint32_t seq; // seq no of this tracked packet
|
||||
uint64_t time; // time when this tracked packet was sent (in usecs)
|
||||
} pack_track_t;
|
||||
|
||||
typedef struct gre_stats {
|
||||
/* statistics for GRE receive */
|
||||
|
||||
uint32_t rx_accepted; // data packet was passed to pppd
|
||||
uint32_t rx_lost; // data packet did not arrive before timeout
|
||||
uint32_t rx_underwin; // data packet was under window (arrived too late
|
||||
// or duplicate packet)
|
||||
uint32_t rx_overwin; // data packet was over window
|
||||
// (too many packets lost?)
|
||||
uint32_t rx_buffered; // data packet arrived earlier than expected,
|
||||
// packet(s) before it were lost or reordered
|
||||
uint32_t rx_errors; // OS error on receive
|
||||
uint32_t rx_truncated; // truncated packet
|
||||
uint32_t rx_invalid; // wrong protocol or invalid flags
|
||||
uint32_t rx_acks; // acknowledgement only
|
||||
|
||||
/* statistics for GRE transmit */
|
||||
|
||||
uint32_t tx_sent; // data packet write() to GRE socket succeeded
|
||||
uint32_t tx_failed; // data packet write() to GRE socket returned error
|
||||
uint32_t tx_short; // data packet write() to GRE socket underflowed
|
||||
uint32_t tx_acks; // sent packet with just ACK
|
||||
uint32_t tx_oversize; // data packet dropped because it was too large
|
||||
|
||||
/* statistics for packet tracking, for RTT calculation */
|
||||
|
||||
pack_track_t pt; // last data packet seq/time
|
||||
int rtt; // estimated round-trip time in us
|
||||
|
||||
} gre_stats_t;
|
||||
|
||||
extern gre_stats_t stats;
|
|
@ -0,0 +1,304 @@
|
|||
/* pptp.h: packet structures and magic constants for the PPTP protocol
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: pptp_msg.h,v 1.4 2008/02/19 05:05:03 quozl Exp $
|
||||
*/
|
||||
|
||||
#ifndef INC_PPTP_H
|
||||
#define INC_PPTP_H
|
||||
|
||||
/* Grab definitions of int16, int32, etc. */
|
||||
#include <sys/types.h>
|
||||
#include "pptp_compat.h"
|
||||
/* define "portable" htons, etc. */
|
||||
#define hton8(x) (x)
|
||||
#define ntoh8(x) (x)
|
||||
#define hton16(x) htons(x)
|
||||
#define ntoh16(x) ntohs(x)
|
||||
#define hton32(x) htonl(x)
|
||||
#define ntoh32(x) ntohl(x)
|
||||
|
||||
/* PPTP magic numbers: ----------------------------------------- */
|
||||
|
||||
#define PPTP_MAGIC 0x1A2B3C4D /* Magic cookie for PPTP datagrams */
|
||||
#define PPTP_PORT 1723 /* PPTP TCP port number */
|
||||
#define PPTP_PROTO 47 /* PPTP IP protocol number */
|
||||
|
||||
/* Control Connection Message Types: --------------------------- */
|
||||
|
||||
#define PPTP_MESSAGE_CONTROL 1
|
||||
#define PPTP_MESSAGE_MANAGE 2
|
||||
|
||||
/* Control Message Types: -------------------------------------- */
|
||||
|
||||
/* (Control Connection Management) */
|
||||
#define PPTP_START_CTRL_CONN_RQST 1
|
||||
#define PPTP_START_CTRL_CONN_RPLY 2
|
||||
#define PPTP_STOP_CTRL_CONN_RQST 3
|
||||
#define PPTP_STOP_CTRL_CONN_RPLY 4
|
||||
#define PPTP_ECHO_RQST 5
|
||||
#define PPTP_ECHO_RPLY 6
|
||||
|
||||
/* (Call Management) */
|
||||
#define PPTP_OUT_CALL_RQST 7
|
||||
#define PPTP_OUT_CALL_RPLY 8
|
||||
#define PPTP_IN_CALL_RQST 9
|
||||
#define PPTP_IN_CALL_RPLY 10
|
||||
#define PPTP_IN_CALL_CONNECT 11
|
||||
#define PPTP_CALL_CLEAR_RQST 12
|
||||
#define PPTP_CALL_CLEAR_NTFY 13
|
||||
|
||||
/* (Error Reporting) */
|
||||
#define PPTP_WAN_ERR_NTFY 14
|
||||
|
||||
/* (PPP Session Control) */
|
||||
#define PPTP_SET_LINK_INFO 15
|
||||
|
||||
/* PPTP version information: --------------------------------------*/
|
||||
#define PPTP_VERSION_STRING "1.00"
|
||||
#define PPTP_VERSION 0x100
|
||||
#define PPTP_FIRMWARE_STRING "0.01"
|
||||
#define PPTP_FIRMWARE_VERSION 0x001
|
||||
|
||||
/* PPTP capabilities: ---------------------------------------------*/
|
||||
|
||||
/* (Framing capabilities for msg sender) */
|
||||
#define PPTP_FRAME_ASYNC 1
|
||||
#define PPTP_FRAME_SYNC 2
|
||||
#define PPTP_FRAME_ANY 3
|
||||
|
||||
/* (Bearer capabilities for msg sender) */
|
||||
#define PPTP_BEARER_ANALOG 1
|
||||
#define PPTP_BEARER_DIGITAL 2
|
||||
#define PPTP_BEARER_ANY 3
|
||||
|
||||
#define PPTP_RESULT_GENERAL_ERROR 2
|
||||
|
||||
/* (Reasons to close a connection) */
|
||||
#define PPTP_STOP_NONE 1 /* no good reason */
|
||||
#define PPTP_STOP_PROTOCOL 2 /* can't support peer's protocol version */
|
||||
#define PPTP_STOP_LOCAL_SHUTDOWN 3 /* requester is being shut down */
|
||||
|
||||
/* PPTP datagram structures (all data in network byte order): ----------*/
|
||||
|
||||
struct pptp_header {
|
||||
u_int16_t length; /* message length in octets, including header */
|
||||
u_int16_t pptp_type; /* PPTP message type. 1 for control message. */
|
||||
u_int32_t magic; /* this should be PPTP_MAGIC. */
|
||||
u_int16_t ctrl_type; /* Control message type (0-15) */
|
||||
u_int16_t reserved0; /* reserved. MUST BE ZERO. */
|
||||
};
|
||||
|
||||
struct pptp_start_ctrl_conn { /* for control message types 1 and 2 */
|
||||
struct pptp_header header;
|
||||
|
||||
u_int16_t version; /* PPTP protocol version. = PPTP_VERSION */
|
||||
u_int8_t result_code; /* these two fields should be zero on rqst msg*/
|
||||
u_int8_t error_code; /* 0 unless result_code==2 (General Error) */
|
||||
u_int32_t framing_cap; /* Framing capabilities */
|
||||
u_int32_t bearer_cap; /* Bearer Capabilities */
|
||||
u_int16_t max_channels; /* Maximum Channels (=0 for PNS, PAC ignores) */
|
||||
u_int16_t firmware_rev; /* Firmware or Software Revision */
|
||||
u_int8_t hostname[64]; /* Host Name (64 octets, zero terminated) */
|
||||
u_int8_t vendor[64]; /* Vendor string (64 octets, zero term.) */
|
||||
/* MS says that end of hostname/vendor fields should be filled with */
|
||||
/* octets of value 0, but Win95 PPTP driver doesn't do this. */
|
||||
};
|
||||
|
||||
struct pptp_stop_ctrl_conn { /* for control message types 3 and 4 */
|
||||
struct pptp_header header;
|
||||
|
||||
u_int8_t reason_result; /* reason for rqst, result for rply */
|
||||
u_int8_t error_code; /* MUST be 0, unless rply result==2 (general err)*/
|
||||
u_int16_t reserved1; /* MUST be 0 */
|
||||
};
|
||||
|
||||
struct pptp_echo_rqst { /* for control message type 5 */
|
||||
struct pptp_header header;
|
||||
u_int32_t identifier; /* arbitrary value set by sender which is used */
|
||||
/* to match up reply and request */
|
||||
};
|
||||
|
||||
struct pptp_echo_rply { /* for control message type 6 */
|
||||
struct pptp_header header;
|
||||
u_int32_t identifier; /* should correspond to id of rqst */
|
||||
u_int8_t result_code;
|
||||
u_int8_t error_code; /* =0, unless result_code==2 (general error) */
|
||||
u_int16_t reserved1; /* MUST BE ZERO */
|
||||
};
|
||||
|
||||
struct pptp_out_call_rqst { /* for control message type 7 */
|
||||
struct pptp_header header;
|
||||
u_int16_t call_id; /* Call ID (unique id used to multiplex data) */
|
||||
u_int16_t call_sernum; /* Call Serial Number (used for logging) */
|
||||
u_int32_t bps_min; /* Minimum BPS (lowest acceptable line speed) */
|
||||
u_int32_t bps_max; /* Maximum BPS (highest acceptable line speed) */
|
||||
u_int32_t bearer; /* Bearer type */
|
||||
u_int32_t framing; /* Framing type */
|
||||
u_int16_t recv_size; /* Recv. Window Size (no. of buffered packets) */
|
||||
u_int16_t delay; /* Packet Processing Delay (in 1/10 sec) */
|
||||
u_int16_t phone_len; /* Phone Number Length (num. of valid digits) */
|
||||
u_int16_t reserved1; /* MUST BE ZERO */
|
||||
u_int8_t phone_num[64]; /* Phone Number (64 octets, null term.) */
|
||||
u_int8_t subaddress[64]; /* Subaddress (64 octets, null term.) */
|
||||
};
|
||||
|
||||
struct pptp_out_call_rply { /* for control message type 8 */
|
||||
struct pptp_header header;
|
||||
u_int16_t call_id; /* Call ID (used to multiplex data over tunnel)*/
|
||||
u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/
|
||||
u_int8_t result_code; /* Result Code (1 is no errors) */
|
||||
u_int8_t error_code; /* Error Code (=0 unless result_code==2) */
|
||||
u_int16_t cause_code; /* Cause Code (addt'l failure information) */
|
||||
u_int32_t speed; /* Connect Speed (in BPS) */
|
||||
u_int16_t recv_size; /* Recv. Window Size (no. of buffered packets) */
|
||||
u_int16_t delay; /* Packet Processing Delay (in 1/10 sec) */
|
||||
u_int32_t channel; /* Physical Channel ID (for logging) */
|
||||
};
|
||||
|
||||
struct pptp_in_call_rqst { /* for control message type 9 */
|
||||
struct pptp_header header;
|
||||
u_int16_t call_id; /* Call ID (unique id used to multiplex data) */
|
||||
u_int16_t call_sernum; /* Call Serial Number (used for logging) */
|
||||
u_int32_t bearer; /* Bearer type */
|
||||
u_int32_t channel; /* Physical Channel ID (for logging) */
|
||||
u_int16_t dialed_len; /* Dialed Number Length (# of valid digits) */
|
||||
u_int16_t dialing_len; /* Dialing Number Length (# of valid digits) */
|
||||
u_int8_t dialed_num[64]; /* Dialed Number (64 octets, zero term.) */
|
||||
u_int8_t dialing_num[64]; /* Dialing Number (64 octets, zero term.) */
|
||||
u_int8_t subaddress[64]; /* Subaddress (64 octets, zero term.) */
|
||||
};
|
||||
|
||||
struct pptp_in_call_rply { /* for control message type 10 */
|
||||
struct pptp_header header;
|
||||
u_int16_t call_id; /* Call ID (used to multiplex data over tunnel)*/
|
||||
u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/
|
||||
u_int8_t result_code; /* Result Code (1 is no errors) */
|
||||
u_int8_t error_code; /* Error Code (=0 unless result_code==2) */
|
||||
u_int16_t recv_size; /* Recv. Window Size (no. of buffered packets) */
|
||||
u_int16_t delay; /* Packet Processing Delay (in 1/10 sec) */
|
||||
u_int16_t reserved1; /* MUST BE ZERO */
|
||||
};
|
||||
|
||||
struct pptp_in_call_connect { /* for control message type 11 */
|
||||
struct pptp_header header;
|
||||
u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/
|
||||
u_int16_t reserved1; /* MUST BE ZERO */
|
||||
u_int32_t speed; /* Connect Speed (in BPS) */
|
||||
u_int16_t recv_size; /* Recv. Window Size (no. of buffered packets) */
|
||||
u_int16_t delay; /* Packet Processing Delay (in 1/10 sec) */
|
||||
u_int32_t framing; /* Framing type */
|
||||
};
|
||||
|
||||
struct pptp_call_clear_rqst { /* for control message type 12 */
|
||||
struct pptp_header header;
|
||||
u_int16_t call_id; /* Call ID (used to multiplex data over tunnel)*/
|
||||
u_int16_t reserved1; /* MUST BE ZERO */
|
||||
};
|
||||
|
||||
struct pptp_call_clear_ntfy { /* for control message type 13 */
|
||||
struct pptp_header header;
|
||||
u_int16_t call_id; /* Call ID (used to multiplex data over tunnel)*/
|
||||
u_int8_t result_code; /* Result Code */
|
||||
u_int8_t error_code; /* Error Code (=0 unless result_code==2) */
|
||||
u_int16_t cause_code; /* Cause Code (for ISDN, is Q.931 cause code) */
|
||||
u_int16_t reserved1; /* MUST BE ZERO */
|
||||
u_int8_t call_stats[128]; /* Call Statistics: 128 octets, ascii, 0-term */
|
||||
};
|
||||
|
||||
struct pptp_wan_err_ntfy { /* for control message type 14 */
|
||||
struct pptp_header header;
|
||||
u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/
|
||||
u_int16_t reserved1; /* MUST BE ZERO */
|
||||
u_int32_t crc_errors; /* CRC errors */
|
||||
u_int32_t frame_errors; /* Framing errors */
|
||||
u_int32_t hard_errors; /* Hardware overruns */
|
||||
u_int32_t buff_errors; /* Buffer overruns */
|
||||
u_int32_t time_errors; /* Time-out errors */
|
||||
u_int32_t align_errors; /* Alignment errors */
|
||||
};
|
||||
|
||||
struct pptp_set_link_info { /* for control message type 15 */
|
||||
struct pptp_header header;
|
||||
u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst) */
|
||||
u_int16_t reserved1; /* MUST BE ZERO */
|
||||
u_int32_t send_accm; /* Send ACCM (for PPP packets; default 0xFFFFFFFF)*/
|
||||
u_int32_t recv_accm; /* Receive ACCM (for PPP pack.;default 0xFFFFFFFF)*/
|
||||
};
|
||||
|
||||
/* helpful #defines: -------------------------------------------- */
|
||||
#define pptp_isvalid_ctrl(header, type, length) \
|
||||
(!( ( ntoh16(((struct pptp_header *)header)->length) < (length) ) || \
|
||||
( ntoh16(((struct pptp_header *)header)->pptp_type) !=(type) ) || \
|
||||
( ntoh32(((struct pptp_header *)header)->magic) !=PPTP_MAGIC) || \
|
||||
( ntoh16(((struct pptp_header *)header)->ctrl_type) > PPTP_SET_LINK_INFO) || \
|
||||
( ntoh16(((struct pptp_header *)header)->reserved0) !=0 ) ))
|
||||
|
||||
#define PPTP_HEADER_CTRL(type) \
|
||||
{ hton16(PPTP_CTRL_SIZE(type)), \
|
||||
hton16(PPTP_MESSAGE_CONTROL), \
|
||||
hton32(PPTP_MAGIC), \
|
||||
hton16(type), 0 }
|
||||
|
||||
#define PPTP_CTRL_SIZE(type) ( \
|
||||
(type==PPTP_START_CTRL_CONN_RQST)?sizeof(struct pptp_start_ctrl_conn): \
|
||||
(type==PPTP_START_CTRL_CONN_RPLY)?sizeof(struct pptp_start_ctrl_conn): \
|
||||
(type==PPTP_STOP_CTRL_CONN_RQST )?sizeof(struct pptp_stop_ctrl_conn): \
|
||||
(type==PPTP_STOP_CTRL_CONN_RPLY )?sizeof(struct pptp_stop_ctrl_conn): \
|
||||
(type==PPTP_ECHO_RQST )?sizeof(struct pptp_echo_rqst): \
|
||||
(type==PPTP_ECHO_RPLY )?sizeof(struct pptp_echo_rply): \
|
||||
(type==PPTP_OUT_CALL_RQST )?sizeof(struct pptp_out_call_rqst): \
|
||||
(type==PPTP_OUT_CALL_RPLY )?sizeof(struct pptp_out_call_rply): \
|
||||
(type==PPTP_IN_CALL_RQST )?sizeof(struct pptp_in_call_rqst): \
|
||||
(type==PPTP_IN_CALL_RPLY )?sizeof(struct pptp_in_call_rply): \
|
||||
(type==PPTP_IN_CALL_CONNECT )?sizeof(struct pptp_in_call_connect): \
|
||||
(type==PPTP_CALL_CLEAR_RQST )?sizeof(struct pptp_call_clear_rqst): \
|
||||
(type==PPTP_CALL_CLEAR_NTFY )?sizeof(struct pptp_call_clear_ntfy): \
|
||||
(type==PPTP_WAN_ERR_NTFY )?sizeof(struct pptp_wan_err_ntfy): \
|
||||
(type==PPTP_SET_LINK_INFO )?sizeof(struct pptp_set_link_info): \
|
||||
0)
|
||||
#define max(a,b) (((a)>(b))?(a):(b))
|
||||
#define PPTP_CTRL_SIZE_MAX ( \
|
||||
max(sizeof(struct pptp_start_ctrl_conn), \
|
||||
max(sizeof(struct pptp_echo_rqst), \
|
||||
max(sizeof(struct pptp_echo_rply), \
|
||||
max(sizeof(struct pptp_out_call_rqst), \
|
||||
max(sizeof(struct pptp_out_call_rply), \
|
||||
max(sizeof(struct pptp_in_call_rqst), \
|
||||
max(sizeof(struct pptp_in_call_rply), \
|
||||
max(sizeof(struct pptp_in_call_connect), \
|
||||
max(sizeof(struct pptp_call_clear_rqst), \
|
||||
max(sizeof(struct pptp_call_clear_ntfy), \
|
||||
max(sizeof(struct pptp_wan_err_ntfy), \
|
||||
max(sizeof(struct pptp_set_link_info), 0)))))))))))))
|
||||
|
||||
|
||||
/* gre header structure: -------------------------------------------- */
|
||||
|
||||
#define PPTP_GRE_PROTO 0x880B
|
||||
#define PPTP_GRE_VER 0x1
|
||||
|
||||
#define PPTP_GRE_FLAG_C 0x80
|
||||
#define PPTP_GRE_FLAG_R 0x40
|
||||
#define PPTP_GRE_FLAG_K 0x20
|
||||
#define PPTP_GRE_FLAG_S 0x10
|
||||
#define PPTP_GRE_FLAG_A 0x80
|
||||
|
||||
#define PPTP_GRE_IS_C(f) ((f)&PPTP_GRE_FLAG_C)
|
||||
#define PPTP_GRE_IS_R(f) ((f)&PPTP_GRE_FLAG_R)
|
||||
#define PPTP_GRE_IS_K(f) ((f)&PPTP_GRE_FLAG_K)
|
||||
#define PPTP_GRE_IS_S(f) ((f)&PPTP_GRE_FLAG_S)
|
||||
#define PPTP_GRE_IS_A(f) ((f)&PPTP_GRE_FLAG_A)
|
||||
|
||||
struct pptp_gre_header {
|
||||
u_int8_t flags; /* bitfield */
|
||||
u_int8_t ver; /* should be PPTP_GRE_VER (enhanced GRE) */
|
||||
u_int16_t protocol; /* should be PPTP_GRE_PROTO (ppp-encaps) */
|
||||
u_int16_t payload_len; /* size of ppp payload, not inc. gre header */
|
||||
u_int16_t call_id; /* peer's call_id for this session */
|
||||
u_int32_t seq; /* sequence number. Present if S==1 */
|
||||
u_int32_t ack; /* seq number of highest packet recieved by */
|
||||
/* sender in this session */
|
||||
};
|
||||
|
||||
#endif /* INC_PPTP_H */
|
|
@ -0,0 +1,41 @@
|
|||
/* pptp_options.h ...... various constants used in the PPTP protocol.
|
||||
* #define STANDARD to emulate NT 4.0 exactly.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: pptp_options.h,v 1.3 2004/11/09 01:42:32 quozl Exp $
|
||||
*/
|
||||
|
||||
#ifndef INC_PPTP_OPTIONS_H
|
||||
#define INC_PPTP_OPTIONS_H
|
||||
|
||||
#undef PPTP_FIRMWARE_STRING
|
||||
#undef PPTP_FIRMWARE_VERSION
|
||||
#define PPTP_BUF_MAX 65536
|
||||
#define PPTP_TIMEOUT 60 /* seconds */
|
||||
extern int idle_wait;
|
||||
extern int max_echo_wait;
|
||||
#define PPTP_CONNECT_SPEED 10000000
|
||||
#define PPTP_WINDOW 3
|
||||
#define PPTP_DELAY 0
|
||||
#define PPTP_BPS_MIN 2400
|
||||
#define PPTP_BPS_MAX 10000000
|
||||
|
||||
#ifndef STANDARD
|
||||
#define PPTP_MAX_CHANNELS 65535
|
||||
#define PPTP_FIRMWARE_STRING "0.01"
|
||||
#define PPTP_FIRMWARE_VERSION 0x001
|
||||
#define PPTP_HOSTNAME {'l','o','c','a','l',0}
|
||||
#define PPTP_VENDOR {'c','a','n','a','n','i','a','n',0}
|
||||
#define PPTP_FRAME_CAP PPTP_FRAME_ANY
|
||||
#define PPTP_BEARER_CAP PPTP_BEARER_ANY
|
||||
#else
|
||||
#define PPTP_MAX_CHANNELS 5
|
||||
#define PPTP_FIRMWARE_STRING "0.01"
|
||||
#define PPTP_FIRMWARE_VERSION 0
|
||||
#define PPTP_HOSTNAME {'l','o','c','a','l',0}
|
||||
#define PPTP_VENDOR {'N','T',0}
|
||||
#define PPTP_FRAME_CAP 2
|
||||
#define PPTP_BEARER_CAP 1
|
||||
#endif
|
||||
|
||||
#endif /* INC_PPTP_OPTIONS_H */
|
|
@ -0,0 +1,54 @@
|
|||
/* pptp_quirks.c ...... various options to fix quirks found in buggy adsl modems
|
||||
* mulix <mulix@actcom.co.il>
|
||||
*
|
||||
* $Id: pptp_quirks.c,v 1.3 2011/12/19 07:15:03 quozl Exp $
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "orckit_quirks.h"
|
||||
#include "pptp_quirks.h"
|
||||
|
||||
static int quirk_index = -1;
|
||||
|
||||
struct pptp_fixup pptp_fixups[] = {
|
||||
{BEZEQ_ISRAEL, ORCKIT, ORCKIT_ATUR3,
|
||||
orckit_atur3_build_hook,
|
||||
orckit_atur3_start_ctrl_conn_hook,
|
||||
orckit_atur3_set_link_hook}
|
||||
};
|
||||
|
||||
static int fixups_sz = sizeof(pptp_fixups)/sizeof(pptp_fixups[0]);
|
||||
|
||||
/* return 0 on success, non 0 otherwise */
|
||||
int set_quirk_index(int index)
|
||||
{
|
||||
if (index >= 0 && index < fixups_sz) {
|
||||
quirk_index = index;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int get_quirk_index(void)
|
||||
{
|
||||
return quirk_index;
|
||||
}
|
||||
|
||||
/* return the index for this isp in the quirks table, -1 if not found */
|
||||
int find_quirk(const char* isp_name)
|
||||
{
|
||||
int i = 0;
|
||||
if (isp_name) {
|
||||
while (i < fixups_sz && pptp_fixups[i].isp) {
|
||||
if (!strcmp(pptp_fixups[i].isp, isp_name)) {
|
||||
return i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/* pptp_quirks.h ...... various options to fix quirks found in buggy adsl modems
|
||||
* mulix <mulix@actcom.co.il>
|
||||
*
|
||||
* $Id: pptp_quirks.h,v 1.2 2011/12/19 07:15:03 quozl Exp $
|
||||
*/
|
||||
|
||||
#ifndef INC_PPTP_QUIRKS_H
|
||||
#define INC_PPTP_QUIRKS_H
|
||||
|
||||
/* isp defs - correspond to slots in the fixups table */
|
||||
#define BEZEQ_ISRAEL "BEZEQ_ISRAEL"
|
||||
|
||||
/* vendor defs */
|
||||
|
||||
#define ORCKIT 1
|
||||
#define ALCATEL 2
|
||||
|
||||
/* device defs */
|
||||
|
||||
#define ORCKIT_ATUR2 1
|
||||
#define ORCKIT_ATUR3 2
|
||||
|
||||
#include "pptp_msg.h"
|
||||
#include "pptp_ctrl.h"
|
||||
|
||||
struct pptp_fixup {
|
||||
const char* isp; /* which isp? e.g. Bezeq in Israel */
|
||||
int vendor; /* which vendor? e.g. Orckit */
|
||||
int device; /* which device? e.g. Orckit Atur3 */
|
||||
|
||||
/* use this hook to build your own out call request packet */
|
||||
int (*out_call_rqst_hook)(struct pptp_out_call_rqst* packet);
|
||||
|
||||
/* use this hook to build your own start control connection packet */
|
||||
/* note that this hook is called from two different places, depending
|
||||
on whether this is a request or reply */
|
||||
int (*start_ctrl_conn)(struct pptp_start_ctrl_conn* packet);
|
||||
|
||||
/* use this hook if you need to send a 'set_link' packet once
|
||||
the connection is established */
|
||||
int (*set_link_hook)(struct pptp_set_link_info* packet,
|
||||
int peer_call_id);
|
||||
};
|
||||
|
||||
extern struct pptp_fixup pptp_fixups[];
|
||||
|
||||
/* find the index for this isp in the quirks table */
|
||||
/* return the index on success, -1 if not found */
|
||||
int find_quirk(const char* isp_name);
|
||||
|
||||
/* set the global quirk index. return 0 on success, non 0 otherwise */
|
||||
int set_quirk_index(int index);
|
||||
|
||||
/* get the global quirk index. return the index on success,
|
||||
-1 if no quirk is defined */
|
||||
int get_quirk_index(void);
|
||||
|
||||
|
||||
#endif /* INC_PPTP_QUIRKS_H */
|
|
@ -0,0 +1,277 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
|
||||
use vars qw($VERSION);
|
||||
$VERSION = '0.03';
|
||||
|
||||
# Command-line parameters:
|
||||
|
||||
# actions
|
||||
my ( $_create, $_delete, $_help );
|
||||
|
||||
# values
|
||||
my ( $SERVER, $DOMAIN, $USERNAME, $PASSWORD, $ENCRYPT, $START );
|
||||
|
||||
my $result = GetOptions(
|
||||
"create|c=s" => \$_create, # --create foo -> &create("foo")
|
||||
"delete=s" => \$_delete, # --delete foo -> &delete("foo")
|
||||
"help|h" => \$_help, # --help -> &help()
|
||||
"server|s=s" => \$SERVER,
|
||||
"domain|d=s" => \$DOMAIN,
|
||||
"username|u=s" => \$USERNAME,
|
||||
"password|p=s" => \$PASSWORD,
|
||||
"encrypt|e" => \$ENCRYPT,
|
||||
"start" => \$START,
|
||||
);
|
||||
|
||||
if ($_create) {
|
||||
&create($_create);
|
||||
} elsif ($_delete) {
|
||||
&delete($_delete);
|
||||
} elsif ($_help) {
|
||||
&help();
|
||||
} else {
|
||||
die "$0: too few arguments.\nTry '$0 --help' for more information.\n";
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
####
|
||||
|
||||
sub create {
|
||||
my $TUNNEL = shift;
|
||||
|
||||
# input validation
|
||||
($TUNNEL) = $TUNNEL =~ m{^(\w+)$}
|
||||
or die "$0: invalid tunnel name.\nTry '$0 --help' for more information.\n";
|
||||
($SERVER) = $SERVER =~ m{^(.+)$}
|
||||
or die "$0: invalid server.\nTry '$0 --help' for more information.\n";
|
||||
($USERNAME) = $USERNAME =~ m{^(.+)$}
|
||||
or die "$0: invalid username.\nTry '$0 --help' for more information.\n";
|
||||
|
||||
# ask password
|
||||
if ( !$PASSWORD ) {
|
||||
print "Password: ";
|
||||
$PASSWORD = <STDIN>;
|
||||
$PASSWORD =~ s/([^\x20\x21\x23-\x7e])/sprintf ("\\x%02x", ord ($1))/eg;
|
||||
}
|
||||
|
||||
# put '\' between domain and username IF specified a domain
|
||||
$DOMAIN = "$DOMAIN\\" if $DOMAIN;
|
||||
|
||||
# create or add lines to the /etc/ppp/chap-secrets file,
|
||||
# which holds usernames and passwords
|
||||
my $chap_secrets_file = '/etc/ppp/chap-secrets';
|
||||
umask( 0027 );
|
||||
open( FILE, ">>", $chap_secrets_file )
|
||||
or die "$0: can't write to '$chap_secrets_file': $!\n";
|
||||
|
||||
print FILE "\n";
|
||||
print FILE "# added by pptpsetup for $TUNNEL\n";
|
||||
print FILE "$DOMAIN$USERNAME $TUNNEL \"$PASSWORD\" *\n";
|
||||
|
||||
close FILE;
|
||||
|
||||
# create a /etc/ppp/peers/$TUNNEL file
|
||||
my $tunnel_file = "/etc/ppp/peers/$TUNNEL";
|
||||
open( FILE, ">$tunnel_file" )
|
||||
or die "$0: can't write to '$tunnel_file': $!\n";
|
||||
|
||||
print FILE <<"TUNNEL";
|
||||
# written by pptpsetup
|
||||
pty "/usr/sbin/pptp $SERVER --nolaunchpppd"
|
||||
lock
|
||||
noauth
|
||||
nobsdcomp
|
||||
nodeflate
|
||||
name $DOMAIN$USERNAME
|
||||
remotename $TUNNEL
|
||||
ipparam $TUNNEL
|
||||
TUNNEL
|
||||
|
||||
print FILE "require-mppe-128\n" if $ENCRYPT;
|
||||
|
||||
close FILE;
|
||||
|
||||
# start tunneling
|
||||
if ($START) {
|
||||
system("pppd call $TUNNEL updetach");
|
||||
}
|
||||
}
|
||||
|
||||
####
|
||||
|
||||
sub help {
|
||||
print <<'EOF';
|
||||
pptpsetup --create <TUNNEL> --server <SERVER> [--domain <DOMAIN>]
|
||||
--username <USERNAME> [--password <PASSWORD>]
|
||||
[--encrypt] [--start]
|
||||
|
||||
pptpsetup --delete <TUNNEL>
|
||||
|
||||
Options:
|
||||
|
||||
* the name you wish to use to refer to the tunnel (you choose it),
|
||||
* the IP address or host name of the server,
|
||||
* the authentication domain name (optional),
|
||||
* the username you are to use,
|
||||
* the password you are to use,
|
||||
* whether encryption is required,
|
||||
* whether to start the connection after configuration.
|
||||
|
||||
pptpsetup - Point-to-Point Tunneling Protocol setup
|
||||
|
||||
Copyright (C) 2006 Free Software Foundation
|
||||
|
||||
pptpsetup comes with ABSOLUTELY NO WARRANTY; for details see source.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; see source for details.
|
||||
|
||||
Written by Nelson Ferraz.
|
||||
EOF
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
####
|
||||
|
||||
sub delete {
|
||||
my $tunnel = shift;
|
||||
|
||||
# input validation
|
||||
($tunnel) = $tunnel =~ m{^(\w+)$}
|
||||
or die "$0: invalid tunnel name.\nTry '$0 --help' for more information.\n";
|
||||
|
||||
# delete tunnel file
|
||||
my $tunnel_file = "/etc/ppp/peers/$tunnel";
|
||||
unlink $tunnel_file
|
||||
or die "$0: can't delete '$tunnel_file': $!\n";
|
||||
|
||||
# delete entry from chap-secrets
|
||||
my $chap_file = '/etc/ppp/chap-secrets';
|
||||
my $mode = (stat($chap_file))[2] & 07777;
|
||||
|
||||
open( FILE, $chap_file )
|
||||
or die "$0: can't read '$chap_file': $!\n";
|
||||
my @chap = <FILE>;
|
||||
close FILE;
|
||||
|
||||
my $new_chap = '';
|
||||
foreach (@chap) {
|
||||
$new_chap .= $_ unless /\b$tunnel\b/;
|
||||
}
|
||||
|
||||
# backup
|
||||
rename( $chap_file, "$chap_file.bkp" );
|
||||
|
||||
# write new chap-secrets
|
||||
open( FILE, ">$chap_file" )
|
||||
or die "$0: can't write '$chap_file': $!\n";
|
||||
chmod $mode, $chap_file;
|
||||
print FILE $new_chap;
|
||||
close FILE;
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
pptpsetup - Point-to-Point Tunneling Protocol setup
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
pptpsetup --create <TUNNEL> --server <SERVER> [--domain <DOMAIN>]
|
||||
--username <USERNAME> [--password <PASSWORD>]
|
||||
[--encrypt] [--start]
|
||||
|
||||
pptpsetup --delete <TUNNEL>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
PPTP Client is a Linux, FreeBSD, NetBSD and OpenBSD client for the
|
||||
proprietary Microsoft Point-to-Point Tunneling Protocol, PPTP.
|
||||
|
||||
This script configures PPTP Client on Linux.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 16
|
||||
|
||||
=item --create TUNNEL
|
||||
|
||||
create a tunnel named TUNNEL
|
||||
|
||||
=item --delete TUNNEL
|
||||
|
||||
delete the file /etc/ppp/peers/TUNNEL and any lines from
|
||||
/etc/ppp/chap-secrets that contains "TUNNEL" as a single word
|
||||
|
||||
=item --server SERVER
|
||||
|
||||
the IP address or host name of the server
|
||||
|
||||
=item --domain DOMAIN
|
||||
|
||||
the authentication domain name (optional)
|
||||
|
||||
=item --username USERNAME
|
||||
|
||||
the username you are to use
|
||||
|
||||
=item --password PASSWORD
|
||||
|
||||
the password you are to use. If you don't specify a password,
|
||||
pptpsetup will ask for one.
|
||||
|
||||
=item --encrypt
|
||||
|
||||
whether encryption is required
|
||||
|
||||
=item --start
|
||||
|
||||
whether the connection should be started after configuration.
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Nelson Ferraz <nferraz at gmail.com>,
|
||||
based on James Cameron's PPTP Client Debian HOWTO.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
=over 16
|
||||
|
||||
=item PPTP Client Debian HOWTO
|
||||
|
||||
http://pptpclient.sourceforge.net/howto-debian.phtml
|
||||
|
||||
=item PPTP Client Diagnosis HOWTO
|
||||
|
||||
http://pptpclient.sourceforge.net/howto-diagnosis.phtml
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
pptpsetup - Point-to-Point Tunneling Protocol setup
|
||||
|
||||
Copyright (C) 2006 Nelson Ferraz
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
@ -0,0 +1,243 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "util.h" // for log()
|
||||
#include "pqueue.h"
|
||||
|
||||
#ifdef DEBUG_PQUEUE
|
||||
#define DEBUG_ON 1
|
||||
#else
|
||||
#define DEBUG_ON 0
|
||||
#endif
|
||||
|
||||
#define DEBUG_CMD(_a) if (DEBUG_ON) { _a }
|
||||
|
||||
|
||||
#define MIN_CAPACITY 128 /* min allocated buffer for a packet */
|
||||
|
||||
static int pqueue_alloc (u_int32_t seq, unsigned char *packet, int packlen, pqueue_t **new);
|
||||
|
||||
int packet_timeout_usecs = DEFAULT_PACKET_TIMEOUT * 1000000;
|
||||
|
||||
|
||||
static pqueue_t *pq_head = NULL, *pq_tail = NULL;
|
||||
|
||||
/* contains a list of free queue elements.*/
|
||||
static pqueue_t *pq_freelist_head = NULL;
|
||||
|
||||
|
||||
|
||||
static void pq_freelist_add(pqueue_t *point) {
|
||||
/* add point to the freelist */
|
||||
point->next = pq_freelist_head;
|
||||
point->prev = NULL;
|
||||
|
||||
if (point->next)
|
||||
point->next->prev = point;
|
||||
pq_freelist_head = point;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int pqueue_alloc(u_int32_t seq, unsigned char *packet, int packlen, pqueue_t **new) {
|
||||
|
||||
pqueue_t *newent;
|
||||
|
||||
DEBUG_CMD(log("seq=%d, packlen=%d", seq, packlen););
|
||||
|
||||
/* search the freelist for one that has sufficient space */
|
||||
if (pq_freelist_head) {
|
||||
|
||||
for (newent = pq_freelist_head; newent; newent = newent->next) {
|
||||
|
||||
if (newent->capacity >= packlen) {
|
||||
|
||||
/* unlink from freelist */
|
||||
if (pq_freelist_head == newent)
|
||||
pq_freelist_head = newent->next;
|
||||
|
||||
if (newent->prev)
|
||||
newent->prev->next = newent->next;
|
||||
|
||||
if (newent->next)
|
||||
newent->next->prev = newent->prev;
|
||||
|
||||
if (pq_freelist_head)
|
||||
pq_freelist_head->prev = NULL;
|
||||
|
||||
break;
|
||||
} /* end if capacity >= packlen */
|
||||
} /* end for */
|
||||
|
||||
/* nothing found? Take first and reallocate it */
|
||||
if (NULL == newent) {
|
||||
|
||||
newent = pq_freelist_head;
|
||||
pq_freelist_head = pq_freelist_head->next;
|
||||
|
||||
if (pq_freelist_head)
|
||||
pq_freelist_head->prev = NULL;
|
||||
|
||||
DEBUG_CMD(log("realloc capacity %d to %d",newent->capacity, packlen););
|
||||
|
||||
newent->packet = (unsigned char *)realloc(newent->packet, packlen);
|
||||
|
||||
if (!newent->packet) {
|
||||
warn("error reallocating packet: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
newent->capacity = packlen;
|
||||
}
|
||||
|
||||
DEBUG_CMD(log("Recycle entry from freelist. Capacity: %d", newent->capacity););
|
||||
|
||||
} else {
|
||||
|
||||
/* allocate a new one */
|
||||
newent = (pqueue_t *)malloc( sizeof(pqueue_t) );
|
||||
if (!newent) {
|
||||
warn("error allocating newent: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
newent->capacity = 0;
|
||||
|
||||
DEBUG_CMD(log("Alloc new queue entry"););
|
||||
}
|
||||
|
||||
if ( ! newent->capacity ) {
|
||||
/* a new queue entry was allocated. Allocate the packet buffer */
|
||||
int size = packlen < MIN_CAPACITY ? MIN_CAPACITY : packlen;
|
||||
/* Allocate at least MIN_CAPACITY */
|
||||
DEBUG_CMD(log("allocating for packet size %d", size););
|
||||
newent->packet = (unsigned char *)malloc(size);
|
||||
if (!newent->packet) {
|
||||
warn("error allocating packet: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
newent->capacity = size;
|
||||
} /* endif ! capacity */
|
||||
assert( newent->capacity >= packlen );
|
||||
/* store the contents into the buffer */
|
||||
memcpy(newent->packet, packet, packlen);
|
||||
|
||||
newent->next = newent->prev = NULL;
|
||||
newent->seq = seq;
|
||||
newent->packlen = packlen;
|
||||
|
||||
gettimeofday(&newent->expires, NULL);
|
||||
newent->expires.tv_usec += packet_timeout_usecs;
|
||||
newent->expires.tv_sec += (newent->expires.tv_usec / 1000000);
|
||||
newent->expires.tv_usec %= 1000000;
|
||||
|
||||
*new = newent;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int pqueue_add (u_int32_t seq, unsigned char *packet, int packlen) {
|
||||
pqueue_t *newent, *point;
|
||||
|
||||
/* get a new entry */
|
||||
if ( 0 != pqueue_alloc(seq, packet, packlen, &newent) ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (point = pq_head; point != NULL; point = point->next) {
|
||||
if (point->seq == seq) {
|
||||
// queue already contains this packet
|
||||
warn("discarding duplicate packet %d", seq);
|
||||
pq_freelist_add(point);
|
||||
return -1;
|
||||
}
|
||||
if (point->seq > seq) {
|
||||
// gone too far: point->seq > seq and point->prev->seq < seq
|
||||
if (point->prev) {
|
||||
// insert between point->prev and point
|
||||
DEBUG_CMD(log("adding %d between %d and %d",
|
||||
seq, point->prev->seq, point->seq););
|
||||
|
||||
point->prev->next = newent;
|
||||
} else {
|
||||
// insert at head of queue, before point
|
||||
DEBUG_CMD(log("adding %d before %d", seq, point->seq););
|
||||
pq_head = newent;
|
||||
}
|
||||
newent->prev = point->prev; // will be NULL, at head of queue
|
||||
newent->next = point;
|
||||
point->prev = newent;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* We didn't find anywhere to insert the packet,
|
||||
* so there are no packets in the queue with higher sequences than this one,
|
||||
* so all the packets in the queue have lower sequences,
|
||||
* so this packet belongs at the end of the queue (which might be empty)
|
||||
*/
|
||||
|
||||
if (pq_head == NULL) {
|
||||
DEBUG_CMD(log("adding %d to empty queue", seq););
|
||||
pq_head = newent;
|
||||
} else {
|
||||
DEBUG_CMD(log("adding %d as tail, after %d", seq, pq_tail->seq););
|
||||
pq_tail->next = newent;
|
||||
}
|
||||
newent->prev = pq_tail;
|
||||
pq_tail = newent;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int pqueue_del (pqueue_t *point) {
|
||||
|
||||
DEBUG_CMD(log("Move seq %d to freelist", point->seq););
|
||||
|
||||
/* unlink from pq */
|
||||
if (pq_head == point) pq_head = point->next;
|
||||
if (pq_tail == point) pq_tail = point->prev;
|
||||
if (point->prev) point->prev->next = point->next;
|
||||
if (point->next) point->next->prev = point->prev;
|
||||
|
||||
/* add point to the freelist */
|
||||
pq_freelist_add(point);
|
||||
|
||||
DEBUG_CMD(
|
||||
int pq_count = 0;
|
||||
int pq_freelist_count = 0;
|
||||
pqueue_t *dpoint;
|
||||
for (dpoint = pq_head; dpoint ; dpoint = dpoint->next) {
|
||||
++pq_count;
|
||||
}
|
||||
|
||||
for (dpoint = pq_freelist_head; dpoint ; dpoint = dpoint->next) {
|
||||
++pq_freelist_count;
|
||||
}
|
||||
log("queue length is %d, freelist length is %d", pq_count,
|
||||
pq_freelist_count);
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
pqueue_t *pqueue_head (void) {
|
||||
return pq_head;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int pqueue_expiry_time (pqueue_t *entry) {
|
||||
struct timeval tv;
|
||||
int expiry_time;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
expiry_time = (entry->expires.tv_sec - tv.tv_sec) * 1000000;
|
||||
expiry_time += (entry->expires.tv_usec - tv.tv_usec);
|
||||
return expiry_time;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef PQUEUE_H
|
||||
#define PQUEUE_H
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* wait this many seconds for missing packets before forgetting about them */
|
||||
#define DEFAULT_PACKET_TIMEOUT 0.3
|
||||
extern int packet_timeout_usecs;
|
||||
|
||||
/* assume packet is bad/spoofed if it's more than this many seqs ahead */
|
||||
/* default is NOT to check - command line override via '--missing-window <n>' */
|
||||
/* default value is 300 - recommended is 6000 for high speed data rates */
|
||||
#define MISSING_WINDOW -1
|
||||
extern int missing_window;
|
||||
|
||||
/* Packet queue structure: linked list of packets received out-of-order */
|
||||
typedef struct pqueue {
|
||||
struct pqueue *next;
|
||||
struct pqueue *prev;
|
||||
u_int32_t seq;
|
||||
struct timeval expires;
|
||||
unsigned char *packet;
|
||||
int packlen;
|
||||
int capacity;
|
||||
} pqueue_t;
|
||||
|
||||
int pqueue_add (u_int32_t seq, unsigned char *packet, int packlen);
|
||||
int pqueue_del (pqueue_t *point);
|
||||
pqueue_t *pqueue_head (void);
|
||||
int pqueue_expiry_time (pqueue_t *entry);
|
||||
|
||||
#endif /* PQUEUE_H */
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
routing.c, manipulating routing table for PPTP Client
|
||||
Copyright (C) 2006 Free Software Foundation
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "routing.h"
|
||||
#include "config.h"
|
||||
|
||||
#if defined (__SVR4) && defined (__sun) /* Solaris */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include "util.h"
|
||||
/* PF_ROUTE socket*/
|
||||
int rts;
|
||||
/* Destination and gateway addresses */
|
||||
struct sockaddr_in rdst, rgw;
|
||||
/* Request sequence */
|
||||
int rseq;
|
||||
int dorouting;
|
||||
#else /* Solaris */
|
||||
/* route to the server */
|
||||
char *route;
|
||||
#endif /* Solaris */
|
||||
|
||||
/*
|
||||
|
||||
Design discussion.
|
||||
|
||||
The primary task of this module is to add a host route to the PPTP
|
||||
server so that the kernel continues to deliver PPTP control and data
|
||||
connection packets to the server despite the new PPP interface that is
|
||||
created. The flag --nohostroute is to disable this.
|
||||
|
||||
A secondary task may be to implement all-to-tunnel routing if the
|
||||
appropriate flag is specified on the command line. The flag
|
||||
--route-all is to implement this (not yet implemented).
|
||||
|
||||
Caveat.
|
||||
|
||||
It is not possible from the "ip route" command to determine if a host
|
||||
route already exists, so it isn't practical to put the routing table
|
||||
back exactly as it was.
|
||||
|
||||
We have a choice of either leaving our route lying around, or
|
||||
destroying a route that the user had pre-arranged. Both are
|
||||
unfortunate. The flag --remove-host-route is to remove the route
|
||||
regardless (not yet implemented).
|
||||
|
||||
*/
|
||||
|
||||
void routing_init(char *ip) {
|
||||
#if defined (__SVR4) && defined (__sun) /* Solaris */
|
||||
rdst.sin_family = AF_INET;
|
||||
if ( ! inet_pton(AF_INET, ip, &rdst.sin_addr) ) {
|
||||
log("Cannot convert address: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (rts = socket(PF_ROUTE, SOCK_RAW, AF_INET )) < 0 ) {
|
||||
log("Cannot open routing socket: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
struct rt_msg rtm = {
|
||||
.hdr.rtm_msglen = sizeof(struct rt_msg),
|
||||
.hdr.rtm_version = RTM_VERSION,
|
||||
.hdr.rtm_type = RTM_GET,
|
||||
.hdr.rtm_addrs = RTA_DST,
|
||||
.hdr.rtm_pid = getpid(),
|
||||
.hdr.rtm_seq = ++rseq,
|
||||
.addrs[RTAX_DST] = rdst
|
||||
};
|
||||
|
||||
if ( write(rts, &rtm, rtm.hdr.rtm_msglen) != rtm.hdr.rtm_msglen ) {
|
||||
log("Error writing to routing socket: %s", strerror(errno));
|
||||
close(rts);
|
||||
return;
|
||||
}
|
||||
|
||||
while ( read(rts, &rtm, sizeof(struct rt_msg)) > 0 )
|
||||
if ( rtm.hdr.rtm_pid == getpid() && rtm.hdr.rtm_seq == rseq) {
|
||||
/* Check if host route already present */
|
||||
if ( ( rtm.hdr.rtm_flags & RTF_HOST ) != RTF_HOST ) {
|
||||
rgw = rtm.addrs[RTAX_GATEWAY];
|
||||
dorouting = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* Solaris */
|
||||
#if defined(__linux)
|
||||
char buf[256];
|
||||
char tbuf[256];
|
||||
const char *uid;
|
||||
FILE *p;
|
||||
|
||||
snprintf(buf, 255, "%s route get %s", IP_BINARY, ip);
|
||||
p = popen(buf, "r");
|
||||
fgets(buf, 255, p);
|
||||
/* TODO: check for failure of fgets */
|
||||
uid = strstr(buf, " uid");
|
||||
if (uid) {
|
||||
snprintf(tbuf, uid - buf + 1, "%s", buf);
|
||||
route = strdup(tbuf);
|
||||
} else {
|
||||
route = strdup(buf);
|
||||
}
|
||||
pclose(p);
|
||||
/* TODO: check for failure of command */
|
||||
#endif /* __linux__ */
|
||||
}
|
||||
|
||||
void routing_start(void) {
|
||||
#if defined (__SVR4) && defined (__sun) /* Solaris */
|
||||
if ( ! dorouting )
|
||||
return;
|
||||
|
||||
struct rt_msg rtm = {
|
||||
.hdr.rtm_msglen = sizeof(struct rt_msg),
|
||||
.hdr.rtm_version = RTM_VERSION,
|
||||
.hdr.rtm_type = RTM_ADD,
|
||||
.hdr.rtm_flags = RTF_HOST | RTF_GATEWAY | RTF_STATIC,
|
||||
.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY,
|
||||
.hdr.rtm_pid = getpid(),
|
||||
.hdr.rtm_seq = ++rseq,
|
||||
.addrs[RTAX_DST] = rdst,
|
||||
.addrs[RTAX_GATEWAY] = rgw
|
||||
};
|
||||
|
||||
if ( write(rts, &rtm, rtm.hdr.rtm_msglen) != rtm.hdr.rtm_msglen ) {
|
||||
log("Error adding route: %s", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
#if defined(__linux__)
|
||||
char buf[256];
|
||||
FILE *p;
|
||||
|
||||
snprintf(buf, 255, "%s route replace %s", IP_BINARY, route);
|
||||
p = popen(buf, "r");
|
||||
pclose(p);
|
||||
#endif /* __linux__ */
|
||||
}
|
||||
|
||||
void routing_end(void) {
|
||||
#if defined (__SVR4) && defined (__sun) /* Solaris */
|
||||
if ( ! dorouting)
|
||||
return;
|
||||
|
||||
struct rt_msg rtm = {
|
||||
.hdr.rtm_msglen = sizeof(struct rt_msg),
|
||||
.hdr.rtm_version = RTM_VERSION,
|
||||
.hdr.rtm_type = RTM_DELETE,
|
||||
.hdr.rtm_flags = RTF_HOST | RTF_GATEWAY | RTF_STATIC,
|
||||
.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY,
|
||||
.hdr.rtm_pid = getpid(),
|
||||
.hdr.rtm_seq = ++rseq,
|
||||
.addrs[RTAX_DST] = rdst,
|
||||
.addrs[RTAX_GATEWAY] = rgw
|
||||
};
|
||||
|
||||
if ( write(rts, &rtm, rtm.hdr.rtm_msglen) != rtm.hdr.rtm_msglen ) {
|
||||
log("Error deleting route: %s", strerror(errno));
|
||||
}
|
||||
#endif /* Solaris */
|
||||
#if defined(__linux__)
|
||||
char buf[256];
|
||||
FILE *p;
|
||||
|
||||
snprintf(buf, 255, "%s route delete %s", IP_BINARY, route);
|
||||
p = popen(buf, "r");
|
||||
pclose(p);
|
||||
#endif /* __linux__ */
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#if defined (__SVR4) && defined (__sun) /* Solaris */
|
||||
#include <netinet/in.h>
|
||||
#include <net/route.h>
|
||||
struct rt_msg {
|
||||
struct rt_msghdr hdr;
|
||||
struct sockaddr_in addrs[RTAX_MAX];
|
||||
};
|
||||
#endif /* Solaris */
|
||||
void routing_init(char *ip);
|
||||
void routing_start(void);
|
||||
void routing_end(void);
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
|
||||
Packet reordering test implementation, intended to cause packets to be
|
||||
reordered for testing pptpd and other servers. Avoids the use of
|
||||
pqueue.c so that it can be tested independently.
|
||||
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
#include "test-redirections.h"
|
||||
|
||||
/* whether we are asked to test ordering, obtained from command line */
|
||||
extern int test_type;
|
||||
|
||||
/* rate at which to do test ordering changes */
|
||||
extern int test_rate;
|
||||
|
||||
/* trigger cycle */
|
||||
static int test_ordering_cycle = 0;
|
||||
|
||||
/* phase of reordering */
|
||||
static int test_ordering_phase = 0;
|
||||
|
||||
/* swap a packet every now and then */
|
||||
static ssize_t write_reordered_swap(int fd, const void *buf, size_t count)
|
||||
{
|
||||
static void *pocket_buf = NULL;
|
||||
static int pocket_count = 0;
|
||||
int stat;
|
||||
|
||||
switch (test_ordering_phase) {
|
||||
case 0: /* between triggers, send as normal */
|
||||
test_ordering_cycle++;
|
||||
if (test_ordering_cycle == test_rate) test_ordering_phase++;
|
||||
return write(fd, buf, count);
|
||||
case 1: /* triggered, swap a packet */
|
||||
test_ordering_cycle++;
|
||||
if (test_ordering_cycle == (test_rate+1)) {
|
||||
/* pocket the packet */
|
||||
pocket_count = count;
|
||||
pocket_buf = malloc(count);
|
||||
memcpy(pocket_buf, buf, count);
|
||||
log("test order swap, packet buffered");
|
||||
/* lie about the result */
|
||||
return count;
|
||||
} else {
|
||||
/* after this, reset to normal */
|
||||
test_ordering_cycle = 0;
|
||||
test_ordering_phase = 0;
|
||||
/* send the new packet first */
|
||||
stat = write(fd, buf, count);
|
||||
if ((size_t)stat != count) return stat;
|
||||
/* then send the old packet next */
|
||||
stat = write(fd, pocket_buf, pocket_count);
|
||||
free(pocket_buf);
|
||||
log("test order swap, packets sent");
|
||||
return count;
|
||||
}
|
||||
default:
|
||||
return write(fd, buf, count);
|
||||
}
|
||||
}
|
||||
|
||||
/* hold ten packets and send the eleventh, then the ten in order */
|
||||
static ssize_t write_reordered_retransmit(int fd, const void *buf, size_t count)
|
||||
{
|
||||
int test_length = 10;
|
||||
static void *pocket_buf[10];
|
||||
static int pocket_count[10];
|
||||
int stat, n;
|
||||
|
||||
switch (test_ordering_phase) {
|
||||
case 0: /* between triggers, send as normal */
|
||||
test_ordering_cycle++;
|
||||
if (test_ordering_cycle == test_rate) test_ordering_phase++;
|
||||
return write(fd, buf, count);
|
||||
case 1: /* triggered, buffer the packets */
|
||||
test_ordering_cycle++;
|
||||
if (test_ordering_cycle == (test_rate+test_length)) {
|
||||
test_ordering_phase = 2;
|
||||
}
|
||||
/* pocket the packet */
|
||||
n = test_ordering_cycle - test_rate - 1;
|
||||
pocket_count[n] = count;
|
||||
pocket_buf[n] = malloc(count);
|
||||
memcpy(pocket_buf[n], buf, count);
|
||||
log("test order retransmit, packet buffered");
|
||||
/* lie about the result */
|
||||
return count;
|
||||
case 2:
|
||||
/* after this, reset to normal */
|
||||
test_ordering_cycle = 0;
|
||||
test_ordering_phase = 0;
|
||||
/* send the new packet first */
|
||||
stat = write(fd, buf, count);
|
||||
if ((size_t)stat != count) return stat;
|
||||
/* send the buffered packets in normal order */
|
||||
for (n=0; n<test_length; n++) {
|
||||
stat = write(fd, pocket_buf[n], pocket_count[n]);
|
||||
/* ignores failures */
|
||||
free(pocket_buf[n]);
|
||||
}
|
||||
log("test order retransmit, packets sent");
|
||||
return count;
|
||||
default:
|
||||
return write(fd, buf, count);
|
||||
}
|
||||
}
|
||||
|
||||
/* hold ten packets and send them in reverse order */
|
||||
static ssize_t write_reordered_reverse(int fd, const void *buf, size_t count)
|
||||
{
|
||||
int test_length = 10;
|
||||
static void *pocket_buf[10];
|
||||
static int pocket_count[10];
|
||||
int stat, n;
|
||||
|
||||
switch (test_ordering_phase) {
|
||||
case 0: /* between triggers, send as normal */
|
||||
test_ordering_cycle++;
|
||||
if (test_ordering_cycle == test_rate) test_ordering_phase++;
|
||||
return write(fd, buf, count);
|
||||
case 1: /* triggered, buffer the packets */
|
||||
test_ordering_cycle++;
|
||||
if (test_ordering_cycle == (test_rate+test_length)) {
|
||||
test_ordering_phase = 2;
|
||||
}
|
||||
/* pocket the packet */
|
||||
n = test_ordering_cycle - test_rate - 1;
|
||||
pocket_count[n] = count;
|
||||
pocket_buf[n] = malloc(count);
|
||||
memcpy(pocket_buf[n], buf, count);
|
||||
log("test order reverse, packet buffered");
|
||||
/* lie about the result */
|
||||
return count;
|
||||
case 2:
|
||||
/* after this, reset to normal */
|
||||
test_ordering_cycle = 0;
|
||||
test_ordering_phase = 0;
|
||||
/* send the new packet first */
|
||||
stat = write(fd, buf, count);
|
||||
if ((size_t)stat != count) return stat;
|
||||
/* send the buffered packets in reverse order */
|
||||
for (n=test_length-1; n>0; n--) {
|
||||
stat = write(fd, pocket_buf[n], pocket_count[n]);
|
||||
/* ignores failures */
|
||||
free(pocket_buf[n]);
|
||||
}
|
||||
log("test order reverse, packets sent");
|
||||
return count;
|
||||
default:
|
||||
return write(fd, buf, count);
|
||||
}
|
||||
}
|
||||
|
||||
/* dispatcher for write reordering tests */
|
||||
static ssize_t write_reordered(int fd, const void *buf, size_t count)
|
||||
{
|
||||
switch (test_type) {
|
||||
case 1: /* swap a packet every now and then */
|
||||
return write_reordered_swap(fd, buf, count);
|
||||
case 2: /* hold ten packets and send the eleventh, then the ten in order */
|
||||
return write_reordered_retransmit(fd, buf, count);
|
||||
case 3: /* hold ten packets and send them in reverse order */
|
||||
return write_reordered_reverse(fd, buf, count);
|
||||
default:
|
||||
return write(fd, buf, count);
|
||||
}
|
||||
}
|
||||
|
||||
struct test_redirections *test_redirections(void)
|
||||
{
|
||||
static struct test_redirections *my = NULL;
|
||||
|
||||
if (my == NULL) my = malloc(sizeof(struct test_redirections));
|
||||
|
||||
my->write = write;
|
||||
if (test_type) my->write = write_reordered;
|
||||
|
||||
return my;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
struct test_redirections {
|
||||
ssize_t (*write)(int fd, const void *buf, size_t count);
|
||||
};
|
||||
|
||||
struct test_redirections *test_redirections(void);
|
|
@ -0,0 +1,154 @@
|
|||
/* util.c ....... error message utilities.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: util.c,v 1.13 2011/12/19 07:15:03 quozl Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "util.h"
|
||||
|
||||
#ifndef PROGRAM_NAME
|
||||
#define PROGRAM_NAME "pptp"
|
||||
#endif
|
||||
|
||||
/* implementation of log_string, defined as extern in util.h */
|
||||
const char *log_string = "anon";
|
||||
|
||||
static void open_log(void) __attribute__ ((constructor));
|
||||
static void close_log(void) __attribute__ ((destructor));
|
||||
|
||||
#define MAKE_STRING(label) \
|
||||
va_list ap; \
|
||||
char buf[256], string[256]; \
|
||||
va_start(ap, format); \
|
||||
vsnprintf(buf, sizeof(buf), format, ap); \
|
||||
snprintf(string, sizeof(string), "%s %s[%s:%s:%d]: %s", \
|
||||
log_string, label, func, file, line, buf); \
|
||||
va_end(ap)
|
||||
|
||||
/*** open log *****************************************************************/
|
||||
static void open_log(void) {
|
||||
openlog(PROGRAM_NAME, LOG_PID, LOG_DAEMON);
|
||||
}
|
||||
|
||||
/*** close log ****************************************************************/
|
||||
static void close_log(void)
|
||||
{
|
||||
closelog();
|
||||
}
|
||||
|
||||
/*** print a message to syslog ************************************************/
|
||||
void _log(const char *func, const char *file, int line, const char *format, ...)
|
||||
{
|
||||
MAKE_STRING("log");
|
||||
syslog(LOG_NOTICE, "%s", string);
|
||||
}
|
||||
|
||||
/*** print a warning to syslog ************************************************/
|
||||
void _warn(const char *func, const char *file, int line, const char *format, ...)
|
||||
{
|
||||
MAKE_STRING("warn");
|
||||
fprintf(stderr, "%s\n", string);
|
||||
syslog(LOG_WARNING, "%s", string);
|
||||
}
|
||||
|
||||
/*** print a fatal warning to syslog and exit *********************************/
|
||||
void _fatal(const char *func, const char *file, int line, const char *format, ...)
|
||||
{
|
||||
MAKE_STRING("fatal");
|
||||
fprintf(stderr, "%s\n", string);
|
||||
syslog(LOG_CRIT, "%s", string);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*** connect a file to a file descriptor **************************************/
|
||||
int file2fd(const char *path, const char *mode, int fd)
|
||||
{
|
||||
int ok = 0;
|
||||
FILE *file = NULL;
|
||||
file = fopen(path, mode);
|
||||
if (file != NULL && dup2(fileno(file), fd) != -1)
|
||||
ok = 1;
|
||||
if (file) fclose(file);
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* signal to pipe delivery implementation */
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
/* pipe private to process */
|
||||
static int sigpipe[2];
|
||||
|
||||
/* create a signal pipe, returns 0 for success, -1 with errno for failure */
|
||||
int sigpipe_create(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = pipe(sigpipe);
|
||||
if (rc < 0) return rc;
|
||||
|
||||
fcntl(sigpipe[0], F_SETFD, FD_CLOEXEC);
|
||||
fcntl(sigpipe[1], F_SETFD, FD_CLOEXEC);
|
||||
|
||||
#ifdef O_NONBLOCK
|
||||
#define FLAG_TO_SET O_NONBLOCK
|
||||
#else
|
||||
#ifdef SYSV
|
||||
#define FLAG_TO_SET O_NDELAY
|
||||
#else /* BSD */
|
||||
#define FLAG_TO_SET FNDELAY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
rc = fcntl(sigpipe[1], F_GETFL);
|
||||
if (rc != -1)
|
||||
rc = fcntl(sigpipe[1], F_SETFL, rc | FLAG_TO_SET);
|
||||
if (rc < 0) return rc;
|
||||
return 0;
|
||||
#undef FLAG_TO_SET
|
||||
}
|
||||
|
||||
/* generic handler for signals, writes signal number to pipe */
|
||||
void sigpipe_handler(int signum)
|
||||
{
|
||||
write(sigpipe[1], &signum, sizeof(signum));
|
||||
signal(signum, sigpipe_handler);
|
||||
}
|
||||
|
||||
/* assign a signal number to the pipe */
|
||||
void sigpipe_assign(int signum)
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = sigpipe_handler;
|
||||
sigaction(signum, &sa, NULL);
|
||||
}
|
||||
|
||||
/* return the signal pipe read file descriptor for select(2) */
|
||||
int sigpipe_fd(void)
|
||||
{
|
||||
return sigpipe[0];
|
||||
}
|
||||
|
||||
/* read and return the pending signal from the pipe */
|
||||
int sigpipe_read(void)
|
||||
{
|
||||
int signum;
|
||||
read(sigpipe[0], &signum, sizeof(signum));
|
||||
return signum;
|
||||
}
|
||||
|
||||
void sigpipe_close(void)
|
||||
{
|
||||
close(sigpipe[0]);
|
||||
close(sigpipe[1]);
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/* util.h ....... error message utilities.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: util.h,v 1.8 2011/12/19 07:15:03 quozl Exp $
|
||||
*/
|
||||
|
||||
#ifndef INC_UTIL_H
|
||||
#define INC_UTIL_H
|
||||
|
||||
/* log_string is an identifier for this pptp process, passed from
|
||||
command line using --log-string=X, and included with every log message.
|
||||
Useful for people with multiple pptp sessions open at a time */
|
||||
extern const char * log_string;
|
||||
|
||||
/* log_level sets the logging verbosity. Values range from 0 (errors only)
|
||||
to 1 (errors and warnings) to 2 (high verbosity, for debugging) */
|
||||
extern int log_level;
|
||||
|
||||
void _log(const char *func, const char *file, int line, const char *format, ...)
|
||||
__attribute__ ((format (printf, 4, 5)));
|
||||
void _warn(const char *func, const char *file, int line, const char *format, ...)
|
||||
__attribute__ ((format (printf, 4, 5)));
|
||||
void _fatal(const char *func, const char *file, int line, const char *format, ...)
|
||||
__attribute__ ((format (printf, 4, 5))) __attribute__ ((noreturn));
|
||||
|
||||
#define log(format, args...) \
|
||||
_log(__FUNCTION__,__FILE__,__LINE__, format , ## args)
|
||||
#define warn(format, args...) \
|
||||
_warn(__FUNCTION__,__FILE__,__LINE__, format , ## args)
|
||||
#define fatal(format, args...) \
|
||||
_fatal(__FUNCTION__,__FILE__,__LINE__, format , ## args)
|
||||
|
||||
int file2fd(const char *path, const char *mode, int fd);
|
||||
|
||||
/* signal to pipe delivery implementation */
|
||||
|
||||
/* create a signal pipe, returns 0 for success, -1 with errno for failure */
|
||||
int sigpipe_create(void);
|
||||
|
||||
/* generic handler for signals, writes signal number to pipe */
|
||||
void sigpipe_handler(int signum);
|
||||
|
||||
/* assign a signal number to the pipe */
|
||||
void sigpipe_assign(int signum);
|
||||
|
||||
/* return the signal pipe read file descriptor for select(2) */
|
||||
int sigpipe_fd(void);
|
||||
|
||||
/* read and return the pending signal from the pipe */
|
||||
int sigpipe_read(void);
|
||||
|
||||
void sigpipe_close(void);
|
||||
|
||||
#endif /* INC_UTIL_H */
|
|
@ -0,0 +1,209 @@
|
|||
/* vector.c ..... store a vector of PPTP_CALL information and search it
|
||||
* efficiently.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: vector.c,v 1.4 2011/12/19 07:15:03 quozl Exp $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "pptp_ctrl.h"
|
||||
#include "vector.h"
|
||||
/* #define VECTOR_DEBUG */
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
struct vector_item {
|
||||
int key;
|
||||
PPTP_CALL *call;
|
||||
};
|
||||
|
||||
struct vector_struct {
|
||||
struct vector_item *item;
|
||||
int size;
|
||||
int alloc;
|
||||
#ifdef VECTOR_DEBUG
|
||||
int key_max;
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct vector_item *binary_search(VECTOR *v, int key);
|
||||
|
||||
/*** vector_create ************************************************************/
|
||||
VECTOR *vector_create(void)
|
||||
{
|
||||
const int INITIAL_SIZE = 4;
|
||||
|
||||
VECTOR *v = malloc(sizeof(*v));
|
||||
if (v == NULL) return v;
|
||||
|
||||
v->size = 0;
|
||||
v->alloc = INITIAL_SIZE;
|
||||
v->item = malloc(sizeof(*(v->item)) * (v->alloc));
|
||||
#ifdef VECTOR_DEBUG
|
||||
v->key_max = -1;
|
||||
#endif
|
||||
if (v->item == NULL) { free(v); return NULL; }
|
||||
else return v;
|
||||
}
|
||||
|
||||
/*** vector_destroy ***********************************************************/
|
||||
void vector_destroy(VECTOR *v)
|
||||
{
|
||||
free(v->item);
|
||||
#ifdef VECTOR_DEBUG
|
||||
v->item = NULL;
|
||||
#endif
|
||||
free(v);
|
||||
}
|
||||
|
||||
/*** vector_size **************************************************************/
|
||||
int vector_size(VECTOR *v)
|
||||
{
|
||||
assert(v != NULL);
|
||||
return v->size;
|
||||
}
|
||||
|
||||
/*** vector_insert*************************************************************
|
||||
* nice thing about file descriptors is that we are assured by POSIX
|
||||
* that they are monotonically increasing.
|
||||
*/
|
||||
int vector_insert(VECTOR *v, int key, PPTP_CALL * call)
|
||||
{
|
||||
int i;
|
||||
assert(v != NULL && call != NULL);
|
||||
assert(!vector_contains(v, key));
|
||||
#ifdef VECTOR_DEBUG
|
||||
assert(v->key_max < key);
|
||||
#endif
|
||||
if (!(v->size < v->alloc)) {
|
||||
void *tmp = realloc(v->item, sizeof(*(v->item)) * 2 * v->alloc);
|
||||
if (tmp != NULL) {
|
||||
v->alloc *= 2;
|
||||
v->item = tmp;
|
||||
} else return FALSE; /* failed to alloc memory. */
|
||||
}
|
||||
assert(v->size < v->alloc);
|
||||
/* for safety, we make this work in the general case;
|
||||
* but this is optimized for adding call to the end of the vector.
|
||||
*/
|
||||
for(i = v->size - 1; i >= 0; i--)
|
||||
if (v->item[i].key < key)
|
||||
break;
|
||||
/* insert after item i */
|
||||
memmove(&v->item[i + 2], &v->item[i + 1],
|
||||
(v->size - i - 1) * sizeof(*(v->item)));
|
||||
v->item[i + 1].key = key;
|
||||
v->item[i + 1].call = call;
|
||||
v->size++;
|
||||
#ifdef VECTOR_DEBUG
|
||||
if (v->key_max < key) /* ie, always. */
|
||||
v->key_max = key;
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*** vector_remove ************************************************************/
|
||||
int vector_remove(VECTOR *v, int key)
|
||||
{
|
||||
struct vector_item *tmp;
|
||||
assert(v != NULL);
|
||||
if ((tmp =binary_search(v,key)) == NULL) return FALSE;
|
||||
assert(tmp >= v->item && tmp < v->item + v->size);
|
||||
memmove(tmp, tmp + 1, (v->size - (tmp - v->item) - 1) * sizeof(*(v->item)));
|
||||
v->size--;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*** vector_search ************************************************************/
|
||||
int vector_search(VECTOR *v, int key, PPTP_CALL **call)
|
||||
{
|
||||
struct vector_item *tmp;
|
||||
assert(v != NULL);
|
||||
tmp = binary_search(v, key);
|
||||
if (tmp ==NULL) return FALSE;
|
||||
*call = tmp->call;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*** vector_contains **********************************************************/
|
||||
int vector_contains(VECTOR *v, int key)
|
||||
{
|
||||
assert(v != NULL);
|
||||
return (binary_search(v, key) != NULL);
|
||||
}
|
||||
|
||||
/*** vector_item **************************************************************/
|
||||
static struct vector_item *binary_search(VECTOR *v, int key)
|
||||
{
|
||||
int l,r,x;
|
||||
l = 0;
|
||||
r = v->size - 1;
|
||||
while (r >= l) {
|
||||
x = (l + r)/2;
|
||||
if (key < v->item[x].key) r = x - 1; else l = x + 1;
|
||||
if (key == v->item[x].key) return &(v->item[x]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*** vector_scan ***************************************************************
|
||||
* Hmm. Let's be fancy and use a binary search for the first
|
||||
* unused key, taking advantage of the list is stored sorted; ie
|
||||
* we can look at pointers and keys at two different locations,
|
||||
* and if (ptr1 - ptr2) = (key1 - key2) then all the slots
|
||||
* between ptr1 and ptr2 are filled. Note that ptr1-ptr2 should
|
||||
* never be greater than key1-key2 (no duplicate keys!)... we
|
||||
* check for this.
|
||||
*/
|
||||
int vector_scan(VECTOR *v, int lo, int hi, int *key)
|
||||
{
|
||||
int l,r,x;
|
||||
assert(v != NULL);
|
||||
assert(key != NULL);
|
||||
if ((v->size<1) || (lo < v->item[0].key)) { *key = lo; return TRUE; }
|
||||
/* our array bounds */
|
||||
l = 0; r = v->size - 1;
|
||||
while (r > l) {
|
||||
/* check for a free spot right after l */
|
||||
if (v->item[l].key + 1 < v->item[l + 1].key) { /* found it! */
|
||||
*key = v->item[l].key + 1;
|
||||
return TRUE;
|
||||
}
|
||||
/* no dice. Let's see if the free spot is before or after the midpoint */
|
||||
x = (l + r)/2;
|
||||
/* Okay, we have right (r), left (l) and the probe (x). */
|
||||
assert(x - l <= v->item[x].key - v->item[l].key);
|
||||
assert(r - x <= v->item[r].key - v->item[x].key);
|
||||
if (x - l < v->item[x].key - v->item[l].key)
|
||||
/* room between l and x */
|
||||
r = x;
|
||||
else /* no room between l and x */
|
||||
if (r - x < v->item[r].key - v->item[x].key)
|
||||
/* room between x and r */
|
||||
l = x;
|
||||
else /* no room between x and r, either */
|
||||
break; /* game over, man. */
|
||||
}
|
||||
/* no room found in already allocated space. Check to see if
|
||||
* there's free space above allocated entries. */
|
||||
if (v->item[v->size - 1].key < hi) {
|
||||
*key = v->item[v->size - 1].key + 1;
|
||||
return TRUE;
|
||||
}
|
||||
/* outta luck */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*** vector_get_Nth ***********************************************************/
|
||||
PPTP_CALL * vector_get_Nth(VECTOR *v, int n)
|
||||
{
|
||||
assert(v != NULL);
|
||||
assert(0 <= n && n < vector_size(v));
|
||||
return v->item[n].call;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/* vector.h ..... store a vector of PPTP_CALL information and search it
|
||||
* efficiently.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: vector.h,v 1.2 2011/12/19 07:15:03 quozl Exp $
|
||||
*/
|
||||
|
||||
#ifndef INC_VECTOR_H
|
||||
#define INC_VECTOR_H
|
||||
|
||||
#include "pptp_ctrl.h" /* for definition of PPTP_CALL */
|
||||
|
||||
typedef struct vector_struct VECTOR;
|
||||
|
||||
VECTOR *vector_create(void);
|
||||
void vector_destroy(VECTOR *v);
|
||||
|
||||
int vector_size(VECTOR *v);
|
||||
|
||||
/* vector_insert and vector_search return TRUE on success, FALSE on failure. */
|
||||
int vector_insert(VECTOR *v, int key, PPTP_CALL * call);
|
||||
int vector_remove(VECTOR *v, int key);
|
||||
int vector_search(VECTOR *v, int key, PPTP_CALL ** call);
|
||||
/* vector_contains returns FALSE if not found, TRUE if found. */
|
||||
int vector_contains(VECTOR *v, int key);
|
||||
/* find first unused key. Returns TRUE on success, FALSE if no. */
|
||||
int vector_scan(VECTOR *v, int lo, int hi, int *key);
|
||||
/* get a specific PPTP_CALL ... useful only when iterating. */
|
||||
PPTP_CALL * vector_get_Nth(VECTOR *v, int n);
|
||||
|
||||
#endif /* INC_VECTOR_H */
|
|
@ -0,0 +1,99 @@
|
|||
/* vector_test.c .... Test the vector package.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: vector_test.c,v 1.2 2003/06/17 17:25:47 reink Exp $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "vector.h"
|
||||
|
||||
#define MAX 25
|
||||
|
||||
void main(void) {
|
||||
int i, j, *d, retval;
|
||||
|
||||
VECTOR *v = vector_create();
|
||||
assert(v != NULL);
|
||||
assert(vector_size(v)==0);
|
||||
for (i=0; i<=MAX; i++) {
|
||||
assert(!vector_contains(v, i));
|
||||
assert(!vector_remove(v, i));
|
||||
assert(!vector_search(v, i, (PPTP_CALL **)&j));
|
||||
retval = vector_scan(v, i, MAX*2, &j);
|
||||
assert(retval);
|
||||
assert(j==i);
|
||||
}
|
||||
|
||||
for (i=1; i<=MAX; i++) {
|
||||
d = malloc(sizeof(int));
|
||||
*d = i;
|
||||
retval = vector_insert(v, i, (PPTP_CALL *)d);
|
||||
assert(retval);
|
||||
assert(vector_size(v)==i);
|
||||
}
|
||||
for (i=1; i<MAX; i++) {
|
||||
retval = vector_search(v, i, (PPTP_CALL **)&d);
|
||||
assert(retval);
|
||||
assert(*d==i);
|
||||
retval = vector_contains(v, i);
|
||||
assert(retval);
|
||||
}
|
||||
assert(vector_size(v)==MAX);
|
||||
retval = vector_contains(v, MAX+1);
|
||||
assert(!retval);
|
||||
retval = vector_search(v, MAX+1, (PPTP_CALL **)&j);
|
||||
assert(!retval);
|
||||
|
||||
retval = vector_scan(v, 0, MAX, &j);
|
||||
assert(retval);
|
||||
assert(j==0);
|
||||
retval = vector_scan(v, 1, MAX, &j);
|
||||
assert(!retval);
|
||||
retval = vector_scan(v, 1, MAX+1, &j);
|
||||
assert(retval);
|
||||
assert(j==MAX+1);
|
||||
retval = vector_scan(v, 1, MAX+MAX, &j);
|
||||
assert(retval);
|
||||
assert(j==MAX+1);
|
||||
|
||||
for (i=0; i<(MAX*10); i++) {
|
||||
int k = (random() % MAX) + 1;
|
||||
assert(vector_contains(v, k));
|
||||
assert(!vector_scan(v, 1, k, &j));
|
||||
assert(!vector_scan(v, k, MAX, &j));
|
||||
retval = vector_remove(v, k);
|
||||
assert(retval);
|
||||
assert(vector_size(v)==MAX-1);
|
||||
assert(!vector_contains(v, k));
|
||||
assert(!vector_search(v, k, (PPTP_CALL **) &j));
|
||||
retval = vector_scan(v, 1, MAX, &j);
|
||||
assert(retval);
|
||||
assert(j==k);
|
||||
d = malloc(sizeof(int));
|
||||
*d = k;
|
||||
retval = vector_insert(v, k, (PPTP_CALL *) d);
|
||||
assert(retval);
|
||||
assert(vector_size(v)==MAX);
|
||||
assert(vector_contains(v, k));
|
||||
assert(!vector_scan(v, 1, MAX, &j));
|
||||
retval = vector_search(v, k, (PPTP_CALL **) &d);
|
||||
assert(retval);
|
||||
assert(*d==k);
|
||||
}
|
||||
|
||||
for (i=1; i<=MAX; i++) {
|
||||
assert(vector_size(v)==MAX-(i-1));
|
||||
vector_remove(v, i);
|
||||
assert(vector_size(v)==MAX-i);
|
||||
assert(!vector_contains(v, i));
|
||||
retval = vector_search(v, i, (PPTP_CALL **) &j);
|
||||
assert(!retval);
|
||||
retval = vector_scan(v, 1, MAX, &j);
|
||||
assert(retval);
|
||||
assert(j==1);
|
||||
}
|
||||
assert(vector_size(v)==0);
|
||||
vector_destroy(v);
|
||||
exit(0);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
/* version.c ..... keep track of package version number.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: version.c,v 1.3 2004/06/22 09:52:26 quozl Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
const char * version = "pptp version " PPTP_LINUX_VERSION;
|
|
@ -0,0 +1,10 @@
|
|||
/* version.h ..... keep track of package version number.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu>
|
||||
*
|
||||
* $Id: version.h,v 1.1 2000/12/23 08:19:51 scott Exp $
|
||||
*/
|
||||
|
||||
#ifndef INC_VERSION_H
|
||||
#define INC_VERSION_H
|
||||
extern const char * version;
|
||||
#endif /* INC_VERSION_H */
|
Loading…
Reference in New Issue