add Acct-Terminate-Cause to RADIUS stop records
This commit is contained in:
parent
0251304ce2
commit
1b6a7a95e6
8 changed files with 186 additions and 50 deletions
3
Changes
3
Changes
|
|
@ -1,8 +1,9 @@
|
||||||
* Wed Apr 5 2006 Brendan O'Dea <bod@optus.net> 2.1.17
|
* Thu Apr 13 2006 Brendan O'Dea <bod@optus.net> 2.1.17
|
||||||
- Fix IPCP length test to allow Terminate-Request (4 bytes).
|
- Fix IPCP length test to allow Terminate-Request (4 bytes).
|
||||||
- Send nsctl responses back using the correct source address (thanks ltd).
|
- Send nsctl responses back using the correct source address (thanks ltd).
|
||||||
- Similarly set the source for DAE responses; use bind_address when
|
- Similarly set the source for DAE responses; use bind_address when
|
||||||
handling forwarded packets on the master.
|
handling forwarded packets on the master.
|
||||||
|
- Add Acct-Terminate-Cause to RADIUS stop records.
|
||||||
|
|
||||||
* Thu Feb 23 2006 Brendan O'Dea <bod@optus.net> 2.1.16
|
* Thu Feb 23 2006 Brendan O'Dea <bod@optus.net> 2.1.16
|
||||||
- Send configured magic-no in LCP EchoReq when LCP is opened.
|
- Send configured magic-no in LCP EchoReq when LCP is opened.
|
||||||
|
|
|
||||||
123
l2tpns.c
123
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.159 2006-04-05 02:13:48 bodea Exp $";
|
char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.160 2006-04-13 11:14:35 bodea Exp $";
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
@ -1559,7 +1559,7 @@ void filter_session(sessionidt s, int filter_in, int filter_out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// start tidy shutdown of session
|
// start tidy shutdown of session
|
||||||
void sessionshutdown(sessionidt s, char *reason, int result, int error)
|
void sessionshutdown(sessionidt s, char const *reason, int cdn_result, int cdn_error, int term_cause)
|
||||||
{
|
{
|
||||||
int walled_garden = session[s].walled_garden;
|
int walled_garden = session[s].walled_garden;
|
||||||
|
|
||||||
|
|
@ -1587,8 +1587,12 @@ void sessionshutdown(sessionidt s, char *reason, int result, int error)
|
||||||
{
|
{
|
||||||
// stop, if not already trying
|
// stop, if not already trying
|
||||||
if (radius[r].state != RADIUSSTOP)
|
if (radius[r].state != RADIUSSTOP)
|
||||||
|
{
|
||||||
|
radius[r].term_cause = term_cause;
|
||||||
|
radius[r].term_msg = reason;
|
||||||
radiussend(r, RADIUSSTOP);
|
radiussend(r, RADIUSSTOP);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
LOG(1, s, session[s].tunnel, "No free RADIUS sessions for Stop message\n");
|
LOG(1, s, session[s].tunnel, "No free RADIUS sessions for Stop message\n");
|
||||||
|
|
||||||
|
|
@ -1627,18 +1631,18 @@ void sessionshutdown(sessionidt s, char *reason, int result, int error)
|
||||||
if (session[s].throttle_in || session[s].throttle_out) // Unthrottle if throttled.
|
if (session[s].throttle_in || session[s].throttle_out) // Unthrottle if throttled.
|
||||||
throttle_session(s, 0, 0);
|
throttle_session(s, 0, 0);
|
||||||
|
|
||||||
if (result)
|
if (cdn_result)
|
||||||
{ // Send CDN
|
{ // Send CDN
|
||||||
controlt *c = controlnew(14); // sending CDN
|
controlt *c = controlnew(14); // sending CDN
|
||||||
if (error)
|
if (cdn_error)
|
||||||
{
|
{
|
||||||
uint8_t buf[4];
|
uint8_t buf[4];
|
||||||
*(uint16_t *) buf = htons(result);
|
*(uint16_t *) buf = htons(cdn_result);
|
||||||
*(uint16_t *) (buf+2) = htons(error);
|
*(uint16_t *) (buf+2) = htons(cdn_error);
|
||||||
controlb(c, 1, buf, 4, 1);
|
controlb(c, 1, buf, 4, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
control16(c, 1, result, 1);
|
control16(c, 1, cdn_result, 1);
|
||||||
|
|
||||||
control16(c, 14, s, 1); // assigned session (our end)
|
control16(c, 14, s, 1); // assigned session (our end)
|
||||||
controladd(c, session[s].far, session[s].tunnel); // send the message
|
controladd(c, session[s].far, session[s].tunnel); // send the message
|
||||||
|
|
@ -1744,7 +1748,7 @@ void sessionkill(sessionidt s, char *reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
session[s].die = TIME;
|
session[s].die = TIME;
|
||||||
sessionshutdown(s, reason, 3, 0); // close radius/routes, etc.
|
sessionshutdown(s, reason, CDN_ADMIN_DISC, TERM_ADMIN_RESET); // close radius/routes, etc.
|
||||||
if (sess_local[s].radius)
|
if (sess_local[s].radius)
|
||||||
radiusclear(sess_local[s].radius, s); // cant send clean accounting data, session is killed
|
radiusclear(sess_local[s].radius, s); // cant send clean accounting data, session is killed
|
||||||
|
|
||||||
|
|
@ -1809,7 +1813,7 @@ static void tunnelshutdown(tunnelidt t, char *reason, int result, int error, cha
|
||||||
// close session
|
// close session
|
||||||
for (s = 1; s <= config->cluster_highest_sessionid ; ++s)
|
for (s = 1; s <= config->cluster_highest_sessionid ; ++s)
|
||||||
if (session[s].tunnel == t)
|
if (session[s].tunnel == t)
|
||||||
sessionshutdown(s, reason, 0, 0);
|
sessionshutdown(s, reason, CDN_NONE, TERM_ADMIN_RESET);
|
||||||
|
|
||||||
tunnel[t].state = TUNNELDIE;
|
tunnel[t].state = TUNNELDIE;
|
||||||
tunnel[t].die = TIME + 700; // Clean up in 70 seconds
|
tunnel[t].die = TIME + 700; // Clean up in 70 seconds
|
||||||
|
|
@ -2048,6 +2052,12 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
int error = 0;
|
int error = 0;
|
||||||
char *msg = 0;
|
char *msg = 0;
|
||||||
|
|
||||||
|
// default disconnect cause/message on receipt
|
||||||
|
// of CDN (set to more specific value from
|
||||||
|
// attribute 46 if present below).
|
||||||
|
int disc_cause = TERM_NAS_REQUEST;
|
||||||
|
char const *disc_reason = "Closed (Received CDN).";
|
||||||
|
|
||||||
// process AVPs
|
// process AVPs
|
||||||
while (l && !(fatal & 0x80)) // 0x80 = mandatory AVP
|
while (l && !(fatal & 0x80)) // 0x80 = mandatory AVP
|
||||||
{
|
{
|
||||||
|
|
@ -2055,6 +2065,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
uint8_t *b = p;
|
uint8_t *b = p;
|
||||||
uint8_t flags = *p;
|
uint8_t flags = *p;
|
||||||
uint16_t mtype;
|
uint16_t mtype;
|
||||||
|
|
||||||
if (n > l)
|
if (n > l)
|
||||||
{
|
{
|
||||||
LOG(1, s, t, "Invalid length in AVP\n");
|
LOG(1, s, t, "Invalid length in AVP\n");
|
||||||
|
|
@ -2191,17 +2202,13 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3: // framing capabilities
|
case 3: // framing capabilities
|
||||||
// LOG(4, s, t, "Framing capabilities\n");
|
|
||||||
break;
|
break;
|
||||||
case 4: // bearer capabilities
|
case 4: // bearer capabilities
|
||||||
// LOG(4, s, t, "Bearer capabilities\n");
|
|
||||||
break;
|
break;
|
||||||
case 5: // tie breaker
|
case 5: // tie breaker
|
||||||
// We never open tunnels, so we don't care about tie breakers
|
// We never open tunnels, so we don't care about tie breakers
|
||||||
// LOG(4, s, t, "Tie breaker\n");
|
|
||||||
continue;
|
continue;
|
||||||
case 6: // firmware revision
|
case 6: // firmware revision
|
||||||
// LOG(4, s, t, "Firmware revision\n");
|
|
||||||
break;
|
break;
|
||||||
case 7: // host name
|
case 7: // host name
|
||||||
memset(tunnel[t].hostname, 0, sizeof(tunnel[t].hostname));
|
memset(tunnel[t].hostname, 0, sizeof(tunnel[t].hostname));
|
||||||
|
|
@ -2356,6 +2363,84 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
memcpy(session[s].random_vector, b, n);
|
memcpy(session[s].random_vector, b, n);
|
||||||
session[s].random_vector_length = n;
|
session[s].random_vector_length = n;
|
||||||
break;
|
break;
|
||||||
|
case 46: // ppp disconnect cause
|
||||||
|
if (n >= 5)
|
||||||
|
{
|
||||||
|
uint16_t code = ntohs(*(uint16_t *) b);
|
||||||
|
uint16_t proto = ntohs(*(uint16_t *) (b + 2));
|
||||||
|
uint8_t dir = *(b + 4);
|
||||||
|
|
||||||
|
LOG(4, s, t, " PPP disconnect cause "
|
||||||
|
"(code=%u, proto=%04X, dir=%u, msg=\"%.*s\")\n",
|
||||||
|
code, proto, dir, n - 5, b + 5);
|
||||||
|
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case 1: // admin disconnect
|
||||||
|
disc_cause = TERM_ADMIN_RESET;
|
||||||
|
disc_reason = "Administrative disconnect";
|
||||||
|
break;
|
||||||
|
case 3: // lcp terminate
|
||||||
|
if (dir != 1) break; // 1=peer, 2=local
|
||||||
|
disc_cause = TERM_USER_REQUEST;
|
||||||
|
disc_reason = "Normal disconnection";
|
||||||
|
break;
|
||||||
|
case 4: // compulsory encryption unavailable
|
||||||
|
if (dir != 2) break; // 1=refused by peer, 2=local
|
||||||
|
disc_cause = TERM_USER_ERROR;
|
||||||
|
disc_reason = "Compulsory encryption refused";
|
||||||
|
break;
|
||||||
|
case 5: // lcp: fsm timeout
|
||||||
|
disc_cause = TERM_PORT_ERROR;
|
||||||
|
disc_reason = "LCP: FSM timeout";
|
||||||
|
break;
|
||||||
|
case 6: // lcp: no recognisable lcp packets received
|
||||||
|
disc_cause = TERM_PORT_ERROR;
|
||||||
|
disc_reason = "LCP: no recognisable LCP packets";
|
||||||
|
break;
|
||||||
|
case 7: // lcp: magic-no error (possibly looped back)
|
||||||
|
disc_cause = TERM_PORT_ERROR;
|
||||||
|
disc_reason = "LCP: magic-no error (possible loop)";
|
||||||
|
break;
|
||||||
|
case 8: // lcp: echo request timeout
|
||||||
|
disc_cause = TERM_PORT_ERROR;
|
||||||
|
disc_reason = "LCP: echo request timeout";
|
||||||
|
break;
|
||||||
|
case 13: // auth: fsm timeout
|
||||||
|
disc_cause = TERM_SERVICE_UNAVAILABLE;
|
||||||
|
disc_reason = "Authentication: FSM timeout";
|
||||||
|
break;
|
||||||
|
case 15: // auth: unacceptable auth protocol
|
||||||
|
disc_cause = TERM_SERVICE_UNAVAILABLE;
|
||||||
|
disc_reason = "Unacceptable authentication protocol";
|
||||||
|
break;
|
||||||
|
case 16: // auth: authentication failed
|
||||||
|
disc_cause = TERM_SERVICE_UNAVAILABLE;
|
||||||
|
disc_reason = "Authentication failed";
|
||||||
|
break;
|
||||||
|
case 17: // ncp: fsm timeout
|
||||||
|
disc_cause = TERM_SERVICE_UNAVAILABLE;
|
||||||
|
disc_reason = "NCP: FSM timeout";
|
||||||
|
break;
|
||||||
|
case 18: // ncp: no ncps available
|
||||||
|
disc_cause = TERM_SERVICE_UNAVAILABLE;
|
||||||
|
disc_reason = "NCP: no NCPs available";
|
||||||
|
break;
|
||||||
|
case 19: // ncp: failure to converge on acceptable address
|
||||||
|
disc_cause = TERM_SERVICE_UNAVAILABLE;
|
||||||
|
disc_reason = (dir == 1)
|
||||||
|
? "NCP: too many Configure-Naks received from peer"
|
||||||
|
: "NCP: too many Configure-Naks sent to peer";
|
||||||
|
break;
|
||||||
|
case 20: // ncp: user not permitted to use any address
|
||||||
|
disc_cause = TERM_SERVICE_UNAVAILABLE;
|
||||||
|
disc_reason = (dir == 1)
|
||||||
|
? "NCP: local link address not acceptable to peer"
|
||||||
|
: "NCP: remote link address not acceptable";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
static char e[] = "unknown AVP 0xXXXX";
|
static char e[] = "unknown AVP 0xXXXX";
|
||||||
|
|
@ -2477,7 +2562,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
|
|
||||||
case 14: // CDN
|
case 14: // CDN
|
||||||
controlnull(t); // ack
|
controlnull(t); // ack
|
||||||
sessionshutdown(s, "Closed (Received CDN).", 0, 0);
|
sessionshutdown(s, disc_reason, CDN_NONE, disc_cause);
|
||||||
break;
|
break;
|
||||||
case 0xFFFF:
|
case 0xFFFF:
|
||||||
LOG(1, s, t, "Missing message type\n");
|
LOG(1, s, t, "Missing message type\n");
|
||||||
|
|
@ -2807,7 +2892,7 @@ static void regular_cleanups(double period)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sessionshutdown(s, "No response to LCP ConfigReq.", 3, 0);
|
sessionshutdown(s, "No response to LCP ConfigReq.", CDN_ADMIN_DISC, TERM_LOST_SERVICE);
|
||||||
STAT(session_timeout);
|
STAT(session_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2836,7 +2921,7 @@ static void regular_cleanups(double period)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sessionshutdown(s, "No response to IPCP ConfigReq.", 3, 0);
|
sessionshutdown(s, "No response to IPCP ConfigReq.", CDN_ADMIN_DISC, TERM_LOST_SERVICE);
|
||||||
STAT(session_timeout);
|
STAT(session_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2902,7 +2987,7 @@ static void regular_cleanups(double period)
|
||||||
// Drop sessions who have not responded within IDLE_TIMEOUT seconds
|
// Drop sessions who have not responded within IDLE_TIMEOUT seconds
|
||||||
if (session[s].last_packet && (time_now - session[s].last_packet >= IDLE_TIMEOUT))
|
if (session[s].last_packet && (time_now - session[s].last_packet >= IDLE_TIMEOUT))
|
||||||
{
|
{
|
||||||
sessionshutdown(s, "No response to LCP ECHO requests.", 3, 0);
|
sessionshutdown(s, "No response to LCP ECHO requests.", CDN_ADMIN_DISC, TERM_LOST_SERVICE);
|
||||||
STAT(session_timeout);
|
STAT(session_timeout);
|
||||||
s_actions++;
|
s_actions++;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -2938,7 +3023,7 @@ static void regular_cleanups(double period)
|
||||||
if (a & CLI_SESS_KILL)
|
if (a & CLI_SESS_KILL)
|
||||||
{
|
{
|
||||||
LOG(2, s, session[s].tunnel, "Dropping session by CLI\n");
|
LOG(2, s, session[s].tunnel, "Dropping session by CLI\n");
|
||||||
sessionshutdown(s, "Requested by administrator.", 3, 0);
|
sessionshutdown(s, "Requested by administrator.", CDN_ADMIN_DISC, TERM_ADMIN_RESET);
|
||||||
a = 0; // dead, no need to check for other actions
|
a = 0; // dead, no need to check for other actions
|
||||||
s_actions++;
|
s_actions++;
|
||||||
}
|
}
|
||||||
|
|
@ -4502,7 +4587,7 @@ int sessionsetup(sessionidt s, tunnelidt t)
|
||||||
if (!session[s].ip)
|
if (!session[s].ip)
|
||||||
{
|
{
|
||||||
LOG(0, s, t, " No IP allocated. The IP address pool is FULL!\n");
|
LOG(0, s, t, " No IP allocated. The IP address pool is FULL!\n");
|
||||||
sessionshutdown(s, "No IP addresses available.", 2, 7); // try another
|
sessionshutdown(s, "No IP addresses available.", CDN_TRY_ANOTHER, TERM_SERVICE_UNAVAILABLE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
LOG(3, s, t, " No IP allocated. Assigned %s from pool\n",
|
LOG(3, s, t, " No IP allocated. Assigned %s from pool\n",
|
||||||
|
|
|
||||||
38
l2tpns.h
38
l2tpns.h
|
|
@ -1,5 +1,5 @@
|
||||||
// L2TPNS Global Stuff
|
// L2TPNS Global Stuff
|
||||||
// $Id: l2tpns.h,v 1.111 2006-04-05 02:13:48 bodea Exp $
|
// $Id: l2tpns.h,v 1.112 2006-04-13 11:14:35 bodea Exp $
|
||||||
|
|
||||||
#ifndef __L2TPNS_H__
|
#ifndef __L2TPNS_H__
|
||||||
#define __L2TPNS_H__
|
#define __L2TPNS_H__
|
||||||
|
|
@ -345,7 +345,7 @@ typedef struct
|
||||||
}
|
}
|
||||||
tunnelt;
|
tunnelt;
|
||||||
|
|
||||||
// 160 bytes per radius session
|
// 164 bytes per radius session
|
||||||
typedef struct // outstanding RADIUS requests
|
typedef struct // outstanding RADIUS requests
|
||||||
{
|
{
|
||||||
sessionidt session; // which session this applies to
|
sessionidt session; // which session this applies to
|
||||||
|
|
@ -356,6 +356,8 @@ typedef struct // outstanding RADIUS requests
|
||||||
uint8_t try; // which try we are on
|
uint8_t try; // which try we are on
|
||||||
uint8_t state; // state of radius requests
|
uint8_t state; // state of radius requests
|
||||||
uint8_t chap; // set if CHAP used (is CHAP identifier)
|
uint8_t chap; // set if CHAP used (is CHAP identifier)
|
||||||
|
uint8_t term_cause; // Stop record: Acct-Terminate-Cause
|
||||||
|
char const *term_msg; // terminate reason
|
||||||
}
|
}
|
||||||
radiust;
|
radiust;
|
||||||
|
|
||||||
|
|
@ -674,6 +676,36 @@ typedef struct
|
||||||
int used; // session ref count
|
int used; // session ref count
|
||||||
} ip_filtert;
|
} ip_filtert;
|
||||||
|
|
||||||
|
// CDN result/error codes
|
||||||
|
#define CDN_NONE 0, 0
|
||||||
|
#define CDN_TRY_ANOTHER 2, 7
|
||||||
|
#define CDN_ADMIN_DISC 3, 0
|
||||||
|
#define CDN_UNAVAILABLE 4, 0
|
||||||
|
|
||||||
|
// RADIUS Acct-Terminate-Cause values
|
||||||
|
#define TERM_USER_REQUEST 1
|
||||||
|
#define TERM_LOST_CARRIER 2
|
||||||
|
#define TERM_LOST_SERVICE 3
|
||||||
|
#define TERM_IDLE_TIMEOUT 4
|
||||||
|
#define TERM_SESSION_TIMEOUT 5
|
||||||
|
#define TERM_ADMIN_RESET 6
|
||||||
|
#define TERM_ADMIN_REBOOT 7
|
||||||
|
#define TERM_PORT_ERROR 8
|
||||||
|
#define TERM_NAS_ERROR 9
|
||||||
|
#define TERM_NAS_REQUEST 10
|
||||||
|
#define TERM_NAS_REBOOT 11
|
||||||
|
#define TERM_PORT_UNNEEDED 12
|
||||||
|
#define TERM_PORT_PREEMPTED 13
|
||||||
|
#define TERM_PORT_SUSPENDED 14
|
||||||
|
#define TERM_SERVICE_UNAVAILABLE 15
|
||||||
|
#define TERM_CALLBACK 16
|
||||||
|
#define TERM_USER_ERROR 17
|
||||||
|
#define TERM_HOST_REQUEST 18
|
||||||
|
#define TERM_SUPPLICANT_RESTART 19
|
||||||
|
#define TERM_REAUTHENTICATION_FAILURE 20
|
||||||
|
#define TERM_PORT_REINIT 21
|
||||||
|
#define TERM_PORT_DISABLED 22
|
||||||
|
|
||||||
// arp.c
|
// arp.c
|
||||||
void sendarp(int ifr_idx, const unsigned char* mac, in_addr_t ip);
|
void sendarp(int ifr_idx, const unsigned char* mac, in_addr_t ip);
|
||||||
|
|
||||||
|
|
@ -716,7 +748,7 @@ sessionidt sessionbyuser(char *username);
|
||||||
void increment_counter(uint32_t *counter, uint32_t *wrap, uint32_t delta);
|
void increment_counter(uint32_t *counter, uint32_t *wrap, uint32_t delta);
|
||||||
void random_data(uint8_t *buf, int len);
|
void random_data(uint8_t *buf, int len);
|
||||||
void sessionkill(sessionidt s, char *reason);
|
void sessionkill(sessionidt s, char *reason);
|
||||||
void sessionshutdown(sessionidt s, char *reason, int result, int error);
|
void sessionshutdown(sessionidt s, char const *reason, int cdn_result, int cdn_error, int term_cause);
|
||||||
void filter_session(sessionidt s, int filter_in, int filter_out);
|
void filter_session(sessionidt s, int filter_in, int filter_out);
|
||||||
void send_garp(in_addr_t ip);
|
void send_garp(in_addr_t ip);
|
||||||
void tunnelsend(uint8_t *buf, uint16_t l, tunnelidt t);
|
void tunnelsend(uint8_t *buf, uint16_t l, tunnelidt t);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
* Wed Apr 5 2006 Brendan O'Dea <bod@optus.net> 2.1.17-1
|
* Thu Apr 13 2006 Brendan O'Dea <bod@optus.net> 2.1.17-1
|
||||||
- 2.1.17 release, see /usr/share/doc/l2tpns-2.1.17/Changes
|
- 2.1.17 release, see /usr/share/doc/l2tpns-2.1.17/Changes
|
||||||
|
|
|
||||||
4
plugin.h
4
plugin.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __PLUGIN_H__
|
#ifndef __PLUGIN_H__
|
||||||
#define __PLUGIN_H__
|
#define __PLUGIN_H__
|
||||||
|
|
||||||
#define PLUGIN_API_VERSION 6
|
#define PLUGIN_API_VERSION 7
|
||||||
#define MAX_PLUGIN_TYPES 30
|
#define MAX_PLUGIN_TYPES 30
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
|
@ -37,7 +37,7 @@ struct pluginfuncs
|
||||||
uint16_t (*radiusnew)(sessionidt s);
|
uint16_t (*radiusnew)(sessionidt s);
|
||||||
void (*radiussend)(uint16_t r, uint8_t state);
|
void (*radiussend)(uint16_t r, uint8_t state);
|
||||||
void *(*getconfig)(char *key, enum config_typet type);
|
void *(*getconfig)(char *key, enum config_typet type);
|
||||||
void (*sessionshutdown)(sessionidt s, char *reason, int result, int error);
|
void (*sessionshutdown)(sessionidt s, char const *reason, int result, int error, int term_cause);
|
||||||
void (*sessionkill)(sessionidt s, char *reason);
|
void (*sessionkill)(sessionidt s, char *reason);
|
||||||
void (*throttle)(sessionidt s, int rate_in, int rate_out);
|
void (*throttle)(sessionidt s, int rate_in, int rate_out);
|
||||||
int (*session_changed)(int sid);
|
int (*session_changed)(int sid);
|
||||||
|
|
|
||||||
34
ppp.c
34
ppp.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS PPP Stuff
|
// L2TPNS PPP Stuff
|
||||||
|
|
||||||
char const *cvs_id_ppp = "$Id: ppp.c,v 1.97 2006-03-27 03:01:08 bodea Exp $";
|
char const *cvs_id_ppp = "$Id: ppp.c,v 1.98 2006-04-13 11:14:35 bodea Exp $";
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -40,7 +40,7 @@ void processpap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
{
|
{
|
||||||
LOG(1, s, t, "Short PAP %u bytes\n", l);
|
LOG(1, s, t, "Short PAP %u bytes\n", l);
|
||||||
STAT(tunnel_rx_errors);
|
STAT(tunnel_rx_errors);
|
||||||
sessionshutdown(s, "Short PAP packet.", 3, 0);
|
sessionshutdown(s, "Short PAP packet.", CDN_ADMIN_DISC, TERM_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ void processpap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
{
|
{
|
||||||
LOG(1, s, t, "Length mismatch PAP %u/%u\n", hl, l);
|
LOG(1, s, t, "Length mismatch PAP %u/%u\n", hl, l);
|
||||||
STAT(tunnel_rx_errors);
|
STAT(tunnel_rx_errors);
|
||||||
sessionshutdown(s, "PAP length mismatch.", 3, 0);
|
sessionshutdown(s, "PAP length mismatch.", CDN_ADMIN_DISC, TERM_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
l = hl;
|
l = hl;
|
||||||
|
|
@ -57,7 +57,7 @@ void processpap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
{
|
{
|
||||||
LOG(1, s, t, "Unexpected PAP code %d\n", *p);
|
LOG(1, s, t, "Unexpected PAP code %d\n", *p);
|
||||||
STAT(tunnel_rx_errors);
|
STAT(tunnel_rx_errors);
|
||||||
sessionshutdown(s, "Unexpected PAP code.", 3, 0);
|
sessionshutdown(s, "Unexpected PAP code.", CDN_ADMIN_DISC, TERM_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,7 +110,7 @@ void processpap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG(1, s, t, "No RADIUS session available to authenticate session...\n");
|
LOG(1, s, t, "No RADIUS session available to authenticate session...\n");
|
||||||
sessionshutdown(s, "No free RADIUS sessions.", 4, 0);
|
sessionshutdown(s, "No free RADIUS sessions.", CDN_UNAVAILABLE, TERM_SERVICE_UNAVAILABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -152,7 +152,7 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
{
|
{
|
||||||
LOG(1, s, t, "Short CHAP %u bytes\n", l);
|
LOG(1, s, t, "Short CHAP %u bytes\n", l);
|
||||||
STAT(tunnel_rx_errors);
|
STAT(tunnel_rx_errors);
|
||||||
sessionshutdown(s, "Short CHAP packet.", 3, 0);
|
sessionshutdown(s, "Short CHAP packet.", CDN_ADMIN_DISC, TERM_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,7 +160,7 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
{
|
{
|
||||||
LOG(1, s, t, "Length mismatch CHAP %u/%u\n", hl, l);
|
LOG(1, s, t, "Length mismatch CHAP %u/%u\n", hl, l);
|
||||||
STAT(tunnel_rx_errors);
|
STAT(tunnel_rx_errors);
|
||||||
sessionshutdown(s, "CHAP length mismatch.", 3, 0);
|
sessionshutdown(s, "CHAP length mismatch.", CDN_ADMIN_DISC, TERM_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
l = hl;
|
l = hl;
|
||||||
|
|
@ -169,7 +169,7 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
{
|
{
|
||||||
LOG(1, s, t, "Unexpected CHAP response code %d\n", *p);
|
LOG(1, s, t, "Unexpected CHAP response code %d\n", *p);
|
||||||
STAT(tunnel_rx_errors);
|
STAT(tunnel_rx_errors);
|
||||||
sessionshutdown(s, "CHAP length mismatch.", 3, 0);
|
sessionshutdown(s, "CHAP length mismatch.", CDN_ADMIN_DISC, TERM_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,7 +190,7 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
{
|
{
|
||||||
LOG(1, s, t, "Wrong CHAP response ID %d (should be %d) (%d)\n", p[1], radius[r].id, r);
|
LOG(1, s, t, "Wrong CHAP response ID %d (should be %d) (%d)\n", p[1], radius[r].id, r);
|
||||||
STAT(tunnel_rx_errors);
|
STAT(tunnel_rx_errors);
|
||||||
sessionshutdown(s, "Unexpected CHAP response ID.", 3, 0);
|
sessionshutdown(s, "Unexpected CHAP response ID.", CDN_ADMIN_DISC, TERM_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,7 +198,7 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
{
|
{
|
||||||
LOG(1, s, t, "Bad CHAP response length %d\n", l < 5 ? -1 : p[4]);
|
LOG(1, s, t, "Bad CHAP response length %d\n", l < 5 ? -1 : p[4]);
|
||||||
STAT(tunnel_rx_errors);
|
STAT(tunnel_rx_errors);
|
||||||
sessionshutdown(s, "Bad CHAP response length.", 3, 0);
|
sessionshutdown(s, "Bad CHAP response length.", CDN_ADMIN_DISC, TERM_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,7 +208,7 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
{
|
{
|
||||||
LOG(1, s, t, "CHAP user too long %d\n", l - 16);
|
LOG(1, s, t, "CHAP user too long %d\n", l - 16);
|
||||||
STAT(tunnel_rx_errors);
|
STAT(tunnel_rx_errors);
|
||||||
sessionshutdown(s, "CHAP username too long.", 3, 0);
|
sessionshutdown(s, "CHAP username too long.", CDN_ADMIN_DISC, TERM_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -814,7 +814,7 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG(2, s, t, "LCP: remote sent %s for type %u?\n", ppp_code(*p), type);
|
LOG(2, s, t, "LCP: remote sent %s for type %u?\n", ppp_code(*p), type);
|
||||||
sessionshutdown(s, "Unable to negotiate LCP.", 3, 0);
|
sessionshutdown(s, "Unable to negotiate LCP.", CDN_ADMIN_DISC, TERM_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
x -= length;
|
x -= length;
|
||||||
|
|
@ -823,7 +823,7 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
|
|
||||||
if (!authtype)
|
if (!authtype)
|
||||||
{
|
{
|
||||||
sessionshutdown(s, "Unsupported authentication.", 3, 0);
|
sessionshutdown(s, "Unsupported authentication.", CDN_ADMIN_DISC, TERM_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -878,11 +878,11 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
if (config->debug > 3) dumplcp(q, l);
|
if (config->debug > 3) dumplcp(q, l);
|
||||||
|
|
||||||
tunnelsend(b, l + (q - b), t); // send it
|
tunnelsend(b, l + (q - b), t); // send it
|
||||||
sessionshutdown(s, "Remote end closed connection.", 3, 0);
|
sessionshutdown(s, "Remote end closed connection.", CDN_ADMIN_DISC, TERM_USER_REQUEST);
|
||||||
}
|
}
|
||||||
else if (*p == TerminateAck)
|
else if (*p == TerminateAck)
|
||||||
{
|
{
|
||||||
sessionshutdown(s, "Connection closed.", 3, 0);
|
sessionshutdown(s, "Connection closed.", CDN_ADMIN_DISC, TERM_NAS_REQUEST);
|
||||||
}
|
}
|
||||||
else if (*p == ProtocolRej)
|
else if (*p == ProtocolRej)
|
||||||
{
|
{
|
||||||
|
|
@ -1039,7 +1039,7 @@ void processipcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
q = ppp_conf_nak(s, b, sizeof(b), PPPIPCP, &response, q, p, o, (uint8_t *) &addr, sizeof(addr));
|
q = ppp_conf_nak(s, b, sizeof(b), PPPIPCP, &response, q, p, o, (uint8_t *) &addr, sizeof(addr));
|
||||||
if (!q || (q != oq && *response == ConfigRej))
|
if (!q || (q != oq && *response == ConfigRej))
|
||||||
{
|
{
|
||||||
sessionshutdown(s, "Can't negotiate IPCP.", 3, 0);
|
sessionshutdown(s, "Can't negotiate IPCP.", CDN_ADMIN_DISC, TERM_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1757,7 +1757,7 @@ void sendchap(sessionidt s, tunnelidt t)
|
||||||
radius[r].retry = backoff(radius[r].try++);
|
radius[r].retry = backoff(radius[r].try++);
|
||||||
if (radius[r].try > 5)
|
if (radius[r].try > 5)
|
||||||
{
|
{
|
||||||
sessionshutdown(s, "CHAP timeout.", 3, 0);
|
sessionshutdown(s, "CHAP timeout.", CDN_ADMIN_DISC, TERM_REAUTHENTICATION_FAILURE);
|
||||||
STAT(tunnel_tx_errors);
|
STAT(tunnel_tx_errors);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
28
radius.c
28
radius.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS Radius Stuff
|
// L2TPNS Radius Stuff
|
||||||
|
|
||||||
char const *cvs_id_radius = "$Id: radius.c,v 1.48 2006-04-05 02:13:48 bodea Exp $";
|
char const *cvs_id_radius = "$Id: radius.c,v 1.49 2006-04-13 11:14:35 bodea Exp $";
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -158,7 +158,7 @@ void radiussend(uint16_t r, uint8_t state)
|
||||||
if (s)
|
if (s)
|
||||||
{
|
{
|
||||||
if (state == RADIUSAUTH)
|
if (state == RADIUSAUTH)
|
||||||
sessionshutdown(s, "RADIUS timeout.", 3, 0);
|
sessionshutdown(s, "RADIUS timeout.", CDN_ADMIN_DISC, TERM_REAUTHENTICATION_FAILURE);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG(1, s, session[s].tunnel, "RADIUS timeout, but in state %s so don't timeout session\n",
|
LOG(1, s, session[s].tunnel, "RADIUS timeout, but in state %s so don't timeout session\n",
|
||||||
|
|
@ -248,8 +248,8 @@ void radiussend(uint16_t r, uint8_t state)
|
||||||
p += p[1];
|
p += p[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (state == RADIUSSTART || state == RADIUSSTOP || state == RADIUSINTERIM)
|
else // accounting
|
||||||
{ // accounting
|
{
|
||||||
*p = 40; // accounting type
|
*p = 40; // accounting type
|
||||||
p[1] = 6;
|
p[1] = 6;
|
||||||
*(uint32_t *) (p + 2) = htonl(state - RADIUSSTART + 1); // start=1, stop=2, interim=3
|
*(uint32_t *) (p + 2) = htonl(state - RADIUSSTART + 1); // start=1, stop=2, interim=3
|
||||||
|
|
@ -304,6 +304,24 @@ void radiussend(uint16_t r, uint8_t state)
|
||||||
p[1] = 6;
|
p[1] = 6;
|
||||||
*(uint32_t *) (p + 2) = htonl(session[s].cout_wrap);
|
*(uint32_t *) (p + 2) = htonl(session[s].cout_wrap);
|
||||||
p += p[1];
|
p += p[1];
|
||||||
|
|
||||||
|
if (state == RADIUSSTOP && radius[r].term_cause)
|
||||||
|
{
|
||||||
|
*p = 49; // acct-terminate-cause
|
||||||
|
p[1] = 6;
|
||||||
|
*(uint32_t *) (p + 2) = htonl(radius[r].term_cause);
|
||||||
|
p += p[1];
|
||||||
|
|
||||||
|
if (radius[r].term_msg)
|
||||||
|
{
|
||||||
|
*p = 26; // vendor-specific
|
||||||
|
*(uint32_t *) (p + 2) = htonl(9); // Cisco
|
||||||
|
p[6] = 1; // Cisco-AVPair
|
||||||
|
p[7] = 2 + sprintf((char *) p + 8, "disc-cause-ext=%s", radius[r].term_msg);
|
||||||
|
p[1] = p[7] + 6;
|
||||||
|
p += p[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -994,7 +1012,7 @@ void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen, struc
|
||||||
LOG(3, s, t, " DAE Disconnect %d (%s)\n", s, session[s].user);
|
LOG(3, s, t, " DAE Disconnect %d (%s)\n", s, session[s].user);
|
||||||
r_code = DisconnectACK;
|
r_code = DisconnectACK;
|
||||||
|
|
||||||
sessionshutdown(s, "Requested by PoD", 3, 0); // disconnect session
|
sessionshutdown(s, "Requested by PoD", CDN_ADMIN_DISC, TERM_ADMIN_RESET); // disconnect session
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CoARequest: // Change of Authorization
|
case CoARequest: // Change of Authorization
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
/* session control */
|
/* session control */
|
||||||
|
|
||||||
char const *cvs_id = "$Id: sessionctl.c,v 1.4 2005-10-11 09:04:53 bodea Exp $";
|
char const *cvs_id = "$Id: sessionctl.c,v 1.5 2006-04-13 11:14:35 bodea Exp $";
|
||||||
|
|
||||||
int plugin_api_version = PLUGIN_API_VERSION;
|
int plugin_api_version = PLUGIN_API_VERSION;
|
||||||
static struct pluginfuncs *f = 0;
|
static struct pluginfuncs *f = 0;
|
||||||
|
|
@ -58,7 +58,7 @@ int plugin_control(struct param_control *data)
|
||||||
reason = "Requested by administrator.";
|
reason = "Requested by administrator.";
|
||||||
|
|
||||||
if (data->argv[0][0] == 'd')
|
if (data->argv[0][0] == 'd')
|
||||||
f->sessionshutdown(session, reason, 3, 0);
|
f->sessionshutdown(session, reason, CDN_ADMIN_DISC, TERM_ADMIN_RESET);
|
||||||
else
|
else
|
||||||
f->sessionkill(session, reason);
|
f->sessionkill(session, reason);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue