- Revise CCP, send ConfigReq once only.
- Check control serial before clearing window, prevents looping tunnel setup in some instances. - Add configuration syntax for adding named access lists (work in progress).
This commit is contained in:
parent
98e9766a66
commit
12f16f60c1
9 changed files with 920 additions and 94 deletions
5
Changes
5
Changes
|
|
@ -1,8 +1,11 @@
|
||||||
* Thu Nov 25 2004 Brendan O'Dea <bod@optusnet.com.au> 2.0.9
|
* Sat Nov 27 2004 Brendan O'Dea <bod@optusnet.com.au> 2.0.9
|
||||||
- Revise CCP, send ConfigReq once only.
|
- Revise CCP, send ConfigReq once only.
|
||||||
- Don't copy the old buffer into Config{Nak,Rej} LCP responses (oops);
|
- Don't copy the old buffer into Config{Nak,Rej} LCP responses (oops);
|
||||||
add length checks when appending.
|
add length checks when appending.
|
||||||
- Have makeppp print a backtrace on overflow.
|
- Have makeppp print a backtrace on overflow.
|
||||||
|
- Check control serial before clearing window, prevents looping tunnel
|
||||||
|
setup in some instances.
|
||||||
|
- Add configuration syntax for adding named access lists (work in progress).
|
||||||
|
|
||||||
* Sat Nov 20 2004 Brendan O'Dea <bod@optusnet.com.au> 2.0.8
|
* Sat Nov 20 2004 Brendan O'Dea <bod@optusnet.com.au> 2.0.8
|
||||||
- Ignore gateway address in Framed-Route (from Jonathan McDowell).
|
- Ignore gateway address in Framed-Route (from Jonathan McDowell).
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ H3 {
|
||||||
<LI><A HREF="#Authentication">Authentication</A></LI>
|
<LI><A HREF="#Authentication">Authentication</A></LI>
|
||||||
<LI><A HREF="#Plugins">Plugins</A></LI>
|
<LI><A HREF="#Plugins">Plugins</A></LI>
|
||||||
<LI><A HREF="#WalledGarden">Walled Garden</A></LI>
|
<LI><A HREF="#WalledGarden">Walled Garden</A></LI>
|
||||||
|
<LI><A HREF="#Filtering">Filtering</A></LI>
|
||||||
<LI><A HREF="#Clustering">Clustering</A></LI>
|
<LI><A HREF="#Clustering">Clustering</A></LI>
|
||||||
<LI><A HREF="#Routing">Routing</A></LI>
|
<LI><A HREF="#Routing">Routing</A></LI>
|
||||||
<LI><A HREF="#Performance">Performance</A></LI>
|
<LI><A HREF="#Performance">Performance</A></LI>
|
||||||
|
|
@ -200,29 +201,34 @@ software upgrade.
|
||||||
|
|
||||||
<LI><B>primary_radius</B> (ip address)
|
<LI><B>primary_radius</B> (ip address)
|
||||||
<LI><B>secondary_radius</B> (ip address)<BR>
|
<LI><B>secondary_radius</B> (ip address)<BR>
|
||||||
Sets the radius servers used for both authentication and accounting.
|
Sets the RADIUS servers used for both authentication and accounting.
|
||||||
If the primary server does not respond, then the secondary radius
|
If the primary server does not respond, then the secondary RADIUS
|
||||||
server will be tried.
|
server will be tried.<br>
|
||||||
|
<strong>Note:</strong> in addition to the source IP address and
|
||||||
|
identifier, the RADIUS server <strong>must</strong> include the source
|
||||||
|
port when detecting duplicates to supress (in order to cope with a
|
||||||
|
large number of sessions comming on-line simultaneously l2tpns uses a
|
||||||
|
set of udp sockets, each with a seperate identifier).
|
||||||
</LI>
|
</LI>
|
||||||
|
|
||||||
<LI><B>primary_radius_port</B> (short)
|
<LI><B>primary_radius_port</B> (short)
|
||||||
<LI><B>secondary_radius_port</B> (short)<BR>
|
<LI><B>secondary_radius_port</B> (short)<BR>
|
||||||
Sets the authentication ports for the primary and secondary radius
|
Sets the authentication ports for the primary and secondary RADIUS
|
||||||
servers. The accounting port is one more than the authentication
|
servers. The accounting port is one more than the authentication
|
||||||
port. If no radius ports are given, the authentication port defaults
|
port. If no RADIUS ports are given, the authentication port defaults
|
||||||
to 1645, and the accounting port to 1646.
|
to 1645, and the accounting port to 1646.
|
||||||
</LI>
|
</LI>
|
||||||
|
|
||||||
<LI><B>radius_accounting</B> (boolean)<BR>
|
<LI><B>radius_accounting</B> (boolean)<BR>
|
||||||
If set to true, then radius accounting packets will be sent. This
|
If set to true, then RADIUS accounting packets will be sent. This
|
||||||
means that a Start record will be sent when the session is
|
means that a Start record will be sent when the session is
|
||||||
successfully authenticated, and a Stop record will be sent when the
|
successfully authenticated, and a Stop record will be sent when the
|
||||||
session is closed.
|
session is closed.
|
||||||
</LI>
|
</LI>
|
||||||
|
|
||||||
<LI><B>radius_secret</B> (string)<BR>
|
<LI><B>radius_secret</B> (string)<BR>
|
||||||
This secret will be used in all radius queries. If this is not set then
|
This secret will be used in all RADIUS queries. If this is not set then
|
||||||
radius queries will fail.
|
RADIUS queries will fail.
|
||||||
</LI>
|
</LI>
|
||||||
|
|
||||||
<LI><B>bind_address</B> (ip address)<BR>
|
<LI><B>bind_address</B> (ip address)<BR>
|
||||||
|
|
@ -338,6 +344,40 @@ Where <I>peer</I> specifies the BGP neighbour as either a hostname or
|
||||||
IP address, <I>as</I> is the remote AS number and <I>keepalive</I>,
|
IP address, <I>as</I> is the remote AS number and <I>keepalive</I>,
|
||||||
<I>hold</I> are the timer values in seconds.
|
<I>hold</I> are the timer values in seconds.
|
||||||
|
|
||||||
|
<P>Named access-lists are configured using one of the commands:
|
||||||
|
<DL>
|
||||||
|
<DD><B>ip access-list standard</B> <I>name</I>
|
||||||
|
<DD><B>ip access-list extended</B> <I>name</I>
|
||||||
|
</DL>
|
||||||
|
|
||||||
|
<P>Subsequent lines prefixed with <B>permit</B> or <B>deny</B>
|
||||||
|
define the body of the access-list. Standard access-list syntax:
|
||||||
|
<DL>
|
||||||
|
<DD>{<B>permit</B>|<B>deny</B>}
|
||||||
|
{<I>host</I>|<I>source source-wildcard</I>|<B>any</B>}
|
||||||
|
[{<I>host</I>|<I>destination destination-wildcard</I>|<B>any</B>}]
|
||||||
|
</DL>
|
||||||
|
|
||||||
|
Extended access-lists:
|
||||||
|
|
||||||
|
<DL>
|
||||||
|
<DD>{<B>permit</B>|<B>deny</B>} <B>ip</B>
|
||||||
|
{<I>host</I>|<I>source source-wildcard</I>|<B>any</B>}
|
||||||
|
{<I>host</I>|<I>destination destination-wildcard</I>|<B>any</B>}
|
||||||
|
<DD>{<B>permit</B>|<B>deny</B>} <B>udp</B>
|
||||||
|
{<I>host</I>|<I>source source-wildcard</I>|<B>any</B>}
|
||||||
|
[{<B>eq</B>|<B>neq</B>|<B>gt</B>|<B>lt</B>} <I>port</I>|<B>range</B> <I>from</I> <I>to</I>]
|
||||||
|
{<I>host</I>|<I>destination destination-wildcard</I>|<B>any</B>}
|
||||||
|
[{<B>eq</B>|<B>neq</B>|<B>gt</B>|<B>lt</B>} <I>port</I>|<B>range</B> <I>from</I> <I>to</I>]
|
||||||
|
<DD>{<B>permit</B>|<B>deny</B>} <B>tcp</B>
|
||||||
|
{<I>host</I>|<I>source source-wildcard</I>|<B>any</B>}
|
||||||
|
[{<B>eq</B>|<B>neq</B>|<B>gt</B>|<B>lt</B>} <I>port</I>|<B>range</B> <I>from</I> <I>to</I>]
|
||||||
|
{<I>host</I>|<I>destination destination-wildcard</I>|<B>any</B>}
|
||||||
|
[{<B>eq</B>|<B>neq</B>|<B>gt</B>|<B>lt</B>} <I>port</I>|<B>range</B> <I>from</I> <I>to</I>]
|
||||||
|
[{<B>established</B>|{<B>match-any</B>|<B>match-all</B>}
|
||||||
|
{<B>+</B>|<B>-</B>}{<B>fin</B>|<B>syn</B>|<B>rst</B>|<B>psh</B>|<B>ack</B>|<B>urg</B>} ...]
|
||||||
|
</DL>
|
||||||
|
|
||||||
<H3 ID="users">users</H3>
|
<H3 ID="users">users</H3>
|
||||||
|
|
||||||
Usernames and passwords for the command-line interface are stored in
|
Usernames and passwords for the command-line interface are stored in
|
||||||
|
|
@ -500,19 +540,19 @@ IP Address Used Session User
|
||||||
</LI>
|
</LI>
|
||||||
|
|
||||||
<LI><B>show radius</B><BR>
|
<LI><B>show radius</B><BR>
|
||||||
Show a summary of the in-use radius sessions. This list should not be very
|
Show a summary of the in-use RADIUS sessions. This list should not be very
|
||||||
long, as radius sessions should be cleaned up as soon as they are used. The
|
long, as RADIUS sessions should be cleaned up as soon as they are used. The
|
||||||
columns listed are:
|
columns listed are:
|
||||||
<TABLE>
|
<TABLE>
|
||||||
<TR><TD><B>Radius</B></TD><TD>The ID of the radius request. This is
|
<TR><TD><B>Radius</B></TD><TD>The ID of the RADIUS request. This is
|
||||||
sent in the packet to the radius server for identification.</TD></TR>
|
sent in the packet to the RADIUS server for identification.</TD></TR>
|
||||||
<TR><TD><B>State</B></TD><TD>The state of the request - WAIT, CHAP,
|
<TR><TD><B>State</B></TD><TD>The state of the request - WAIT, CHAP,
|
||||||
AUTH, IPCP, START, STOP, NULL.</TD></TR>
|
AUTH, IPCP, START, STOP, NULL.</TD></TR>
|
||||||
<TR><TD><B>Session</B></TD><TD>The session ID that this radius
|
<TR><TD><B>Session</B></TD><TD>The session ID that this RADIUS
|
||||||
request is associated with</TD></TR>
|
request is associated with</TD></TR>
|
||||||
<TR><TD><B>Retry</B></TD><TD>If a response does not appear to the
|
<TR><TD><B>Retry</B></TD><TD>If a response does not appear to the
|
||||||
request, it will retry at this time. This is a unix timestamp.</TD></TR>
|
request, it will retry at this time. This is a unix timestamp.</TD></TR>
|
||||||
<TR><TD><B>Try</B></TD><TD>Retry count. The radius request is
|
<TR><TD><B>Try</B></TD><TD>Retry count. The RADIUS request is
|
||||||
discarded after 3 retries.</TD></TR>
|
discarded after 3 retries.</TD></TR>
|
||||||
</TABLE>
|
</TABLE>
|
||||||
<P>
|
<P>
|
||||||
|
|
@ -553,7 +593,7 @@ current session for that username will be forwarded to the given
|
||||||
host/port. Specify <EM>no snoop username</EM> to disable interception
|
host/port. Specify <EM>no snoop username</EM> to disable interception
|
||||||
for the session.<P>
|
for the session.<P>
|
||||||
|
|
||||||
If you want interception to be permanent, you will have to modify the radius
|
If you want interception to be permanent, you will have to modify the RADIUS
|
||||||
response for the user. See <A HREF="#Interception">Interception</A>.
|
response for the user. See <A HREF="#Interception">Interception</A>.
|
||||||
<P>
|
<P>
|
||||||
</LI>
|
</LI>
|
||||||
|
|
@ -564,7 +604,7 @@ session. Specify <EM>no throttle username</EM> to disable throttling
|
||||||
for the current session.<P>
|
for the current session.<P>
|
||||||
|
|
||||||
If you want throttling to be permanent, you will have to modify the
|
If you want throttling to be permanent, you will have to modify the
|
||||||
radius response for the user. See <A HREF="#THrottling">Throttling</A>.
|
RADIUS response for the user. See <A HREF="#Throttling">Throttling</A>.
|
||||||
<P>
|
<P>
|
||||||
</LI>
|
</LI>
|
||||||
|
|
||||||
|
|
@ -660,7 +700,7 @@ desire. You must first enable the global setting <EM>throttle_speed</EM>
|
||||||
before this will be activated.<P>
|
before this will be activated.<P>
|
||||||
|
|
||||||
If you wish a session to be throttled permanently, you should set the
|
If you wish a session to be throttled permanently, you should set the
|
||||||
Vendor-Specific radius value <B>Cisco-Avpair="throttle=yes"</B>, which
|
Vendor-Specific RADIUS value <B>Cisco-Avpair="throttle=yes"</B>, which
|
||||||
will be handled by the <EM>autothrottle</EM> module.<P>
|
will be handled by the <EM>autothrottle</EM> module.<P>
|
||||||
|
|
||||||
Otherwise, you can enable and disable throttling an active session using
|
Otherwise, you can enable and disable throttling an active session using
|
||||||
|
|
@ -684,7 +724,7 @@ and <EM>no snoop username</EM> CLI commands. These will enable interception
|
||||||
immediately.<P>
|
immediately.<P>
|
||||||
|
|
||||||
If you wish the user to be intercepted whenever they reconnect, you will
|
If you wish the user to be intercepted whenever they reconnect, you will
|
||||||
need to modify the radius response to include the Vendor-Specific value
|
need to modify the RADIUS response to include the Vendor-Specific value
|
||||||
<B>Cisco-Avpair="intercept=yes"</B>. For this feature to be enabled,
|
<B>Cisco-Avpair="intercept=yes"</B>. For this feature to be enabled,
|
||||||
you need to have the <EM>autosnoop</EM> module loaded.<P>
|
you need to have the <EM>autosnoop</EM> module loaded.<P>
|
||||||
|
|
||||||
|
|
@ -694,11 +734,11 @@ Whenever a session connects, it is not fully set up until authentication is
|
||||||
completed. The remote end must send a PPP CHAP or PPP PAP authentication
|
completed. The remote end must send a PPP CHAP or PPP PAP authentication
|
||||||
request to l2tpns.<P>
|
request to l2tpns.<P>
|
||||||
|
|
||||||
This request is sent to the radius server, which will hopefully respond with
|
This request is sent to the RADIUS server, which will hopefully respond with
|
||||||
Auth-Accept or Auth-Reject.<P>
|
Auth-Accept or Auth-Reject.<P>
|
||||||
|
|
||||||
If Auth-Accept is received, the session is set up and an IP address is
|
If Auth-Accept is received, the session is set up and an IP address is
|
||||||
assigned. The radius server can include a Framed-IP-Address field in the
|
assigned. The RADIUS server can include a Framed-IP-Address field in the
|
||||||
reply, and that address will be assigned to the client. It can also include
|
reply, and that address will be assigned to the client. It can also include
|
||||||
specific DNS servers, and a Framed-Route if that is required.<P>
|
specific DNS servers, and a Framed-Route if that is required.<P>
|
||||||
|
|
||||||
|
|
@ -708,7 +748,7 @@ walled garden module is loaded, in which case the user still receives the
|
||||||
PPP AUTHACK, but their session is flagged as being a garden'd user, and they
|
PPP AUTHACK, but their session is flagged as being a garden'd user, and they
|
||||||
should not receive any service.<P>
|
should not receive any service.<P>
|
||||||
|
|
||||||
The radius reply can also contain a Vendor-Specific attribute called
|
The RADIUS reply can also contain a Vendor-Specific attribute called
|
||||||
Cisco-Avpair. This field is a freeform text field that most Cisco
|
Cisco-Avpair. This field is a freeform text field that most Cisco
|
||||||
devices understand to contain configuration instructions for the session. In
|
devices understand to contain configuration instructions for the session. In
|
||||||
the case of l2tpns it is expected to be of the form
|
the case of l2tpns it is expected to be of the form
|
||||||
|
|
@ -758,7 +798,7 @@ supplied structure:
|
||||||
<TABLE CELLSPACING=1 CELLPADDING=3>
|
<TABLE CELLSPACING=1 CELLPADDING=3>
|
||||||
<TR BGCOLOR=LIGHTGREEN><TH><B>Event</B></TH><TH><B>Description</B></TH><TH><B>Parameters</B></TH></TR>
|
<TR BGCOLOR=LIGHTGREEN><TH><B>Event</B></TH><TH><B>Description</B></TH><TH><B>Parameters</B></TH></TR>
|
||||||
<TR VALIGN=TOP BGCOLOR=WHITE><TD><B>pre_auth</B></TD>
|
<TR VALIGN=TOP BGCOLOR=WHITE><TD><B>pre_auth</B></TD>
|
||||||
<TD>This is called after a radius response has been
|
<TD>This is called after a RADIUS response has been
|
||||||
received, but before it has been processed by the
|
received, but before it has been processed by the
|
||||||
code. This will allow you to modify the response in
|
code. This will allow you to modify the response in
|
||||||
some way.
|
some way.
|
||||||
|
|
@ -775,7 +815,7 @@ supplied structure:
|
||||||
</TD>
|
</TD>
|
||||||
</TR>
|
</TR>
|
||||||
<TR VALIGN=TOP BGCOLOR=WHITE><TD><B>post_auth</B></TD>
|
<TR VALIGN=TOP BGCOLOR=WHITE><TD><B>post_auth</B></TD>
|
||||||
<TD>This is called after a radius response has been
|
<TD>This is called after a RADIUS response has been
|
||||||
received, and the basic checks have been performed. This
|
received, and the basic checks have been performed. This
|
||||||
is what the garden module uses to force authentication
|
is what the garden module uses to force authentication
|
||||||
to be accepted.
|
to be accepted.
|
||||||
|
|
@ -855,7 +895,7 @@ supplied structure:
|
||||||
</TD>
|
</TD>
|
||||||
</TR>
|
</TR>
|
||||||
<TR VALIGN=TOP BGCOLOR=WHITE><TD><B>radius_response</B></TD>
|
<TR VALIGN=TOP BGCOLOR=WHITE><TD><B>radius_response</B></TD>
|
||||||
<TD>This is called whenever a radius response includes a
|
<TD>This is called whenever a RADIUS response includes a
|
||||||
Cisco-Avpair value. The value is split up into
|
Cisco-Avpair value. The value is split up into
|
||||||
<EM>key=value</EM> pairs, and each is processed through all
|
<EM>key=value</EM> pairs, and each is processed through all
|
||||||
modules.
|
modules.
|
||||||
|
|
@ -901,7 +941,7 @@ Walled Garden is implemented so that you can provide perhaps limited service
|
||||||
to sessions that incorrectly authenticate.<P>
|
to sessions that incorrectly authenticate.<P>
|
||||||
|
|
||||||
Whenever a session provides incorrect authentication, and the
|
Whenever a session provides incorrect authentication, and the
|
||||||
radius server responds with Auth-Reject, the walled garden module
|
RADIUS server responds with Auth-Reject, the walled garden module
|
||||||
(if loaded) will force authentication to succeed, but set the flag
|
(if loaded) will force authentication to succeed, but set the flag
|
||||||
<EM>garden</EM> in the session structure, and adds an iptables rule to
|
<EM>garden</EM> in the session structure, and adds an iptables rule to
|
||||||
the <B>garden_users</B> chain to force all packets for the session's IP
|
the <B>garden_users</B> chain to force all packets for the session's IP
|
||||||
|
|
@ -926,6 +966,14 @@ command:
|
||||||
iptables -t nat -L garden -nvx
|
iptables -t nat -L garden -nvx
|
||||||
</PRE>
|
</PRE>
|
||||||
|
|
||||||
|
<H2 ID="Filtering">Filtering</H2>
|
||||||
|
|
||||||
|
Sessions may be filtered by specifying <B>Filter-Id</B> attributes in
|
||||||
|
the RADIUS reply. <I>filter</I>.<B>in</B> specifies that the named
|
||||||
|
access-list <I>filter</I> should be applied to traffic from the
|
||||||
|
customer, <I>filter</I>.<B>out</B> specifies a list for traffic to the
|
||||||
|
customer.
|
||||||
|
|
||||||
<H2 ID="Clustering">Clustering</H2>
|
<H2 ID="Clustering">Clustering</H2>
|
||||||
|
|
||||||
An l2tpns cluster consists of of one* or more servers configured with
|
An l2tpns cluster consists of of one* or more servers configured with
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
.de Id
|
.de Id
|
||||||
.ds Dt \\$4 \\$5
|
.ds Dt \\$4 \\$5
|
||||||
..
|
..
|
||||||
.Id $Id: startup-config.5,v 1.1 2004/11/17 15:08:19 bodea Exp $
|
.Id $Id: startup-config.5,v 1.2 2004/11/27 05:19:54 bodea Exp $
|
||||||
.TH STARTUP-CONFIG 5 "\*(Dt" L2TPNS "File Formats and Conventions"
|
.TH STARTUP-CONFIG 5 "\*(Dt" L2TPNS "File Formats and Conventions"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
startup\-config \- configuration file for l2tpns
|
startup\-config \- configuration file for l2tpns
|
||||||
|
|
@ -199,5 +199,111 @@ is the remote AS number and
|
||||||
.IR keepalive ,
|
.IR keepalive ,
|
||||||
.I hold
|
.I hold
|
||||||
are the timer values in seconds.
|
are the timer values in seconds.
|
||||||
|
.SS NAMED ACCESS LISTS
|
||||||
|
Named access lists may be defined with either of
|
||||||
|
.IP
|
||||||
|
.BI "ip access\-list standard " name
|
||||||
|
.br
|
||||||
|
.BI "ip access\-list extended " name
|
||||||
|
.PP
|
||||||
|
Subsequent lines starting with
|
||||||
|
.B permit
|
||||||
|
or
|
||||||
|
.B deny
|
||||||
|
define the body of the access\-list.
|
||||||
|
.PP
|
||||||
|
.B Standard Access Lists
|
||||||
|
.RS 4n
|
||||||
|
Standard access lists are defined with:
|
||||||
|
.IP
|
||||||
|
.RB { permit | deny }
|
||||||
|
.IR source " [" dest ]
|
||||||
|
.PP
|
||||||
|
Where
|
||||||
|
.I source
|
||||||
|
and
|
||||||
|
.I dest
|
||||||
|
specify IP matches using one of:
|
||||||
|
.IP
|
||||||
|
.I address
|
||||||
|
.I wildard
|
||||||
|
.br
|
||||||
|
.B host
|
||||||
|
.I address
|
||||||
|
.br
|
||||||
|
.B any
|
||||||
|
.PP
|
||||||
|
.I address
|
||||||
|
and
|
||||||
|
.I wildard
|
||||||
|
are in dotted-quad notation, bits in the
|
||||||
|
.I wildard
|
||||||
|
indicate which address bits in
|
||||||
|
.I address
|
||||||
|
are relevant to the match (0 = exact match; 1 = don't care).
|
||||||
|
.PP
|
||||||
|
The shorthand
|
||||||
|
.RB ' host
|
||||||
|
.IR address '
|
||||||
|
is equivalent to
|
||||||
|
.RI ' address
|
||||||
|
.BR 0.0.0.0 ';
|
||||||
|
.RB ' any '
|
||||||
|
to
|
||||||
|
.RB ' 0.0.0.0
|
||||||
|
.BR 255.255.255.255 '.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
.B Extended Access Lists
|
||||||
|
.RS 4n
|
||||||
|
Extended access lists are defined with:
|
||||||
|
.IP
|
||||||
|
.RB { permit | deny }
|
||||||
|
.I proto
|
||||||
|
.IR source " [" ports "] " dest " [" ports "] [" flags ]
|
||||||
|
.PP
|
||||||
|
Where
|
||||||
|
.I proto
|
||||||
|
is one of
|
||||||
|
.BR ip ,
|
||||||
|
.B tcp
|
||||||
|
or
|
||||||
|
.BR udp ,
|
||||||
|
and
|
||||||
|
.I source
|
||||||
|
and
|
||||||
|
.I dest
|
||||||
|
are as described above for standard lists.
|
||||||
|
.PP
|
||||||
|
For
|
||||||
|
.B tcp
|
||||||
|
and
|
||||||
|
.B udp
|
||||||
|
matches, source and destination may be optionally followed by a
|
||||||
|
.I ports
|
||||||
|
specification:
|
||||||
|
.IP
|
||||||
|
.RB { eq | neq | gt | lt }
|
||||||
|
.I port
|
||||||
|
.br
|
||||||
|
.B
|
||||||
|
range
|
||||||
|
.I from to
|
||||||
|
.PP
|
||||||
|
.B tcp
|
||||||
|
matches may also specify
|
||||||
|
.I flags
|
||||||
|
to match against tcp header flags:
|
||||||
|
.IP
|
||||||
|
.RB { match\-any | match\-all }
|
||||||
|
.RB { + | - }{ fin | syn | rst | psh | ack | urg }
|
||||||
|
\&...
|
||||||
|
.br
|
||||||
|
.B established
|
||||||
|
.PP
|
||||||
|
.RB ' established '
|
||||||
|
is shorthand for
|
||||||
|
.RB ' "match-any +ack +rst -syn" '.
|
||||||
|
.RE
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR l2tpns (8)
|
.BR l2tpns (8)
|
||||||
|
|
|
||||||
615
cli.c
615
cli.c
|
|
@ -2,7 +2,7 @@
|
||||||
// vim: sw=8 ts=8
|
// vim: sw=8 ts=8
|
||||||
|
|
||||||
char const *cvs_name = "$Name: $";
|
char const *cvs_name = "$Name: $";
|
||||||
char const *cvs_id_cli = "$Id: cli.c,v 1.28 2004/11/16 07:54:32 bodea Exp $";
|
char const *cvs_id_cli = "$Id: cli.c,v 1.29 2004/11/27 05:19:53 bodea Exp $";
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
@ -38,14 +38,15 @@ extern radiust *radius;
|
||||||
extern ippoolt *ip_address_pool;
|
extern ippoolt *ip_address_pool;
|
||||||
extern struct Tstats *_statistics;
|
extern struct Tstats *_statistics;
|
||||||
static struct cli_def *cli = NULL;
|
static struct cli_def *cli = NULL;
|
||||||
extern struct configt *config;
|
extern configt *config;
|
||||||
extern struct config_descriptt config_values[];
|
extern config_descriptt config_values[];
|
||||||
#ifdef RINGBUFFER
|
#ifdef RINGBUFFER
|
||||||
extern struct Tringbuffer *ringbuffer;
|
extern struct Tringbuffer *ringbuffer;
|
||||||
#endif
|
#endif
|
||||||
extern struct cli_session_actions *cli_session_actions;
|
extern struct cli_session_actions *cli_session_actions;
|
||||||
extern struct cli_tunnel_actions *cli_tunnel_actions;
|
extern struct cli_tunnel_actions *cli_tunnel_actions;
|
||||||
extern tbft *filter_list;
|
extern tbft *filter_list;
|
||||||
|
extern ip_filtert *ip_filters;
|
||||||
|
|
||||||
static char *debug_levels[] = {
|
static char *debug_levels[] = {
|
||||||
"CRIT",
|
"CRIT",
|
||||||
|
|
@ -110,6 +111,14 @@ static int cmd_no_suspend_bgp(struct cli_def *cli, char *command, char **argv, i
|
||||||
static int cmd_restart_bgp(struct cli_def *cli, char *command, char **argv, int argc);
|
static int cmd_restart_bgp(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
#endif /* BGP */
|
#endif /* BGP */
|
||||||
|
|
||||||
|
#define MODE_CONFIG_NACL 9
|
||||||
|
static int cmd_ip_access_list(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
|
static int cmd_no_ip_access_list(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
|
static int cmd_ip_access_list_rule(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
|
|
||||||
|
/* match if b is a substr of a */
|
||||||
|
#define MATCH(a,b) (!strncmp((a), (b), strlen(b)))
|
||||||
|
|
||||||
void init_cli(char *hostname)
|
void init_cli(char *hostname)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
@ -203,6 +212,16 @@ void init_cli(char *hostname)
|
||||||
|
|
||||||
cli_register_command(cli, NULL, "set", cmd_set, PRIVILEGE_PRIVILEGED, MODE_CONFIG, "Set a configuration variable");
|
cli_register_command(cli, NULL, "set", cmd_set, PRIVILEGE_PRIVILEGED, MODE_CONFIG, "Set a configuration variable");
|
||||||
|
|
||||||
|
c = cli_register_command(cli, NULL, "ip", NULL, PRIVILEGE_PRIVILEGED, MODE_CONFIG, NULL);
|
||||||
|
cli_register_command(cli, c, "access-list", cmd_ip_access_list, PRIVILEGE_PRIVILEGED, MODE_CONFIG, "Add named access-list");
|
||||||
|
|
||||||
|
cli_register_command(cli, NULL, "permit", cmd_ip_access_list_rule, PRIVILEGE_PRIVILEGED, MODE_CONFIG_NACL, "Permit rule");
|
||||||
|
cli_register_command(cli, NULL, "deny", cmd_ip_access_list_rule, PRIVILEGE_PRIVILEGED, MODE_CONFIG_NACL, "Deny rule");
|
||||||
|
|
||||||
|
c = cli_register_command(cli, NULL, "no", NULL, PRIVILEGE_UNPRIVILEGED, MODE_CONFIG, NULL);
|
||||||
|
c2 = cli_register_command(cli, c, "ip", NULL, PRIVILEGE_PRIVILEGED, MODE_CONFIG, NULL);
|
||||||
|
cli_register_command(cli, c2, "access-list", cmd_no_ip_access_list, PRIVILEGE_PRIVILEGED, MODE_CONFIG, "Remove named access-list");
|
||||||
|
|
||||||
// Enable regular processing
|
// Enable regular processing
|
||||||
cli_regular(cli, regular_stuff);
|
cli_regular(cli, regular_stuff);
|
||||||
|
|
||||||
|
|
@ -852,6 +871,8 @@ static int cmd_write_memory(struct cli_def *cli, char *command, char **argv, int
|
||||||
return CLI_OK;
|
return CLI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char const *show_access_list_rule(int extended, ip_filter_rulet *rule);
|
||||||
|
|
||||||
static int cmd_show_run(struct cli_def *cli, char *command, char **argv, int argc)
|
static int cmd_show_run(struct cli_def *cli, char *command, char **argv, int argc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -929,6 +950,22 @@ static int cmd_show_run(struct cli_def *cli, char *command, char **argv, int arg
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
cli_print(cli, "# Filters");
|
||||||
|
for (i = 0; i < MAXFILTER; i++)
|
||||||
|
{
|
||||||
|
ip_filter_rulet *rules;
|
||||||
|
if (!*ip_filters[i].name)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cli_print(cli, "ip access-list %s %s",
|
||||||
|
ip_filters[i].extended ? "extended" : "standard",
|
||||||
|
ip_filters[i].name);
|
||||||
|
|
||||||
|
rules = ip_filters[i].rules;
|
||||||
|
while (rules->action)
|
||||||
|
cli_print(cli, "%s", show_access_list_rule(ip_filters[i].extended, rules++));
|
||||||
|
}
|
||||||
|
|
||||||
cli_print(cli, "# end");
|
cli_print(cli, "# end");
|
||||||
return CLI_OK;
|
return CLI_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -1877,7 +1914,7 @@ static int cmd_router_bgp(struct cli_def *cli, char *command, char **argv, int a
|
||||||
return CLI_OK;
|
return CLI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int find_bgp_neighbour(char *name)
|
static int find_bgp_neighbour(char const *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int new = -1;
|
int new = -1;
|
||||||
|
|
@ -1940,10 +1977,10 @@ static int cmd_router_bgp_neighbour(struct cli_def *cli, char *command, char **a
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (!strncmp("remote-as", argv[1], strlen(argv[1])))
|
if (MATCH("remote-as", argv[1]))
|
||||||
return cli_arg_help(cli, argv[2][1], "<1-65535>", "Autonomous system number", NULL);
|
return cli_arg_help(cli, argv[2][1], "<1-65535>", "Autonomous system number", NULL);
|
||||||
|
|
||||||
if (!strncmp("timers", argv[1], strlen(argv[1])))
|
if (MATCH("timers", argv[1]))
|
||||||
{
|
{
|
||||||
if (argc == 3)
|
if (argc == 3)
|
||||||
return cli_arg_help(cli, 0, "<1-65535>", "Keepalive time", NULL);
|
return cli_arg_help(cli, 0, "<1-65535>", "Keepalive time", NULL);
|
||||||
|
|
@ -1977,7 +2014,7 @@ static int cmd_router_bgp_neighbour(struct cli_def *cli, char *command, char **a
|
||||||
return CLI_OK;
|
return CLI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strncmp("remote-as", argv[1], strlen(argv[1])))
|
if (MATCH("remote-as", argv[1]))
|
||||||
{
|
{
|
||||||
int as = atoi(argv[2]);
|
int as = atoi(argv[2]);
|
||||||
if (as < 0 || as > 65535)
|
if (as < 0 || as > 65535)
|
||||||
|
|
@ -1997,7 +2034,7 @@ static int cmd_router_bgp_neighbour(struct cli_def *cli, char *command, char **a
|
||||||
return CLI_OK;
|
return CLI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc != 4 || strncmp("timers", argv[1], strlen(argv[1])))
|
if (argc != 4 || !MATCH("timers", argv[1]))
|
||||||
{
|
{
|
||||||
cli_print(cli, "Invalid arguments");
|
cli_print(cli, "Invalid arguments");
|
||||||
return CLI_OK;
|
return CLI_OK;
|
||||||
|
|
@ -2222,6 +2259,568 @@ static int cmd_restart_bgp(struct cli_def *cli, char *command, char **argv, int
|
||||||
}
|
}
|
||||||
#endif /* BGP*/
|
#endif /* BGP*/
|
||||||
|
|
||||||
|
static int filt;
|
||||||
|
static int find_access_list(char const *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXFILTER; i++)
|
||||||
|
if (!(*ip_filters[i].name && strcmp(ip_filters[i].name, name)))
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int access_list(struct cli_def *cli, char **argv, int argc, int add)
|
||||||
|
{
|
||||||
|
int extended;
|
||||||
|
|
||||||
|
if (CLI_HELP_REQUESTED)
|
||||||
|
{
|
||||||
|
switch (argc)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
return cli_arg_help(cli, 0,
|
||||||
|
"standard", "Standard syntax",
|
||||||
|
"extended", "Extended syntax",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
return cli_arg_help(cli, argv[1][1],
|
||||||
|
"NAME", "Access-list name",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (argc == 3 && !argv[2][1])
|
||||||
|
return cli_arg_help(cli, 1, NULL);
|
||||||
|
|
||||||
|
return CLI_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Specify access-list type and name");
|
||||||
|
return CLI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MATCH("standard", argv[0]))
|
||||||
|
extended = 0;
|
||||||
|
else if (MATCH("extended", argv[0]))
|
||||||
|
extended = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cli_print(cli, "Invalid access-list type");
|
||||||
|
return CLI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(argv[1]) > sizeof(ip_filters[0].name) - 1 ||
|
||||||
|
strspn(argv[1], "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_") != strlen(argv[1]))
|
||||||
|
{
|
||||||
|
cli_print(cli, "Invalid access-list name");
|
||||||
|
return CLI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
filt = find_access_list(argv[1]);
|
||||||
|
if (add)
|
||||||
|
{
|
||||||
|
if (filt < 0)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Too many access-lists");
|
||||||
|
return CLI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// racy
|
||||||
|
if (!*ip_filters[filt].name)
|
||||||
|
{
|
||||||
|
memset(&ip_filters[filt], 0, sizeof(ip_filters[filt]));
|
||||||
|
strcpy(ip_filters[filt].name, argv[1]);
|
||||||
|
ip_filters[filt].extended = extended;
|
||||||
|
}
|
||||||
|
else if (ip_filters[filt].extended != extended)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Access-list is %s",
|
||||||
|
ip_filters[filt].extended ? "extended" : "standard");
|
||||||
|
|
||||||
|
return CLI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_set_configmode(cli, MODE_CONFIG_NACL, extended ? "ext-nacl" : "std-nacl");
|
||||||
|
return CLI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filt < 0 || !*ip_filters[filt].name)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Access-list not defined");
|
||||||
|
return CLI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// racy
|
||||||
|
if (ip_filters[filt].used)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Access-list in use");
|
||||||
|
return CLI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&ip_filters[filt], 0, sizeof(ip_filters[filt]));
|
||||||
|
return CLI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_ip_access_list(struct cli_def *cli, char *command, char **argv, int argc)
|
||||||
|
{
|
||||||
|
return access_list(cli, argv, argc, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_no_ip_access_list(struct cli_def *cli, char *command, char **argv, int argc)
|
||||||
|
{
|
||||||
|
return access_list(cli, argv, argc, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int show_ip_wild(char *buf, ipt ip, ipt wild)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (ip == INADDR_ANY && wild == INADDR_BROADCAST)
|
||||||
|
return sprintf(buf, " any");
|
||||||
|
|
||||||
|
if (wild == INADDR_ANY)
|
||||||
|
return sprintf(buf, " host %s", inet_toa(ip));
|
||||||
|
|
||||||
|
i = sprintf(buf, " %s", inet_toa(ip));
|
||||||
|
return i + sprintf(buf + i, " %s", inet_toa(wild));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int show_ports(char *buf, ip_filter_portt *ports)
|
||||||
|
{
|
||||||
|
switch (ports->op)
|
||||||
|
{
|
||||||
|
case FILTER_PORT_OP_EQ: return sprintf(buf, " eq %u", ports->port);
|
||||||
|
case FILTER_PORT_OP_NEQ: return sprintf(buf, " neq %u", ports->port);
|
||||||
|
case FILTER_PORT_OP_GT: return sprintf(buf, " gt %u", ports->port);
|
||||||
|
case FILTER_PORT_OP_LT: return sprintf(buf, " lt %u", ports->port);
|
||||||
|
case FILTER_PORT_OP_RANGE: return sprintf(buf, " range %u %u", ports->port, ports->port2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char const *show_access_list_rule(int extended, ip_filter_rulet *rule)
|
||||||
|
{
|
||||||
|
static char buf[256];
|
||||||
|
char *p = buf;
|
||||||
|
|
||||||
|
p += sprintf(p, " %s", rule->action == FILTER_ACTION_PERMIT ? "permit" : "deny");
|
||||||
|
if (extended)
|
||||||
|
{
|
||||||
|
struct protoent *proto = getprotobynumber(rule->proto);
|
||||||
|
p += sprintf(p, " %s", proto ? proto->p_name : "ERR");
|
||||||
|
}
|
||||||
|
|
||||||
|
p += show_ip_wild(p, rule->src_ip, rule->src_wild);
|
||||||
|
if (!extended)
|
||||||
|
return buf;
|
||||||
|
|
||||||
|
if (rule->proto == IPPROTO_TCP || rule->proto == IPPROTO_UDP)
|
||||||
|
p += show_ports(p, &rule->src_ports);
|
||||||
|
|
||||||
|
p += show_ip_wild(p, rule->dst_ip, rule->dst_wild);
|
||||||
|
if (rule->proto == IPPROTO_TCP || rule->proto == IPPROTO_UDP)
|
||||||
|
p += show_ports(p, &rule->dst_ports);
|
||||||
|
|
||||||
|
if (rule->proto == IPPROTO_TCP && (rule->tcp_sflags || rule->tcp_cflags))
|
||||||
|
{
|
||||||
|
if (rule->tcp_flag_op == FILTER_FLAG_OP_ANY &&
|
||||||
|
rule->tcp_sflags == (TCP_FLAG_ACK|TCP_FLAG_FIN) &&
|
||||||
|
rule->tcp_cflags == TCP_FLAG_SYN)
|
||||||
|
{
|
||||||
|
p += sprintf(p, " established");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p += sprintf(p, " match-%s", rule->tcp_flag_op == FILTER_FLAG_OP_ALL ? "all" : "any");
|
||||||
|
if (rule->tcp_sflags & TCP_FLAG_FIN) p += sprintf(p, " +fin");
|
||||||
|
if (rule->tcp_cflags & TCP_FLAG_FIN) p += sprintf(p, " -fin");
|
||||||
|
if (rule->tcp_sflags & TCP_FLAG_SYN) p += sprintf(p, " +syn");
|
||||||
|
if (rule->tcp_cflags & TCP_FLAG_SYN) p += sprintf(p, " -syn");
|
||||||
|
if (rule->tcp_sflags & TCP_FLAG_RST) p += sprintf(p, " +rst");
|
||||||
|
if (rule->tcp_cflags & TCP_FLAG_RST) p += sprintf(p, " -rst");
|
||||||
|
if (rule->tcp_sflags & TCP_FLAG_PSH) p += sprintf(p, " +psh");
|
||||||
|
if (rule->tcp_cflags & TCP_FLAG_PSH) p += sprintf(p, " -psh");
|
||||||
|
if (rule->tcp_sflags & TCP_FLAG_ACK) p += sprintf(p, " +ack");
|
||||||
|
if (rule->tcp_cflags & TCP_FLAG_ACK) p += sprintf(p, " -ack");
|
||||||
|
if (rule->tcp_sflags & TCP_FLAG_URG) p += sprintf(p, " +urg");
|
||||||
|
if (rule->tcp_cflags & TCP_FLAG_URG) p += sprintf(p, " -urg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_filter_rulet *access_list_rule_ext(struct cli_def *cli, char *command, char **argv, int argc)
|
||||||
|
{
|
||||||
|
static ip_filter_rulet rule;
|
||||||
|
struct in_addr addr;
|
||||||
|
int i;
|
||||||
|
int a;
|
||||||
|
|
||||||
|
if (CLI_HELP_REQUESTED)
|
||||||
|
{
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
cli_arg_help(cli, 0,
|
||||||
|
"ip", "Match IP packets",
|
||||||
|
"tcp", "Match TCP packets",
|
||||||
|
"udp", "Match UDP packets",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *sigh*, too darned complex
|
||||||
|
cli_arg_help(cli, 0, "RULE", "SOURCE [PORTS] DEST [PORTS] FLAGS", NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Specify rule details");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&rule, 0, sizeof(rule));
|
||||||
|
rule.action = (command[0] == 'p')
|
||||||
|
? FILTER_ACTION_PERMIT
|
||||||
|
: FILTER_ACTION_DENY;
|
||||||
|
|
||||||
|
if (MATCH("ip", argv[0]))
|
||||||
|
rule.proto = IPPROTO_IP;
|
||||||
|
else if (MATCH("udp", argv[0]))
|
||||||
|
rule.proto = IPPROTO_UDP;
|
||||||
|
else if (MATCH("tcp", argv[0]))
|
||||||
|
rule.proto = IPPROTO_TCP;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cli_print(cli, "Invalid protocol \"%s\"", argv[0]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (a = 1, i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
ipt *ip;
|
||||||
|
ipt *wild;
|
||||||
|
ip_filter_portt *port;
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
ip = &rule.src_ip;
|
||||||
|
wild = &rule.src_wild;
|
||||||
|
port = &rule.src_ports;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ip = &rule.dst_ip;
|
||||||
|
wild = &rule.dst_wild;
|
||||||
|
port = &rule.dst_ports;
|
||||||
|
if (a >= argc)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Specify destination");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MATCH("any", argv[a]))
|
||||||
|
{
|
||||||
|
*ip = INADDR_ANY;
|
||||||
|
*wild = INADDR_BROADCAST;
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
else if (MATCH("host", argv[a]))
|
||||||
|
{
|
||||||
|
if (++a >= argc)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Specify host ip address");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inet_aton(argv[a], &addr))
|
||||||
|
{
|
||||||
|
cli_print(cli, "Cannot parse IP \"%s\"", argv[a]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ip = addr.s_addr;
|
||||||
|
*wild = INADDR_ANY;
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (++a >= argc)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Specify %s ip address and wildcard", i ? "destination" : "source");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inet_aton(argv[a], &addr))
|
||||||
|
{
|
||||||
|
cli_print(cli, "Cannot parse IP \"%s\"", argv[a]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ip = addr.s_addr;
|
||||||
|
|
||||||
|
if (!inet_aton(argv[++a], &addr))
|
||||||
|
{
|
||||||
|
cli_print(cli, "Cannot parse IP \"%s\"", argv[a]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*wild = addr.s_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rule.proto == IPPROTO_IP || a >= argc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
port->op = 0;
|
||||||
|
if (MATCH("eq", argv[a]))
|
||||||
|
port->op = FILTER_PORT_OP_EQ;
|
||||||
|
else if (MATCH("neq", argv[a]))
|
||||||
|
port->op = FILTER_PORT_OP_NEQ;
|
||||||
|
else if (MATCH("gt", argv[a]))
|
||||||
|
port->op = FILTER_PORT_OP_GT;
|
||||||
|
else if (MATCH("lt", argv[a]))
|
||||||
|
port->op = FILTER_PORT_OP_LT;
|
||||||
|
else if (MATCH("range", argv[a]))
|
||||||
|
port->op = FILTER_PORT_OP_RANGE;
|
||||||
|
|
||||||
|
if (!port->op)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (++a >= argc)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Specify port");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(port->port = atoi(argv[a])))
|
||||||
|
{
|
||||||
|
cli_print(cli, "Invalid port \"%s\"", argv[a]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a++;
|
||||||
|
if (port->op != FILTER_PORT_OP_RANGE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (a >= argc)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Specify port");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(port->port2 = atoi(argv[a])) || port->port2 < port->port)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Invalid port \"%s\"", argv[a]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rule.proto == IPPROTO_TCP && a < argc)
|
||||||
|
{
|
||||||
|
if (MATCH("established", argv[a]))
|
||||||
|
{
|
||||||
|
rule.tcp_flag_op = FILTER_FLAG_OP_ANY;
|
||||||
|
rule.tcp_sflags = (TCP_FLAG_ACK|TCP_FLAG_FIN);
|
||||||
|
rule.tcp_cflags = TCP_FLAG_SYN;
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
else if (!strcmp(argv[a], "match-any") || !strcmp(argv[a], "match-an") ||
|
||||||
|
!strcmp(argv[a], "match-all") || !strcmp(argv[a], "match-al"))
|
||||||
|
{
|
||||||
|
rule.tcp_flag_op = argv[a][7] == 'n'
|
||||||
|
? FILTER_FLAG_OP_ANY
|
||||||
|
: FILTER_FLAG_OP_ALL;
|
||||||
|
|
||||||
|
if (++a >= argc)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Specify tcp flags");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (a < argc && (argv[a][0] == '+' || argv[a][0] == '-'))
|
||||||
|
{
|
||||||
|
u8 *f;
|
||||||
|
|
||||||
|
f = (argv[a][0] == '+') ? &rule.tcp_sflags : &rule.tcp_cflags;
|
||||||
|
|
||||||
|
if (MATCH("fin", &argv[a][1])) *f |= TCP_FLAG_FIN;
|
||||||
|
else if (MATCH("syn", &argv[a][1])) *f |= TCP_FLAG_SYN;
|
||||||
|
else if (MATCH("rst", &argv[a][1])) *f |= TCP_FLAG_RST;
|
||||||
|
else if (MATCH("psh", &argv[a][1])) *f |= TCP_FLAG_PSH;
|
||||||
|
else if (MATCH("ack", &argv[a][1])) *f |= TCP_FLAG_ACK;
|
||||||
|
else if (MATCH("urg", &argv[a][1])) *f |= TCP_FLAG_URG;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cli_print(cli, "Invalid tcp flag \"%s\"", argv[a]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a < argc)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Invalid flag \"%s\"", argv[a]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_filter_rulet *access_list_rule_std(struct cli_def *cli, char *command, char **argv, int argc)
|
||||||
|
{
|
||||||
|
static ip_filter_rulet rule;
|
||||||
|
struct in_addr addr;
|
||||||
|
|
||||||
|
if (CLI_HELP_REQUESTED)
|
||||||
|
{
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
cli_arg_help(cli, argv[0][1],
|
||||||
|
"A.B.C.D", "Source address",
|
||||||
|
"any", "Any source address",
|
||||||
|
"host", "Source host",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MATCH("any", argv[0]))
|
||||||
|
{
|
||||||
|
if (argc == 2 && !argv[1][1])
|
||||||
|
cli_arg_help(cli, 1, NULL);
|
||||||
|
}
|
||||||
|
else if (MATCH("host", argv[0]))
|
||||||
|
{
|
||||||
|
if (argc == 2)
|
||||||
|
{
|
||||||
|
cli_arg_help(cli, argv[1][1],
|
||||||
|
"A.B.C.D", "Host address",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else if (argc == 3 && !argv[2][1])
|
||||||
|
cli_arg_help(cli, 1, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (argc == 2)
|
||||||
|
{
|
||||||
|
cli_arg_help(cli, 1,
|
||||||
|
"A.B.C.D", "Wildcard bits",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else if (argc == 3 && !argv[2][1])
|
||||||
|
cli_arg_help(cli, 1, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc < 1)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Specify rule details");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&rule, 0, sizeof(rule));
|
||||||
|
rule.action = (command[0] == 'p')
|
||||||
|
? FILTER_ACTION_PERMIT
|
||||||
|
: FILTER_ACTION_DENY;
|
||||||
|
|
||||||
|
rule.proto = IPPROTO_IP;
|
||||||
|
if (MATCH("any", argv[0]))
|
||||||
|
{
|
||||||
|
rule.src_ip = INADDR_ANY;
|
||||||
|
rule.src_wild = INADDR_BROADCAST;
|
||||||
|
}
|
||||||
|
else if (MATCH("host", argv[0]))
|
||||||
|
{
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Specify host ip address");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inet_aton(argv[1], &addr))
|
||||||
|
{
|
||||||
|
cli_print(cli, "Cannot parse IP \"%s\"", argv[1]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rule.src_ip = addr.s_addr;
|
||||||
|
rule.src_wild = INADDR_ANY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (argc > 2)
|
||||||
|
{
|
||||||
|
cli_print(cli, "Specify source ip address and wildcard");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inet_aton(argv[0], &addr))
|
||||||
|
{
|
||||||
|
cli_print(cli, "Cannot parse IP \"%s\"", argv[0]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rule.src_ip = addr.s_addr;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
{
|
||||||
|
if (!inet_aton(argv[1], &addr))
|
||||||
|
{
|
||||||
|
cli_print(cli, "Cannot parse IP \"%s\"", argv[1]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rule.src_wild = addr.s_addr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rule.src_wild = INADDR_ANY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_ip_access_list_rule(struct cli_def *cli, char *command, char **argv, int argc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
ip_filter_rulet *rule = ip_filters[filt].extended
|
||||||
|
? access_list_rule_ext(cli, command, argv, argc)
|
||||||
|
: access_list_rule_std(cli, command, argv, argc);
|
||||||
|
|
||||||
|
if (!rule)
|
||||||
|
return CLI_OK;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXFILTER_RULES - 1; i++) // -1: list always terminated by empty rule
|
||||||
|
{
|
||||||
|
if (!ip_filters[filt].rules[i].action)
|
||||||
|
{
|
||||||
|
memcpy(&ip_filters[filt].rules[i], rule, sizeof(*rule));
|
||||||
|
return CLI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!memcmp(&ip_filters[filt].rules[i], rule, sizeof(*rule)))
|
||||||
|
return CLI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_print(cli, "Too many rules");
|
||||||
|
return CLI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Convert a string in the form of abcd.ef12.3456 into char[6]
|
// Convert a string in the form of abcd.ef12.3456 into char[6]
|
||||||
void parsemac(char *string, char mac[6])
|
void parsemac(char *string, char mac[6])
|
||||||
{
|
{
|
||||||
|
|
|
||||||
78
l2tpns.c
78
l2tpns.c
|
|
@ -4,7 +4,7 @@
|
||||||
// Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
|
// Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
|
||||||
// vim: sw=8 ts=8
|
// vim: sw=8 ts=8
|
||||||
|
|
||||||
char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.56 2004/11/25 02:49:18 bodea Exp $";
|
char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.57 2004/11/27 05:19:53 bodea Exp $";
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
@ -54,7 +54,7 @@ char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.56 2004/11/25 02:49:18 bodea Exp
|
||||||
#endif /* BGP */
|
#endif /* BGP */
|
||||||
|
|
||||||
// Globals
|
// Globals
|
||||||
struct configt *config = NULL; // all configuration
|
configt *config = NULL; // all configuration
|
||||||
int tunfd = -1; // tun interface file handle. (network device)
|
int tunfd = -1; // tun interface file handle. (network device)
|
||||||
int udpfd = -1; // UDP file handle
|
int udpfd = -1; // UDP file handle
|
||||||
int controlfd = -1; // Control signal handle
|
int controlfd = -1; // Control signal handle
|
||||||
|
|
@ -88,9 +88,9 @@ linked_list *loaded_plugins;
|
||||||
linked_list *plugins[MAX_PLUGIN_TYPES];
|
linked_list *plugins[MAX_PLUGIN_TYPES];
|
||||||
|
|
||||||
#define membersize(STRUCT, MEMBER) sizeof(((STRUCT *)0)->MEMBER)
|
#define membersize(STRUCT, MEMBER) sizeof(((STRUCT *)0)->MEMBER)
|
||||||
#define CONFIG(NAME, MEMBER, TYPE) { NAME, offsetof(struct configt, MEMBER), membersize(struct configt, MEMBER), TYPE }
|
#define CONFIG(NAME, MEMBER, TYPE) { NAME, offsetof(configt, MEMBER), membersize(configt, MEMBER), TYPE }
|
||||||
|
|
||||||
struct config_descriptt config_values[] = {
|
config_descriptt config_values[] = {
|
||||||
CONFIG("debug", debug, INT),
|
CONFIG("debug", debug, INT),
|
||||||
CONFIG("log_file", log_filename, STRING),
|
CONFIG("log_file", log_filename, STRING),
|
||||||
CONFIG("pid_file", pid_file, STRING),
|
CONFIG("pid_file", pid_file, STRING),
|
||||||
|
|
@ -146,6 +146,7 @@ sessiont *session = NULL; // Array of session structures.
|
||||||
sessioncountt *sess_count = NULL; // Array of partial per-session traffic counters.
|
sessioncountt *sess_count = NULL; // Array of partial per-session traffic counters.
|
||||||
radiust *radius = NULL; // Array of radius structures.
|
radiust *radius = NULL; // Array of radius structures.
|
||||||
ippoolt *ip_address_pool = NULL; // Array of dynamic IP addresses.
|
ippoolt *ip_address_pool = NULL; // Array of dynamic IP addresses.
|
||||||
|
ip_filtert *ip_filters = NULL; // Array of named filters.
|
||||||
static controlt *controlfree = 0;
|
static controlt *controlfree = 0;
|
||||||
struct Tstats *_statistics = NULL;
|
struct Tstats *_statistics = NULL;
|
||||||
#ifdef RINGBUFFER
|
#ifdef RINGBUFFER
|
||||||
|
|
@ -942,8 +943,10 @@ static void controladd(controlt * c, tunnelidt t, sessionidt s)
|
||||||
tunnel[t].controle->next = c;
|
tunnel[t].controle->next = c;
|
||||||
else
|
else
|
||||||
tunnel[t].controls = c;
|
tunnel[t].controls = c;
|
||||||
|
|
||||||
tunnel[t].controle = c;
|
tunnel[t].controle = c;
|
||||||
tunnel[t].controlc++;
|
tunnel[t].controlc++;
|
||||||
|
|
||||||
// send now if space in window
|
// send now if space in window
|
||||||
if (tunnel[t].controlc <= tunnel[t].window)
|
if (tunnel[t].controlc <= tunnel[t].window)
|
||||||
{
|
{
|
||||||
|
|
@ -1306,10 +1309,9 @@ void processudp(u8 * buf, int len, struct sockaddr_in *addr)
|
||||||
STAT(tunnel_rx_errors);
|
STAT(tunnel_rx_errors);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG(3, ntohl(addr->sin_addr.s_addr), s, t, "Control message (%d bytes): (unacked %d) l-ns %d l-nr %d r-ns %d r-nr %d\n",
|
|
||||||
l, tunnel[t].controlc, tunnel[t].ns, tunnel[t].nr, ns, nr);
|
// check for duplicate tunnel open message
|
||||||
// if no tunnel specified, assign one
|
if (!t && ns == 0)
|
||||||
if (!t)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
@ -1323,10 +1325,15 @@ void processudp(u8 * buf, int len, struct sockaddr_in *addr)
|
||||||
tunnel[i].port != ntohs(addr->sin_port) )
|
tunnel[i].port != ntohs(addr->sin_port) )
|
||||||
continue;
|
continue;
|
||||||
t = i;
|
t = i;
|
||||||
|
LOG(3, ntohl(addr->sin_addr.s_addr), s, t, "Duplicate SCCRQ?\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG(3, ntohl(addr->sin_addr.s_addr), s, t, "Control message (%d bytes): (unacked %d) l-ns %d l-nr %d r-ns %d r-nr %d\n",
|
||||||
|
l, tunnel[t].controlc, tunnel[t].ns, tunnel[t].nr, ns, nr);
|
||||||
|
|
||||||
|
// if no tunnel specified, assign one
|
||||||
if (!t)
|
if (!t)
|
||||||
{
|
{
|
||||||
if (!(t = new_tunnel()))
|
if (!(t = new_tunnel()))
|
||||||
|
|
@ -1339,26 +1346,10 @@ void processudp(u8 * buf, int len, struct sockaddr_in *addr)
|
||||||
tunnel[t].ip = ntohl(*(ipt *) & addr->sin_addr);
|
tunnel[t].ip = ntohl(*(ipt *) & addr->sin_addr);
|
||||||
tunnel[t].port = ntohs(addr->sin_port);
|
tunnel[t].port = ntohs(addr->sin_port);
|
||||||
tunnel[t].window = 4; // default window
|
tunnel[t].window = 4; // default window
|
||||||
LOG(1, ntohl(addr->sin_addr.s_addr), 0, t, " New tunnel from %u.%u.%u.%u/%u ID %d\n", tunnel[t].ip >> 24, tunnel[t].ip >> 16 & 255, tunnel[t].ip >> 8 & 255, tunnel[t].ip & 255, tunnel[t].port, t);
|
|
||||||
STAT(tunnel_created);
|
STAT(tunnel_created);
|
||||||
}
|
LOG(1, ntohl(addr->sin_addr.s_addr), 0, t, " New tunnel from %u.%u.%u.%u/%u ID %d\n",
|
||||||
|
tunnel[t].ip >> 24, tunnel[t].ip >> 16 & 255,
|
||||||
// This is used to time out old tunnels
|
tunnel[t].ip >> 8 & 255, tunnel[t].ip & 255, tunnel[t].port, t);
|
||||||
tunnel[t].lastrec = time_now;
|
|
||||||
|
|
||||||
// check sequence of this message
|
|
||||||
{
|
|
||||||
int skip = tunnel[t].window; // track how many in-window packets are still in queue
|
|
||||||
// some to clear maybe?
|
|
||||||
while (tunnel[t].controlc && (((tunnel[t].ns - tunnel[t].controlc) - nr) & 0x8000))
|
|
||||||
{
|
|
||||||
controlt *c = tunnel[t].controls;
|
|
||||||
tunnel[t].controls = c->next;
|
|
||||||
tunnel[t].controlc--;
|
|
||||||
c->next = controlfree;
|
|
||||||
controlfree = c;
|
|
||||||
skip--;
|
|
||||||
tunnel[t].try = 0; // we have progress
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the 'ns' just received is not the 'nr' we're
|
// If the 'ns' just received is not the 'nr' we're
|
||||||
|
|
@ -1370,13 +1361,33 @@ void processudp(u8 * buf, int len, struct sockaddr_in *addr)
|
||||||
if (ns != tunnel[t].nr)
|
if (ns != tunnel[t].nr)
|
||||||
{
|
{
|
||||||
// is this the sequence we were expecting?
|
// is this the sequence we were expecting?
|
||||||
LOG(1, ntohl(addr->sin_addr.s_addr), 0, t, " Out of sequence tunnel %d, (%d is not the expected %d)\n", t, ns, tunnel[t].nr);
|
|
||||||
STAT(tunnel_rx_errors);
|
STAT(tunnel_rx_errors);
|
||||||
|
LOG(1, ntohl(addr->sin_addr.s_addr), 0, t, " Out of sequence tunnel %d, (%d is not the expected %d)\n",
|
||||||
|
t, ns, tunnel[t].nr);
|
||||||
|
|
||||||
if (l) // Is this not a ZLB?
|
if (l) // Is this not a ZLB?
|
||||||
controlnull(t);
|
controlnull(t);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is used to time out old tunnels
|
||||||
|
tunnel[t].lastrec = time_now;
|
||||||
|
|
||||||
|
// check sequence of this message
|
||||||
|
{
|
||||||
|
int skip = tunnel[t].window; // track how many in-window packets are still in queue
|
||||||
|
// some to clear maybe?
|
||||||
|
while (tunnel[t].controlc > 0 && (((tunnel[t].ns - tunnel[t].controlc) - nr) & 0x8000))
|
||||||
|
{
|
||||||
|
controlt *c = tunnel[t].controls;
|
||||||
|
tunnel[t].controls = c->next;
|
||||||
|
tunnel[t].controlc--;
|
||||||
|
c->next = controlfree;
|
||||||
|
controlfree = c;
|
||||||
|
skip--;
|
||||||
|
tunnel[t].try = 0; // we have progress
|
||||||
|
}
|
||||||
|
|
||||||
// receiver advance (do here so quoted correctly in any sends below)
|
// receiver advance (do here so quoted correctly in any sends below)
|
||||||
if (l) tunnel[t].nr = (ns + 1);
|
if (l) tunnel[t].nr = (ns + 1);
|
||||||
if (skip < 0) skip = 0;
|
if (skip < 0) skip = 0;
|
||||||
|
|
@ -2480,12 +2491,12 @@ static void initdata(int optdebug, char *optconfig)
|
||||||
LOG(0, 0, 0, 0, "Error doing malloc for _statistics: %s\n", strerror(errno));
|
LOG(0, 0, 0, 0, "Error doing malloc for _statistics: %s\n", strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (!(config = shared_malloc(sizeof(struct configt))))
|
if (!(config = shared_malloc(sizeof(configt))))
|
||||||
{
|
{
|
||||||
LOG(0, 0, 0, 0, "Error doing malloc for configuration: %s\n", strerror(errno));
|
LOG(0, 0, 0, 0, "Error doing malloc for configuration: %s\n", strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
memset(config, 0, sizeof(struct configt));
|
memset(config, 0, sizeof(configt));
|
||||||
time(&config->start_time);
|
time(&config->start_time);
|
||||||
strncpy(config->config_file, optconfig, strlen(optconfig));
|
strncpy(config->config_file, optconfig, strlen(optconfig));
|
||||||
config->debug = optdebug;
|
config->debug = optdebug;
|
||||||
|
|
@ -2521,6 +2532,13 @@ static void initdata(int optdebug, char *optconfig)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(ip_filters = shared_malloc(sizeof(ip_filtert) * MAXFILTER)))
|
||||||
|
{
|
||||||
|
LOG(0, 0, 0, 0, "Error doing malloc for ip_filters: %s\n", strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
memset(ip_filters, 0, sizeof(ip_filtert) * MAXFILTER);
|
||||||
|
|
||||||
#ifdef RINGBUFFER
|
#ifdef RINGBUFFER
|
||||||
if (!(ringbuffer = shared_malloc(sizeof(struct Tringbuffer))))
|
if (!(ringbuffer = shared_malloc(sizeof(struct Tringbuffer))))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
76
l2tpns.h
76
l2tpns.h
|
|
@ -1,5 +1,5 @@
|
||||||
// L2TPNS Global Stuff
|
// L2TPNS Global Stuff
|
||||||
// $Id: l2tpns.h,v 1.37 2004/11/25 12:41:35 bodea Exp $
|
// $Id: l2tpns.h,v 1.38 2004/11/27 05:19:53 bodea Exp $
|
||||||
|
|
||||||
#ifndef __L2TPNS_H__
|
#ifndef __L2TPNS_H__
|
||||||
#define __L2TPNS_H__
|
#define __L2TPNS_H__
|
||||||
|
|
@ -142,7 +142,7 @@ struct cli_tunnel_actions {
|
||||||
#define DUMP_MAGIC "L2TPNS#" VERSION "#"
|
#define DUMP_MAGIC "L2TPNS#" VERSION "#"
|
||||||
|
|
||||||
// structures
|
// structures
|
||||||
typedef struct routes // route
|
typedef struct // route
|
||||||
{
|
{
|
||||||
ipt ip;
|
ipt ip;
|
||||||
ipt mask;
|
ipt mask;
|
||||||
|
|
@ -157,7 +157,7 @@ typedef struct controls // control message
|
||||||
}
|
}
|
||||||
controlt;
|
controlt;
|
||||||
|
|
||||||
typedef struct sessions
|
typedef struct
|
||||||
{
|
{
|
||||||
sessionidt next; // next session in linked list
|
sessionidt next; // next session in linked list
|
||||||
sessionidt far; // far end session ID
|
sessionidt far; // far end session ID
|
||||||
|
|
@ -199,7 +199,9 @@ typedef struct sessions
|
||||||
ipt snoop_ip; // Interception destination IP
|
ipt snoop_ip; // Interception destination IP
|
||||||
u16 snoop_port; // Interception destination port
|
u16 snoop_port; // Interception destination port
|
||||||
u16 sid; // near end session id.
|
u16 sid; // near end session id.
|
||||||
char reserved[20]; // Space to expand structure without changing HB_VERSION
|
u8 filter_in; // input filter index (to ip_filters[N-1]; 0 if none)
|
||||||
|
u8 filter_out; // output filter index
|
||||||
|
char reserved[18]; // Space to expand structure without changing HB_VERSION
|
||||||
}
|
}
|
||||||
sessiont;
|
sessiont;
|
||||||
|
|
||||||
|
|
@ -207,7 +209,8 @@ sessiont;
|
||||||
#define SF_LCP_ACKED 2 // LCP negotiated
|
#define SF_LCP_ACKED 2 // LCP negotiated
|
||||||
#define SF_CCP_ACKED 4 // CCP negotiated
|
#define SF_CCP_ACKED 4 // CCP negotiated
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
u32 cin;
|
u32 cin;
|
||||||
u32 cout;
|
u32 cout;
|
||||||
} sessioncountt;
|
} sessioncountt;
|
||||||
|
|
@ -216,7 +219,7 @@ typedef struct {
|
||||||
#define SESSIONACFC 2 // ACFC negotiated flags
|
#define SESSIONACFC 2 // ACFC negotiated flags
|
||||||
|
|
||||||
// 168 bytes per tunnel
|
// 168 bytes per tunnel
|
||||||
typedef struct tunnels
|
typedef struct
|
||||||
{
|
{
|
||||||
tunnelidt far; // far end tunnel ID
|
tunnelidt far; // far end tunnel ID
|
||||||
ipt ip; // Ip for far end
|
ipt ip; // Ip for far end
|
||||||
|
|
@ -239,7 +242,7 @@ typedef struct tunnels
|
||||||
tunnelt;
|
tunnelt;
|
||||||
|
|
||||||
// 180 bytes per radius session
|
// 180 bytes per radius session
|
||||||
typedef struct radiuss // outstanding RADIUS requests
|
typedef struct // outstanding RADIUS requests
|
||||||
{
|
{
|
||||||
sessionidt session; // which session this applies to
|
sessionidt session; // which session this applies to
|
||||||
hasht auth; // request authenticator
|
hasht auth; // request authenticator
|
||||||
|
|
@ -393,7 +396,7 @@ struct Tstats
|
||||||
#define SET_STAT(x, y)
|
#define SET_STAT(x, y)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct configt
|
typedef struct
|
||||||
{
|
{
|
||||||
int debug; // debugging level
|
int debug; // debugging level
|
||||||
time_t start_time; // time when l2tpns was started
|
time_t start_time; // time when l2tpns was started
|
||||||
|
|
@ -470,16 +473,65 @@ struct configt
|
||||||
int hold;
|
int hold;
|
||||||
} neighbour[BGP_NUM_PEERS];
|
} neighbour[BGP_NUM_PEERS];
|
||||||
#endif
|
#endif
|
||||||
};
|
} configt;
|
||||||
|
|
||||||
enum config_typet { INT, STRING, UNSIGNED_LONG, SHORT, BOOL, IP, MAC };
|
enum config_typet { INT, STRING, UNSIGNED_LONG, SHORT, BOOL, IP, MAC };
|
||||||
struct config_descriptt
|
typedef struct
|
||||||
{
|
{
|
||||||
char *key;
|
char *key;
|
||||||
int offset;
|
int offset;
|
||||||
int size;
|
int size;
|
||||||
enum config_typet type;
|
enum config_typet type;
|
||||||
};
|
} config_descriptt;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u8 op; // operation
|
||||||
|
#define FILTER_PORT_OP_NONE 0 // all ports match
|
||||||
|
#define FILTER_PORT_OP_EQ 1
|
||||||
|
#define FILTER_PORT_OP_NEQ 2
|
||||||
|
#define FILTER_PORT_OP_GT 3
|
||||||
|
#define FILTER_PORT_OP_LT 4
|
||||||
|
#define FILTER_PORT_OP_RANGE 5
|
||||||
|
portt port;
|
||||||
|
portt port2; // for range
|
||||||
|
} ip_filter_portt;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int action; // permit/deny
|
||||||
|
#define FILTER_ACTION_DENY 1
|
||||||
|
#define FILTER_ACTION_PERMIT 2
|
||||||
|
int proto; // protocol: IPPROTO_* (netinet/in.h)
|
||||||
|
ipt src_ip; // source ip
|
||||||
|
ipt src_wild;
|
||||||
|
ip_filter_portt src_ports;
|
||||||
|
ipt dst_ip; // dest ip
|
||||||
|
ipt dst_wild;
|
||||||
|
ip_filter_portt dst_ports;
|
||||||
|
u8 tcp_flag_op; // match type: any, all
|
||||||
|
#define FILTER_FLAG_OP_ANY 0
|
||||||
|
#define FILTER_FLAG_OP_ALL 1
|
||||||
|
u8 tcp_sflags; // flags set
|
||||||
|
u8 tcp_cflags; // flags clear
|
||||||
|
} ip_filter_rulet;
|
||||||
|
|
||||||
|
#define TCP_FLAG_FIN 0x01
|
||||||
|
#define TCP_FLAG_SYN 0x02
|
||||||
|
#define TCP_FLAG_RST 0x04
|
||||||
|
#define TCP_FLAG_PSH 0x08
|
||||||
|
#define TCP_FLAG_ACK 0x10
|
||||||
|
#define TCP_FLAG_URG 0x20
|
||||||
|
|
||||||
|
#define MAXFILTER 32
|
||||||
|
#define MAXFILTER_RULES 32
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char name[32]; // ACL name
|
||||||
|
int extended; // type: 0 = standard, 1 = extended
|
||||||
|
ip_filter_rulet rules[MAXFILTER_RULES];
|
||||||
|
int used; // session ref count
|
||||||
|
} ip_filtert;
|
||||||
|
|
||||||
// arp.c
|
// arp.c
|
||||||
void sendarp(int ifr_idx, const unsigned char* mac, ipt ip);
|
void sendarp(int ifr_idx, const unsigned char* mac, ipt ip);
|
||||||
|
|
@ -570,7 +622,7 @@ if (count++ < max) { \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern struct configt *config;
|
extern configt *config;
|
||||||
extern time_t basetime; // Time when this process started.
|
extern time_t basetime; // Time when this process started.
|
||||||
extern time_t time_now; // Seconds since EPOCH.
|
extern time_t time_now; // Seconds since EPOCH.
|
||||||
extern u32 last_id;
|
extern u32 last_id;
|
||||||
|
|
|
||||||
|
|
@ -43,5 +43,5 @@ rm -rf %{buildroot}
|
||||||
%attr(644,root,root) /usr/share/man/man[58]/*
|
%attr(644,root,root) /usr/share/man/man[58]/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Thu Nov 25 2004 Brendan O'Dea <bod@optusnet.com.au> 2.0.9-1
|
* Sat Nov 27 2004 Brendan O'Dea <bod@optusnet.com.au> 2.0.9-1
|
||||||
- 2.0.9 release, see /usr/share/doc/l2tpns-2.0.9/Changes
|
- 2.0.9 release, see /usr/share/doc/l2tpns-2.0.9/Changes
|
||||||
|
|
|
||||||
4
ppp.c
4
ppp.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS PPP Stuff
|
// L2TPNS PPP Stuff
|
||||||
|
|
||||||
char const *cvs_id_ppp = "$Id: ppp.c,v 1.30 2004/11/25 12:46:48 bodea Exp $";
|
char const *cvs_id_ppp = "$Id: ppp.c,v 1.31 2004/11/27 05:19:53 bodea Exp $";
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -21,7 +21,7 @@ extern int tunfd;
|
||||||
extern char hostname[];
|
extern char hostname[];
|
||||||
extern u32 eth_tx;
|
extern u32 eth_tx;
|
||||||
extern time_t time_now;
|
extern time_t time_now;
|
||||||
extern struct configt *config;
|
extern configt *config;
|
||||||
|
|
||||||
static void initccp(tunnelidt t, sessionidt s);
|
static void initccp(tunnelidt t, sessionidt s);
|
||||||
|
|
||||||
|
|
|
||||||
4
radius.c
4
radius.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS Radius Stuff
|
// L2TPNS Radius Stuff
|
||||||
|
|
||||||
char const *cvs_id_radius = "$Id: radius.c,v 1.13 2004/11/25 02:45:27 bodea Exp $";
|
char const *cvs_id_radius = "$Id: radius.c,v 1.14 2004/11/27 05:19:53 bodea Exp $";
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -22,7 +22,7 @@ extern radiust *radius;
|
||||||
extern sessiont *session;
|
extern sessiont *session;
|
||||||
extern tunnelt *tunnel;
|
extern tunnelt *tunnel;
|
||||||
extern u32 sessionid;
|
extern u32 sessionid;
|
||||||
extern struct configt *config;
|
extern configt *config;
|
||||||
extern int *radfds;
|
extern int *radfds;
|
||||||
|
|
||||||
static const char *radius_state(int state)
|
static const char *radius_state(int state)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue