add DAE support (PoD/CoA) from Vladislav Bjelic
This commit is contained in:
parent
659ed315c2
commit
4f253feef0
16 changed files with 604 additions and 158 deletions
3
Changes
3
Changes
|
|
@ -1,9 +1,10 @@
|
||||||
* Mon Jun 27 2005 Brendan O'Dea <bod@optus.net> 2.1.2
|
* Wed Jun 29 2005 Brendan O'Dea <bod@c47.org> 2.1.2
|
||||||
- Don't resend IPCP while still in progress.
|
- Don't resend IPCP while still in progress.
|
||||||
- Ignore duplicate ACKs for IPCP.
|
- Ignore duplicate ACKs for IPCP.
|
||||||
- Clear RADIUSIPCP for walled garden sessions on ACK.
|
- Clear RADIUSIPCP for walled garden sessions on ACK.
|
||||||
- Clear cluster_master on election so that slaves will accept a new master.
|
- Clear cluster_master on election so that slaves will accept a new master.
|
||||||
- Provide more comments/defaults in etc/startup-config.default.
|
- Provide more comments/defaults in etc/startup-config.default.
|
||||||
|
- Add DAE support (PoD/CoA) from Vladislav Bjelic.
|
||||||
|
|
||||||
* Tue Jun 14 2005 Brendan O'Dea <bod@optusnet.com.au> 2.1.1
|
* Tue Jun 14 2005 Brendan O'Dea <bod@optusnet.com.au> 2.1.1
|
||||||
- Add missing newline to backtrace macro.
|
- Add missing newline to backtrace macro.
|
||||||
|
|
|
||||||
|
|
@ -229,6 +229,11 @@ A comma separated list of supported RADIUS authentication methods
|
||||||
(<B>pap</B> or <B>chap</B>), in order of preference (default <B>pap</B>).
|
(<B>pap</B> or <B>chap</B>), in order of preference (default <B>pap</B>).
|
||||||
</LI>
|
</LI>
|
||||||
|
|
||||||
|
<LI><B>radius_dae_port</B> (short)<BR>
|
||||||
|
Port for DAE RADIUS (Packet of Death/Disconnect, Change of Authorization)
|
||||||
|
requests (default: <B>3799</B>).
|
||||||
|
</LI>
|
||||||
|
|
||||||
<LI><B>allow_duplicate_users</B> (boolean)</BR>
|
<LI><B>allow_duplicate_users</B> (boolean)</BR>
|
||||||
Allow multiple logins with the same username. If false (the default),
|
Allow multiple logins with the same username. If false (the default),
|
||||||
any prior session with the same username will be dropped when a new
|
any prior session with the same username will be dropped when a new
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
.de Id
|
.de Id
|
||||||
.ds Dt \\$4 \\$5
|
.ds Dt \\$4 \\$5
|
||||||
..
|
..
|
||||||
.Id $Id: startup-config.5,v 1.10 2005/06/02 11:32:33 bodea Exp $
|
.Id $Id: startup-config.5,v 1.11 2005/06/28 14:48:31 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
|
||||||
|
|
@ -100,6 +100,10 @@ Secret to be used in RADIUS packets.
|
||||||
A comma separated list of supported RADIUS authentication methods
|
A comma separated list of supported RADIUS authentication methods
|
||||||
("pap" or "chap"), in order of preference (default "pap").
|
("pap" or "chap"), in order of preference (default "pap").
|
||||||
.TP
|
.TP
|
||||||
|
.B radius_dae_port
|
||||||
|
Port for DAE RADIUS (Packet of Death/Disconnect, Change of Authorization)
|
||||||
|
requests (default: 3799).
|
||||||
|
.TP
|
||||||
.B allow_duplicate_users
|
.B allow_duplicate_users
|
||||||
Allow multiple logins with the same username. If false (the default),
|
Allow multiple logins with the same username. If false (the default),
|
||||||
any prior session with the same username will be dropped when a new
|
any prior session with the same username will be dropped when a new
|
||||||
|
|
|
||||||
19
cli.c
19
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.62 2005/06/07 05:31:43 bodea Exp $";
|
char const *cvs_id_cli = "$Id: cli.c,v 1.63 2005/06/28 14:48:17 bodea Exp $";
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
@ -2316,17 +2316,6 @@ static int cmd_restart_bgp(struct cli_def *cli, char *command, char **argv, int
|
||||||
#endif /* BGP*/
|
#endif /* BGP*/
|
||||||
|
|
||||||
static int filt;
|
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)
|
static int access_list(struct cli_def *cli, char **argv, int argc, int add)
|
||||||
{
|
{
|
||||||
int extended;
|
int extended;
|
||||||
|
|
@ -2377,7 +2366,7 @@ static int access_list(struct cli_def *cli, char **argv, int argc, int add)
|
||||||
return CLI_OK;
|
return CLI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
filt = find_access_list(argv[1]);
|
filt = find_filter(argv[1], strlen(argv[1]));
|
||||||
if (add)
|
if (add)
|
||||||
{
|
{
|
||||||
if (filt < 0)
|
if (filt < 0)
|
||||||
|
|
@ -2970,7 +2959,7 @@ static int cmd_filter(struct cli_def *cli, char *command, char **argv, int argc)
|
||||||
return CLI_OK;
|
return CLI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
v = find_access_list(argv[i+1]);
|
v = find_filter(argv[i+1], strlen(argv[i+1]));
|
||||||
if (v < 0 || !*ip_filters[v].name)
|
if (v < 0 || !*ip_filters[v].name)
|
||||||
{
|
{
|
||||||
cli_error(cli, "Access-list %s not defined", argv[i+1]);
|
cli_error(cli, "Access-list %s not defined", argv[i+1]);
|
||||||
|
|
@ -3046,7 +3035,7 @@ static int cmd_show_access_list(struct cli_def *cli, char *command, char **argv,
|
||||||
|
|
||||||
for (i = 0; i < argc; i++)
|
for (i = 0; i < argc; i++)
|
||||||
{
|
{
|
||||||
int f = find_access_list(argv[i]);
|
int f = find_filter(argv[i], strlen(argv[i]));
|
||||||
ip_filter_rulet *rules;
|
ip_filter_rulet *rules;
|
||||||
|
|
||||||
if (f < 0 || !*ip_filters[f].name)
|
if (f < 0 || !*ip_filters[f].name)
|
||||||
|
|
|
||||||
57
cluster.c
57
cluster.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS Clustering Stuff
|
// L2TPNS Clustering Stuff
|
||||||
|
|
||||||
char const *cvs_id_cluster = "$Id: cluster.c,v 1.43 2005/06/27 04:52:54 bodea Exp $";
|
char const *cvs_id_cluster = "$Id: cluster.c,v 1.44 2005/06/28 14:48:19 bodea Exp $";
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -270,13 +270,8 @@ static int peer_send_message(in_addr_t peer, int type, int more, char *data, int
|
||||||
return peer_send_data(peer, buf, (p-buf) );
|
return peer_send_data(peer, buf, (p-buf) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// send a packet to the master
|
||||||
// Forward a state changing packet to the master.
|
static int _forward_packet(char *data, int size, in_addr_t addr, int port, int type)
|
||||||
//
|
|
||||||
// The master just processes the payload as if it had
|
|
||||||
// received it off the tun device.
|
|
||||||
//
|
|
||||||
int master_forward_packet(char *data, int size, in_addr_t addr, int port)
|
|
||||||
{
|
{
|
||||||
char buf[65536]; // Vast overkill.
|
char buf[65536]; // Vast overkill.
|
||||||
char *p = buf;
|
char *p = buf;
|
||||||
|
|
@ -287,13 +282,30 @@ int master_forward_packet(char *data, int size, in_addr_t addr, int port)
|
||||||
LOG(4, 0, 0, "Forwarding packet from %s to master (size %d)\n", fmtaddr(addr, 0), size);
|
LOG(4, 0, 0, "Forwarding packet from %s to master (size %d)\n", fmtaddr(addr, 0), size);
|
||||||
|
|
||||||
STAT(c_forwarded);
|
STAT(c_forwarded);
|
||||||
add_type(&p, C_FORWARD, addr, (char *) &port, sizeof(port)); // ick. should be uint16_t
|
add_type(&p, type, addr, (char *) &port, sizeof(port)); // ick. should be uint16_t
|
||||||
memcpy(p, data, size);
|
memcpy(p, data, size);
|
||||||
p += size;
|
p += size;
|
||||||
|
|
||||||
return peer_send_data(config->cluster_master_address, buf, (p - buf));
|
return peer_send_data(config->cluster_master_address, buf, (p - buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Forward a state changing packet to the master.
|
||||||
|
//
|
||||||
|
// The master just processes the payload as if it had
|
||||||
|
// received it off the tun device.
|
||||||
|
//
|
||||||
|
int master_forward_packet(char *data, int size, in_addr_t addr, int port)
|
||||||
|
{
|
||||||
|
return _forward_packet(data, size, addr, port, C_FORWARD);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward a DAE RADIUS packet to the master.
|
||||||
|
int master_forward_dae_packet(char *data, int size, in_addr_t addr, int port)
|
||||||
|
{
|
||||||
|
return _forward_packet(data, size, addr, port, C_FORWARD_DAE);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Forward a throttled packet to the master for handling.
|
// Forward a throttled packet to the master for handling.
|
||||||
//
|
//
|
||||||
|
|
@ -1585,7 +1597,8 @@ int processcluster(char *data, int size, in_addr_t addr)
|
||||||
p += sizeof(uint32_t);
|
p += sizeof(uint32_t);
|
||||||
s -= sizeof(uint32_t);
|
s -= sizeof(uint32_t);
|
||||||
|
|
||||||
switch (type) {
|
switch (type)
|
||||||
|
{
|
||||||
case C_PING: // Update the peers table.
|
case C_PING: // Update the peers table.
|
||||||
return cluster_add_peer(addr, more, (pingt *) p, s);
|
return cluster_add_peer(addr, more, (pingt *) p, s);
|
||||||
|
|
||||||
|
|
@ -1595,7 +1608,17 @@ int processcluster(char *data, int size, in_addr_t addr)
|
||||||
case C_LASTSEEN: // Catch up a slave (slave missed a packet).
|
case C_LASTSEEN: // Catch up a slave (slave missed a packet).
|
||||||
return cluster_catchup_slave(more, addr);
|
return cluster_catchup_slave(more, addr);
|
||||||
|
|
||||||
case C_FORWARD: { // Forwarded control packet. pass off to processudp.
|
case C_FORWARD: // Forwarded control packet. pass off to processudp.
|
||||||
|
case C_FORWARD_DAE: // Forwarded DAE packet. pass off to processdae.
|
||||||
|
if (!config->cluster_iam_master)
|
||||||
|
{
|
||||||
|
LOG(0, 0, 0, "I'm not the master, but I got a C_FORWARD_%s from %s?\n",
|
||||||
|
type == C_FORWARD_DAE ? "_DAE" : "", fmtaddr(addr, 0));
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
struct sockaddr_in a;
|
struct sockaddr_in a;
|
||||||
a.sin_addr.s_addr = more;
|
a.sin_addr.s_addr = more;
|
||||||
|
|
||||||
|
|
@ -1603,16 +1626,18 @@ int processcluster(char *data, int size, in_addr_t addr)
|
||||||
s -= sizeof(int);
|
s -= sizeof(int);
|
||||||
p += sizeof(int);
|
p += sizeof(int);
|
||||||
|
|
||||||
if (!config->cluster_iam_master) { // huh?
|
LOG(4, 0, 0, "Got a forwarded %spacket... (%s:%d)\n",
|
||||||
LOG(0, 0, 0, "I'm not the master, but I got a C_FORWARD from %s?\n", fmtaddr(addr, 0));
|
type == C_FORWARD_DAE ? "DAE " : "", fmtaddr(more, 0), a.sin_port);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(4, 0, 0, "Got a forwarded packet... (%s:%d)\n", fmtaddr(more, 0), a.sin_port);
|
|
||||||
STAT(recv_forward);
|
STAT(recv_forward);
|
||||||
|
if (type == C_FORWARD_DAE)
|
||||||
|
processdae(p, s, &a, sizeof(a));
|
||||||
|
else
|
||||||
processudp(p, s, &a);
|
processudp(p, s, &a);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case C_THROTTLE: { // Receive a forwarded packet from a slave.
|
case C_THROTTLE: { // Receive a forwarded packet from a slave.
|
||||||
if (!config->cluster_iam_master) {
|
if (!config->cluster_iam_master) {
|
||||||
LOG(0, 0, 0, "I'm not the master, but I got a C_THROTTLE from %s?\n", fmtaddr(addr, 0));
|
LOG(0, 0, 0, "I'm not the master, but I got a C_THROTTLE from %s?\n", fmtaddr(addr, 0));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// L2TPNS Clustering Stuff
|
// L2TPNS Clustering Stuff
|
||||||
// $Id: cluster.h,v 1.12 2005/06/02 11:32:30 bodea Exp $
|
// $Id: cluster.h,v 1.13 2005/06/28 14:48:19 bodea Exp $
|
||||||
|
|
||||||
#ifndef __CLUSTER_H__
|
#ifndef __CLUSTER_H__
|
||||||
#define __CLUSTER_H__
|
#define __CLUSTER_H__
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#define C_CTUNNEL 13 // Compressed tunnel structure.
|
#define C_CTUNNEL 13 // Compressed tunnel structure.
|
||||||
#define C_GARDEN 14 // Gardened packet
|
#define C_GARDEN 14 // Gardened packet
|
||||||
#define C_MASTER 15 // Tell a slave the address of the master.
|
#define C_MASTER 15 // Tell a slave the address of the master.
|
||||||
|
#define C_FORWARD_DAE 16 // A DAE packet for the master to handle
|
||||||
|
|
||||||
#define HB_VERSION 5 // Protocol version number..
|
#define HB_VERSION 5 // Protocol version number..
|
||||||
#define HB_MAX_SEQ (1<<30) // Maximum sequence number. (MUST BE A POWER OF 2!)
|
#define HB_MAX_SEQ (1<<30) // Maximum sequence number. (MUST BE A POWER OF 2!)
|
||||||
|
|
@ -75,6 +76,7 @@ int processcluster(char *buf, int size, in_addr_t addr);
|
||||||
int cluster_send_session(int sid);
|
int cluster_send_session(int sid);
|
||||||
int cluster_send_tunnel(int tid);
|
int cluster_send_tunnel(int tid);
|
||||||
int master_forward_packet(char *data, int size, in_addr_t addr, int port);
|
int master_forward_packet(char *data, int size, in_addr_t addr, int port);
|
||||||
|
int master_forward_dae_packet(char *data, int size, in_addr_t addr, int port);
|
||||||
int master_throttle_packet(int tid, char *data, int size);
|
int master_throttle_packet(int tid, char *data, int size);
|
||||||
int master_garden_packet(sessionidt s, char *data, int size);
|
int master_garden_packet(sessionidt s, char *data, int size);
|
||||||
void master_update_counts(void);
|
void master_update_counts(void);
|
||||||
|
|
|
||||||
15
constants.c
15
constants.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS: constants
|
// L2TPNS: constants
|
||||||
|
|
||||||
char const *cvs_id_constants = "$Id: constants.c,v 1.5 2005/05/05 10:02:07 bodea Exp $";
|
char const *cvs_id_constants = "$Id: constants.c,v 1.6 2005/06/28 14:48:20 bodea Exp $";
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
|
@ -173,8 +173,17 @@ CONSTANT(radius_code,
|
||||||
0, // 9
|
0, // 9
|
||||||
0, // 10
|
0, // 10
|
||||||
"Access-Challenge", // 11
|
"Access-Challenge", // 11
|
||||||
"Status-Server (experimental)", // 12
|
"Status-Server", // 12
|
||||||
"Status-Client (experimental)" // 13
|
"Status-Client", // 13
|
||||||
|
0, 0, 0, 0, 0, 0, // 14-19
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20-29
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 30-39
|
||||||
|
"Disconnect-Request", // 40
|
||||||
|
"Disconnect-ACK", // 41
|
||||||
|
"Disconnect-NAK", // 42
|
||||||
|
"CoA-Request", // 43
|
||||||
|
"CoA-ACK", // 44
|
||||||
|
"CoA-NAK" // 45
|
||||||
)
|
)
|
||||||
|
|
||||||
CONSTANT(l2tp_message_type,
|
CONSTANT(l2tp_message_type,
|
||||||
|
|
|
||||||
103
l2tpns.c
103
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.112 2005/06/24 07:05:04 bodea Exp $";
|
char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.113 2005/06/28 14:48:20 bodea Exp $";
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
@ -60,6 +60,7 @@ 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
|
||||||
int clifd = -1; // Socket listening for CLI connections.
|
int clifd = -1; // Socket listening for CLI connections.
|
||||||
|
int daefd = -1; // Socket listening for DAE connections.
|
||||||
int snoopfd = -1; // UDP file handle for sending out intercept data
|
int snoopfd = -1; // UDP file handle for sending out intercept data
|
||||||
int *radfds = NULL; // RADIUS requests file handles
|
int *radfds = NULL; // RADIUS requests file handles
|
||||||
int ifrfd = -1; // File descriptor for routing, etc
|
int ifrfd = -1; // File descriptor for routing, etc
|
||||||
|
|
@ -114,6 +115,7 @@ config_descriptt config_values[] = {
|
||||||
CONFIG("radius_interim", radius_interim, INT),
|
CONFIG("radius_interim", radius_interim, INT),
|
||||||
CONFIG("radius_secret", radiussecret, STRING),
|
CONFIG("radius_secret", radiussecret, STRING),
|
||||||
CONFIG("radius_authtypes", radius_authtypes_s, STRING),
|
CONFIG("radius_authtypes", radius_authtypes_s, STRING),
|
||||||
|
CONFIG("radius_dae_port", radius_dae_port, SHORT),
|
||||||
CONFIG("allow_duplicate_users", allow_duplicate_users, BOOL),
|
CONFIG("allow_duplicate_users", allow_duplicate_users, BOOL),
|
||||||
CONFIG("bind_address", bind_address, IPv4),
|
CONFIG("bind_address", bind_address, IPv4),
|
||||||
CONFIG("peer_address", peer_address, IPv4),
|
CONFIG("peer_address", peer_address, IPv4),
|
||||||
|
|
@ -148,6 +150,7 @@ static char *plugin_functions[] = {
|
||||||
"plugin_kill_session",
|
"plugin_kill_session",
|
||||||
"plugin_control",
|
"plugin_control",
|
||||||
"plugin_radius_response",
|
"plugin_radius_response",
|
||||||
|
"plugin_radius_reset",
|
||||||
"plugin_become_master",
|
"plugin_become_master",
|
||||||
"plugin_new_session_master",
|
"plugin_new_session_master",
|
||||||
};
|
};
|
||||||
|
|
@ -578,7 +581,7 @@ static void inittun(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up UDP port
|
// set up UDP ports
|
||||||
static void initudp(void)
|
static void initudp(void)
|
||||||
{
|
{
|
||||||
int on = 1;
|
int on = 1;
|
||||||
|
|
@ -600,7 +603,6 @@ static void initudp(void)
|
||||||
LOG(0, 0, 0, "Error in UDP bind: %s\n", strerror(errno));
|
LOG(0, 0, 0, "Error in UDP bind: %s\n", strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
snoopfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
|
|
||||||
// Control
|
// Control
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
|
@ -613,6 +615,21 @@ static void initudp(void)
|
||||||
LOG(0, 0, 0, "Error in control bind: %s\n", strerror(errno));
|
LOG(0, 0, 0, "Error in control bind: %s\n", strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dynamic Authorization Extensions to RADIUS
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(config->radius_dae_port);
|
||||||
|
daefd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
setsockopt(daefd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||||
|
if (bind(daefd, (void *) &addr, sizeof(addr)) < 0)
|
||||||
|
{
|
||||||
|
LOG(0, 0, 0, "Error in DAE bind: %s\n", strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intercept
|
||||||
|
snoopfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -1415,7 +1432,7 @@ void throttle_session(sessionidt s, int rate_in, int rate_out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add/remove filters from session (-1 = no change)
|
// add/remove filters from session (-1 = no change)
|
||||||
static void filter_session(sessionidt s, int filter_in, int filter_out)
|
void filter_session(sessionidt s, int filter_in, int filter_out)
|
||||||
{
|
{
|
||||||
if (!session[s].opened)
|
if (!session[s].opened)
|
||||||
return; // No-one home.
|
return; // No-one home.
|
||||||
|
|
@ -2959,8 +2976,8 @@ static int still_busy(void)
|
||||||
# include "fake_epoll.h"
|
# include "fake_epoll.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// the base set of fds polled: control, cli, udp, tun, cluster
|
// the base set of fds polled: cli, cluster, tun, udp, control, dae
|
||||||
#define BASE_FDS 5
|
#define BASE_FDS 6
|
||||||
|
|
||||||
// additional polled fds
|
// additional polled fds
|
||||||
#ifdef BGP
|
#ifdef BGP
|
||||||
|
|
@ -2984,8 +3001,8 @@ static void mainloop(void)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(4, 0, 0, "Beginning of main loop. udpfd=%d, tunfd=%d, cluster_sockfd=%d, controlfd=%d\n",
|
LOG(4, 0, 0, "Beginning of main loop. clifd=%d, cluster_sockfd=%d, tunfd=%d, udpfd=%d, controlfd=%d, daefd=%d\n",
|
||||||
udpfd, tunfd, cluster_sockfd, controlfd);
|
clifd, cluster_sockfd, tunfd, udpfd, controlfd, daefd);
|
||||||
|
|
||||||
/* setup our fds to poll for input */
|
/* setup our fds to poll for input */
|
||||||
{
|
{
|
||||||
|
|
@ -2995,25 +3012,29 @@ static void mainloop(void)
|
||||||
e.events = EPOLLIN;
|
e.events = EPOLLIN;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
d[i].type = FD_TYPE_CONTROL;
|
|
||||||
e.data.ptr = &d[i++];
|
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, controlfd, &e);
|
|
||||||
|
|
||||||
d[i].type = FD_TYPE_CLI;
|
d[i].type = FD_TYPE_CLI;
|
||||||
e.data.ptr = &d[i++];
|
e.data.ptr = &d[i++];
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, clifd, &e);
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, clifd, &e);
|
||||||
|
|
||||||
d[i].type = FD_TYPE_UDP;
|
d[i].type = FD_TYPE_CLUSTER;
|
||||||
e.data.ptr = &d[i++];
|
e.data.ptr = &d[i++];
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, udpfd, &e);
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, cluster_sockfd, &e);
|
||||||
|
|
||||||
d[i].type = FD_TYPE_TUN;
|
d[i].type = FD_TYPE_TUN;
|
||||||
e.data.ptr = &d[i++];
|
e.data.ptr = &d[i++];
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, tunfd, &e);
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, tunfd, &e);
|
||||||
|
|
||||||
d[i].type = FD_TYPE_CLUSTER;
|
d[i].type = FD_TYPE_UDP;
|
||||||
e.data.ptr = &d[i++];
|
e.data.ptr = &d[i++];
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, cluster_sockfd, &e);
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, udpfd, &e);
|
||||||
|
|
||||||
|
d[i].type = FD_TYPE_CONTROL;
|
||||||
|
e.data.ptr = &d[i++];
|
||||||
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, controlfd, &e);
|
||||||
|
|
||||||
|
d[i].type = FD_TYPE_DAE;
|
||||||
|
e.data.ptr = &d[i++];
|
||||||
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, daefd, &e);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BGP
|
#ifdef BGP
|
||||||
|
|
@ -3080,12 +3101,6 @@ static void mainloop(void)
|
||||||
struct event_data *d = events[i].data.ptr;
|
struct event_data *d = events[i].data.ptr;
|
||||||
switch (d->type)
|
switch (d->type)
|
||||||
{
|
{
|
||||||
case FD_TYPE_CONTROL: // nsctl commands
|
|
||||||
alen = sizeof(addr);
|
|
||||||
processcontrol(buf, recvfrom(controlfd, buf, sizeof(buf), MSG_WAITALL, (void *) &addr, &alen), &addr, alen);
|
|
||||||
n--;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FD_TYPE_CLI: // CLI connections
|
case FD_TYPE_CLI: // CLI connections
|
||||||
{
|
{
|
||||||
int cli;
|
int cli;
|
||||||
|
|
@ -3104,9 +3119,21 @@ static void mainloop(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// these are handled below, with multiple interleaved reads
|
// these are handled below, with multiple interleaved reads
|
||||||
case FD_TYPE_UDP: udp_ready++; break;
|
|
||||||
case FD_TYPE_TUN: tun_ready++; break;
|
|
||||||
case FD_TYPE_CLUSTER: cluster_ready++; break;
|
case FD_TYPE_CLUSTER: cluster_ready++; break;
|
||||||
|
case FD_TYPE_TUN: tun_ready++; break;
|
||||||
|
case FD_TYPE_UDP: udp_ready++; break;
|
||||||
|
|
||||||
|
case FD_TYPE_CONTROL: // nsctl commands
|
||||||
|
alen = sizeof(addr);
|
||||||
|
processcontrol(buf, recvfrom(controlfd, buf, sizeof(buf), MSG_WAITALL, (void *) &addr, &alen), &addr, alen);
|
||||||
|
n--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FD_TYPE_DAE: // DAE requests
|
||||||
|
alen = sizeof(addr);
|
||||||
|
processdae(buf, recvfrom(daefd, buf, sizeof(buf), MSG_WAITALL, (void *) &addr, &alen), &addr, alen);
|
||||||
|
n--;
|
||||||
|
break;
|
||||||
|
|
||||||
case FD_TYPE_RADIUS: // RADIUS response
|
case FD_TYPE_RADIUS: // RADIUS response
|
||||||
s = recv(radfds[d->index], buf, sizeof(buf), 0);
|
s = recv(radfds[d->index], buf, sizeof(buf), 0);
|
||||||
|
|
@ -4186,6 +4213,9 @@ static void update_config()
|
||||||
strcat(config->radius_authtypes_s, ", pap");
|
strcat(config->radius_authtypes_s, ", pap");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!config->radius_dae_port)
|
||||||
|
config->radius_dae_port = DAEPORT;
|
||||||
|
|
||||||
// re-initialise the random number source
|
// re-initialise the random number source
|
||||||
initrandom(config->random_device);
|
initrandom(config->random_device);
|
||||||
|
|
||||||
|
|
@ -5044,6 +5074,31 @@ static void unhide_value(uint8_t *value, size_t len, uint16_t type, uint8_t *vec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int find_filter(char const *name, size_t len)
|
||||||
|
{
|
||||||
|
int free = -1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXFILTER; i++)
|
||||||
|
{
|
||||||
|
if (!*ip_filters[i].name)
|
||||||
|
{
|
||||||
|
if (free < 0)
|
||||||
|
free = i;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(ip_filters[i].name) != len)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!strncmp(ip_filters[i].name, name, len))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return free;
|
||||||
|
}
|
||||||
|
|
||||||
static int ip_filter_port(ip_filter_portt *p, uint16_t port)
|
static int ip_filter_port(ip_filter_portt *p, uint16_t port)
|
||||||
{
|
{
|
||||||
switch (p->op)
|
switch (p->op)
|
||||||
|
|
|
||||||
23
l2tpns.h
23
l2tpns.h
|
|
@ -1,5 +1,5 @@
|
||||||
// L2TPNS Global Stuff
|
// L2TPNS Global Stuff
|
||||||
// $Id: l2tpns.h,v 1.79 2005/06/24 07:05:04 bodea Exp $
|
// $Id: l2tpns.h,v 1.80 2005/06/28 14:48:27 bodea Exp $
|
||||||
|
|
||||||
#ifndef __L2TPNS_H__
|
#ifndef __L2TPNS_H__
|
||||||
#define __L2TPNS_H__
|
#define __L2TPNS_H__
|
||||||
|
|
@ -76,6 +76,7 @@
|
||||||
#define ACCT_SHUT_TIME 600 // 1 minute for counters of shutdown sessions
|
#define ACCT_SHUT_TIME 600 // 1 minute for counters of shutdown sessions
|
||||||
#define L2TPPORT 1701 // L2TP port
|
#define L2TPPORT 1701 // L2TP port
|
||||||
#define RADPORT 1645 // old radius port...
|
#define RADPORT 1645 // old radius port...
|
||||||
|
#define DAEPORT 3799 // DAE port
|
||||||
#define PKTARP 0x0806 // ARP packet type
|
#define PKTARP 0x0806 // ARP packet type
|
||||||
#define PKTIP 0x0800 // IPv4 packet type
|
#define PKTIP 0x0800 // IPv4 packet type
|
||||||
#define PKTIPV6 0x86DD // IPv6 packet type
|
#define PKTIPV6 0x86DD // IPv6 packet type
|
||||||
|
|
@ -111,7 +112,13 @@ enum {
|
||||||
AccessReject,
|
AccessReject,
|
||||||
AccountingRequest,
|
AccountingRequest,
|
||||||
AccountingResponse,
|
AccountingResponse,
|
||||||
AccessChallenge = 11
|
AccessChallenge = 11,
|
||||||
|
DisconnectRequest = 40,
|
||||||
|
DisconnectACK,
|
||||||
|
DisconnectNAK,
|
||||||
|
CoARequest,
|
||||||
|
CoAACK,
|
||||||
|
CoANAK
|
||||||
};
|
};
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
|
|
@ -457,6 +464,8 @@ typedef struct
|
||||||
uint16_t radiusport[MAXRADSERVER]; // radius base ports
|
uint16_t radiusport[MAXRADSERVER]; // radius base ports
|
||||||
uint8_t numradiusservers; // radius server count
|
uint8_t numradiusservers; // radius server count
|
||||||
|
|
||||||
|
uint16_t radius_dae_port; // local port for radius dae
|
||||||
|
|
||||||
char radius_authtypes_s[32]; // list of valid authentication types (chap, pap) in order of preference
|
char radius_authtypes_s[32]; // list of valid authentication types (chap, pap) in order of preference
|
||||||
int radius_authtypes;
|
int radius_authtypes;
|
||||||
int radius_authprefer;
|
int radius_authprefer;
|
||||||
|
|
@ -611,6 +620,7 @@ void processrad(uint8_t *buf, int len, char socket_index);
|
||||||
void radiusretry(uint16_t r);
|
void radiusretry(uint16_t r);
|
||||||
uint16_t radiusnew(sessionidt s);
|
uint16_t radiusnew(sessionidt s);
|
||||||
void radiusclear(uint16_t r, sessionidt s);
|
void radiusclear(uint16_t r, sessionidt s);
|
||||||
|
void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen);
|
||||||
|
|
||||||
|
|
||||||
// l2tpns.c
|
// l2tpns.c
|
||||||
|
|
@ -624,11 +634,13 @@ 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 *reason, int result, int error);
|
||||||
|
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);
|
||||||
void sendipcp(tunnelidt t, sessionidt s);
|
void sendipcp(tunnelidt t, sessionidt s);
|
||||||
void processudp(uint8_t *buf, int len, struct sockaddr_in *addr);
|
void processudp(uint8_t *buf, int len, struct sockaddr_in *addr);
|
||||||
void snoop_send_packet(char *packet, uint16_t size, in_addr_t destination, uint16_t port);
|
void snoop_send_packet(char *packet, uint16_t size, in_addr_t destination, uint16_t port);
|
||||||
|
int find_filter(char const *name, size_t len);
|
||||||
int ip_filter(uint8_t *buf, int len, uint8_t filter);
|
int ip_filter(uint8_t *buf, int len, uint8_t filter);
|
||||||
int cmd_show_ipcache(struct cli_def *cli, char *command, char **argv, int argc);
|
int cmd_show_ipcache(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
int cmd_show_hist_idle(struct cli_def *cli, char *command, char **argv, int argc);
|
int cmd_show_hist_idle(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
|
|
@ -696,11 +708,12 @@ extern int epollfd;
|
||||||
|
|
||||||
struct event_data {
|
struct event_data {
|
||||||
enum {
|
enum {
|
||||||
FD_TYPE_CONTROL,
|
|
||||||
FD_TYPE_CLI,
|
FD_TYPE_CLI,
|
||||||
FD_TYPE_UDP,
|
|
||||||
FD_TYPE_TUN,
|
|
||||||
FD_TYPE_CLUSTER,
|
FD_TYPE_CLUSTER,
|
||||||
|
FD_TYPE_TUN,
|
||||||
|
FD_TYPE_UDP,
|
||||||
|
FD_TYPE_CONTROL,
|
||||||
|
FD_TYPE_DAE,
|
||||||
FD_TYPE_RADIUS,
|
FD_TYPE_RADIUS,
|
||||||
FD_TYPE_BGP,
|
FD_TYPE_BGP,
|
||||||
} type;
|
} type;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
* Mon Jun 27 2005 Brendan O'Dea <bod@optus.net> 2.1.2-1
|
* Wed Jun 29 2005 Brendan O'Dea <bod@c47.org> 2.1.2-1
|
||||||
- 2.1.2 release, see /usr/share/doc/l2tpns-2.1.2/Changes
|
- 2.1.2 release, see /usr/share/doc/l2tpns-2.1.2/Changes
|
||||||
|
|
|
||||||
9
plugin.h
9
plugin.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __PLUGIN_H__
|
#ifndef __PLUGIN_H__
|
||||||
#define __PLUGIN_H__
|
#define __PLUGIN_H__
|
||||||
|
|
||||||
#define PLUGIN_API_VERSION 5
|
#define PLUGIN_API_VERSION 6
|
||||||
#define MAX_PLUGIN_TYPES 30
|
#define MAX_PLUGIN_TYPES 30
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
|
@ -15,6 +15,7 @@ enum
|
||||||
PLUGIN_KILL_SESSION,
|
PLUGIN_KILL_SESSION,
|
||||||
PLUGIN_CONTROL,
|
PLUGIN_CONTROL,
|
||||||
PLUGIN_RADIUS_RESPONSE,
|
PLUGIN_RADIUS_RESPONSE,
|
||||||
|
PLUGIN_RADIUS_RESET,
|
||||||
PLUGIN_BECOME_MASTER,
|
PLUGIN_BECOME_MASTER,
|
||||||
PLUGIN_NEW_SESSION_MASTER,
|
PLUGIN_NEW_SESSION_MASTER,
|
||||||
};
|
};
|
||||||
|
|
@ -111,4 +112,10 @@ struct param_radius_response
|
||||||
char *value;
|
char *value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct param_radius_reset
|
||||||
|
{
|
||||||
|
tunnelt *t;
|
||||||
|
sessiont *s;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __PLUGIN_H__ */
|
#endif /* __PLUGIN_H__ */
|
||||||
|
|
|
||||||
424
radius.c
424
radius.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS Radius Stuff
|
// L2TPNS Radius Stuff
|
||||||
|
|
||||||
char const *cvs_id_radius = "$Id: radius.c,v 1.33 2005/06/04 15:42:36 bodea Exp $";
|
char const *cvs_id_radius = "$Id: radius.c,v 1.34 2005/06/28 14:48:28 bodea Exp $";
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -12,11 +12,13 @@ char const *cvs_id_radius = "$Id: radius.c,v 1.33 2005/06/04 15:42:36 bodea Exp
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "l2tpns.h"
|
#include "l2tpns.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "cluster.h"
|
||||||
|
|
||||||
extern radiust *radius;
|
extern radiust *radius;
|
||||||
extern sessiont *session;
|
extern sessiont *session;
|
||||||
|
|
@ -51,7 +53,7 @@ static uint16_t get_free_radius()
|
||||||
int count;
|
int count;
|
||||||
static uint32_t next_radius_id = 0;
|
static uint32_t next_radius_id = 0;
|
||||||
|
|
||||||
for (count = MAXRADIUS; count > 0 ; --count)
|
for (count = MAXRADIUS; count > 0; --count)
|
||||||
{
|
{
|
||||||
++next_radius_id; // Find the next ID to check.
|
++next_radius_id; // Find the next ID to check.
|
||||||
if (next_radius_id >= MAXRADIUS)
|
if (next_radius_id >= MAXRADIUS)
|
||||||
|
|
@ -296,7 +298,7 @@ void radiussend(uint16_t r, uint8_t state)
|
||||||
{
|
{
|
||||||
*p = 26; // vendor-specific
|
*p = 26; // vendor-specific
|
||||||
*(uint32_t *) (p + 2) = htonl(9); // Cisco
|
*(uint32_t *) (p + 2) = htonl(9); // Cisco
|
||||||
p[6] = 1; // Cisco-Avpair
|
p[6] = 1; // Cisco-AVPair
|
||||||
p[7] = 2 + sprintf(p + 8, "intercept=%s:%d",
|
p[7] = 2 + sprintf(p + 8, "intercept=%s:%d",
|
||||||
fmtaddr(session[s].snoop_ip, 0), session[s].snoop_port);
|
fmtaddr(session[s].snoop_ip, 0), session[s].snoop_port);
|
||||||
|
|
||||||
|
|
@ -377,6 +379,47 @@ void radiussend(uint16_t r, uint8_t state)
|
||||||
sendto(radfds[r & RADIUS_MASK], b, p - b, 0, (void *) &addr, sizeof(addr));
|
sendto(radfds[r & RADIUS_MASK], b, p - b, 0, (void *) &addr, sizeof(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_avpair(sessionidt s, uint8_t *avp, int len)
|
||||||
|
{
|
||||||
|
char *key = avp;
|
||||||
|
char *value = memchr(avp, '=', len);
|
||||||
|
char tmp[2048] = "";
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
*value++ = 0;
|
||||||
|
len -= value - key;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = tmp;
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// strip quotes
|
||||||
|
if (len > 2 && (*value == '"' || *value == '\'') && value[len - 1] == *value)
|
||||||
|
{
|
||||||
|
value++;
|
||||||
|
len--;
|
||||||
|
value[len - 1] = 0;
|
||||||
|
}
|
||||||
|
// copy and null terminate
|
||||||
|
else if (len < sizeof(tmp) - 1)
|
||||||
|
{
|
||||||
|
memcpy(tmp, value, len);
|
||||||
|
tmp[len] = 0;
|
||||||
|
value = tmp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Run hooks
|
||||||
|
{
|
||||||
|
struct param_radius_response p = { &tunnel[session[s].tunnel], &session[s], key, value };
|
||||||
|
run_plugins(PLUGIN_RADIUS_RESPONSE, &p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// process RADIUS response
|
// process RADIUS response
|
||||||
void processrad(uint8_t *buf, int len, char socket_index)
|
void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
{
|
{
|
||||||
|
|
@ -577,37 +620,36 @@ void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
char *filter = p + 2;
|
char *filter = p + 2;
|
||||||
int l = p[1] - 2;
|
int l = p[1] - 2;
|
||||||
char *suffix;
|
char *suffix;
|
||||||
uint8_t *f = 0;
|
int f;
|
||||||
int i;
|
uint8_t *fp = 0;
|
||||||
|
|
||||||
LOG(3, s, session[s].tunnel, " Radius reply contains Filter-Id \"%.*s\"\n", l, filter);
|
LOG(3, s, session[s].tunnel, " Radius reply contains Filter-Id \"%.*s\"\n", l, filter);
|
||||||
if ((suffix = memchr(filter, '.', l)))
|
if ((suffix = memchr(filter, '.', l)))
|
||||||
{
|
{
|
||||||
int b = suffix - filter;
|
int b = suffix - filter;
|
||||||
if (l - b == 3 && !memcmp("in", suffix+1, 2))
|
if (l - b == 3 && !memcmp("in", suffix+1, 2))
|
||||||
f = &session[s].filter_in;
|
fp = &session[s].filter_in;
|
||||||
else if (l - b == 4 && !memcmp("out", suffix+1, 3))
|
else if (l - b == 4 && !memcmp("out", suffix+1, 3))
|
||||||
f = &session[s].filter_out;
|
fp = &session[s].filter_out;
|
||||||
|
|
||||||
l = b;
|
l = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!f)
|
if (!fp)
|
||||||
{
|
{
|
||||||
LOG(3, s, session[s].tunnel, " Invalid filter\n");
|
LOG(3, s, session[s].tunnel, " Invalid filter\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (*f = 0, i = 0; !*f && i < MAXFILTER; i++)
|
if ((f = find_filter(filter, l)) < 0 || !*ip_filters[f].name)
|
||||||
if (strlen(ip_filters[i].name) == l &&
|
{
|
||||||
!strncmp(ip_filters[i].name, filter, l))
|
|
||||||
*f = i + 1;
|
|
||||||
|
|
||||||
if (*f)
|
|
||||||
ip_filters[*f - 1].used++;
|
|
||||||
else
|
|
||||||
LOG(3, s, session[s].tunnel, " Unknown filter\n");
|
LOG(3, s, session[s].tunnel, " Unknown filter\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*fp = f + 1;
|
||||||
|
ip_filters[f].used++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (*p == 26 && p[1] >= 7)
|
else if (*p == 26 && p[1] >= 7)
|
||||||
{
|
{
|
||||||
|
|
@ -615,7 +657,6 @@ void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
int vendor = ntohl(*(int *)(p + 2));
|
int vendor = ntohl(*(int *)(p + 2));
|
||||||
char attrib = *(p + 6);
|
char attrib = *(p + 6);
|
||||||
int attrib_length = *(p + 7) - 2;
|
int attrib_length = *(p + 7) - 2;
|
||||||
char *avpair, *value, *key, *newp;
|
|
||||||
|
|
||||||
LOG(3, s, session[s].tunnel, " Radius reply contains Vendor-Specific. Vendor=%d Attrib=%d Length=%d\n", vendor, attrib, attrib_length);
|
LOG(3, s, session[s].tunnel, " Radius reply contains Vendor-Specific. Vendor=%d Attrib=%d Length=%d\n", vendor, attrib, attrib_length);
|
||||||
if (vendor != 9 || attrib != 1)
|
if (vendor != 9 || attrib != 1)
|
||||||
|
|
@ -624,36 +665,13 @@ void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrib_length < 0) continue;
|
if (attrib_length > 0)
|
||||||
|
|
||||||
avpair = key = calloc(attrib_length + 1, 1);
|
|
||||||
memcpy(avpair, p + 8, attrib_length);
|
|
||||||
LOG(3, s, session[s].tunnel, " Cisco-Avpair value: %s\n", avpair);
|
|
||||||
do {
|
|
||||||
value = strchr(key, '=');
|
|
||||||
if (!value) break;
|
|
||||||
*value++ = 0;
|
|
||||||
|
|
||||||
// Trim quotes off reply string
|
|
||||||
if (*value == '\'' || *value == '\"')
|
|
||||||
{
|
{
|
||||||
char *x;
|
LOG(3, s, session[s].tunnel, " Cisco-AVPair value: %.*s\n",
|
||||||
value++;
|
attrib_length, p + 8);
|
||||||
x = value + strlen(value) - 1;
|
|
||||||
if (*x == '\'' || *x == '\"')
|
|
||||||
*x = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run hooks
|
handle_avpair(s, p + 8, attrib_length);
|
||||||
newp = strchr(value, ',');
|
|
||||||
if (newp) *newp++ = 0;
|
|
||||||
{
|
|
||||||
struct param_radius_response p = { &tunnel[session[s].tunnel], &session[s], key, value };
|
|
||||||
run_plugins(PLUGIN_RADIUS_RESPONSE, &p);
|
|
||||||
}
|
}
|
||||||
key = newp;
|
|
||||||
} while (newp);
|
|
||||||
free(avpair);
|
|
||||||
}
|
}
|
||||||
else if (*p == 99)
|
else if (*p == 99)
|
||||||
{
|
{
|
||||||
|
|
@ -756,3 +774,319 @@ void radiusretry(uint16_t r)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int daefd;
|
||||||
|
|
||||||
|
void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen)
|
||||||
|
{
|
||||||
|
int i, r_code, r_id, length, attribute_length;
|
||||||
|
uint8_t vector[16], hash[16], *packet, attribute;
|
||||||
|
MD5_CTX ctx;
|
||||||
|
char username[MAXUSER] = "";
|
||||||
|
in_addr_t nas = 0;
|
||||||
|
in_addr_t ip = 0;
|
||||||
|
uint32_t port = 0;
|
||||||
|
uint32_t error = 0;
|
||||||
|
sessionidt s = 0;
|
||||||
|
tunnelidt t;
|
||||||
|
int fin = -1;
|
||||||
|
int fout = -1;
|
||||||
|
uint8_t *avpair[64];
|
||||||
|
int avpair_len[sizeof(avpair)/sizeof(*avpair)];
|
||||||
|
int avp = 0;
|
||||||
|
int auth_only = 0;
|
||||||
|
uint8_t *p;
|
||||||
|
|
||||||
|
LOG(3, 0, 0, "DAE request from %s\n", fmtaddr(addr->sin_addr.s_addr, 0));
|
||||||
|
|
||||||
|
// check if DAE is from RADIUS server
|
||||||
|
for (i = 0; i < config->numradiusservers; i++)
|
||||||
|
if (config->radiusserver[i] == addr -> sin_addr.s_addr)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i >= config->numradiusservers)
|
||||||
|
{
|
||||||
|
LOG(1, 0, 0, "Unknown DAE client %s\n", fmtaddr(addr->sin_addr.s_addr, 0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_HEX(5, "DAE Request", buf, len);
|
||||||
|
|
||||||
|
if (len < 20 || len < ntohs(*(uint16_t *) (buf + 2)))
|
||||||
|
{
|
||||||
|
LOG(1, 0, 0, "Duff DAE request length %d\n", len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
r_code = buf[0]; // request type
|
||||||
|
r_id = buf[1]; // radius indentifier.
|
||||||
|
|
||||||
|
if (r_code != DisconnectRequest && r_code != CoARequest)
|
||||||
|
{
|
||||||
|
LOG(1, 0, 0, "Unrecognised DAE request %s\n", radius_code(r_code));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config->cluster_iam_master)
|
||||||
|
{
|
||||||
|
master_forward_dae_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ntohs(*(uint16_t *) (buf + 2));
|
||||||
|
|
||||||
|
LOG(3, 0, 0, "Received DAE %s, id %d\n", radius_code(r_code), r_id);
|
||||||
|
|
||||||
|
// check authenticator
|
||||||
|
memcpy(vector, buf + 4, 16);
|
||||||
|
memset(buf + 4, 0, 16);
|
||||||
|
|
||||||
|
i = strlen(config->radiussecret);
|
||||||
|
if (i > 16) i = 16;
|
||||||
|
|
||||||
|
MD5Init(&ctx);
|
||||||
|
MD5Update(&ctx, buf, len);
|
||||||
|
MD5Update(&ctx, buf, config->radiussecret, i);
|
||||||
|
MD5Final(hash, &ctx);
|
||||||
|
if (memcmp(hash, vector, 16) != 0)
|
||||||
|
{
|
||||||
|
LOG(1, 0, 0, "Incorrect vector in DAE request (wrong secret in radius config?)\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unpack attributes
|
||||||
|
packet = buf + 20;
|
||||||
|
length = len - 20;
|
||||||
|
|
||||||
|
while (length > 0)
|
||||||
|
{
|
||||||
|
attribute = *packet++;
|
||||||
|
attribute_length = *packet++;
|
||||||
|
if (attribute_length < 2)
|
||||||
|
break;
|
||||||
|
|
||||||
|
length -= attribute_length;
|
||||||
|
attribute_length -= 2;
|
||||||
|
switch (attribute)
|
||||||
|
{
|
||||||
|
case 1: /* username */
|
||||||
|
len = attribute_length < MAXUSER ? attribute_length : MAXUSER - 1;
|
||||||
|
memcpy(username, packet, len);
|
||||||
|
username[len] = 0;
|
||||||
|
LOG(4, 0, 0, " Received DAE User-Name: %s\n", username);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: /* nas ip address */
|
||||||
|
nas = *(uint32_t *) packet; // net order
|
||||||
|
if (nas != config->bind_address)
|
||||||
|
error = 403; // NAS identification mismatch
|
||||||
|
|
||||||
|
LOG(4, 0, 0, " Received DAE NAS-IP-Address: %s\n", fmtaddr(nas, 0));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5: /* nas port */
|
||||||
|
port = ntohl(*(uint32_t *) packet);
|
||||||
|
if (port < 1 || port > MAXSESSION)
|
||||||
|
error = 404;
|
||||||
|
|
||||||
|
LOG(4, 0, 0, " Received DAE NAS-Port: %u\n", port);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6: /* service type */
|
||||||
|
{
|
||||||
|
uint32_t service_type = ntohl(*(uint32_t *) packet);
|
||||||
|
auth_only = service_type == 8; // Authenticate only
|
||||||
|
|
||||||
|
LOG(4, 0, 0, " Received DAE Service-Type: %u\n", service_type);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8: /* ip address */
|
||||||
|
ip = *(uint32_t *) packet; // net order
|
||||||
|
LOG(4, 0, 0, " Received DAE Framed-IP-Address: %s\n", fmtaddr(ip, 0));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 11: /* filter id */
|
||||||
|
LOG(4, 0, 0, " Received DAE Filter-Id: %.*s\n", attribute_length, packet);
|
||||||
|
if (!(p = memchr(packet, '.', attribute_length)))
|
||||||
|
{
|
||||||
|
error = 404; // invalid request
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = p - packet;
|
||||||
|
i = find_filter(packet, len);
|
||||||
|
if (i < 0 || !*ip_filters[i].name)
|
||||||
|
{
|
||||||
|
error = 404;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!memcmp(p, ".in", attribute_length - len))
|
||||||
|
fin = i + 1;
|
||||||
|
else if (!memcmp(p, ".out", attribute_length - len))
|
||||||
|
fout = i + 1;
|
||||||
|
else
|
||||||
|
error = 404;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 26: /* vendor specific */
|
||||||
|
if (attribute_length >= 6
|
||||||
|
&& ntohl(*(uint32_t *) packet) == 9 // Cisco
|
||||||
|
&& *(packet + 4) == 1 // Cisco-AVPair
|
||||||
|
&& *(packet + 5) >= 2) // length
|
||||||
|
{
|
||||||
|
int len = *(packet + 5) - 2;
|
||||||
|
uint8_t *a = packet + 6;
|
||||||
|
|
||||||
|
LOG(4, 0, 0, " Received DAE Cisco-AVPair: %.*s\n", len, a);
|
||||||
|
if (avp < sizeof(avpair)/sizeof(*avpair) - 1)
|
||||||
|
{
|
||||||
|
avpair[avp] = a;
|
||||||
|
avpair_len[avp++] = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
packet += attribute_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error && auth_only)
|
||||||
|
{
|
||||||
|
if (fin != -1 || fout != -1 || avp)
|
||||||
|
error = 401; // unsupported attribute
|
||||||
|
else
|
||||||
|
error = 405; // unsupported service
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error && !(port || ip || *username))
|
||||||
|
error = 402; // missing attribute
|
||||||
|
|
||||||
|
// exact match for SID if given
|
||||||
|
if (!error && port)
|
||||||
|
{
|
||||||
|
s = port;
|
||||||
|
if (!session[s].opened)
|
||||||
|
error = 503; // not found
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error && ip)
|
||||||
|
{
|
||||||
|
// find/check session by IP
|
||||||
|
i = sessionbyip(ip);
|
||||||
|
if (!i || (s && s != i)) // not found or mismatching port
|
||||||
|
error = 503;
|
||||||
|
else
|
||||||
|
s = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error && *username)
|
||||||
|
{
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
if (strcmp(session[s].user, username))
|
||||||
|
error = 503;
|
||||||
|
}
|
||||||
|
else if (!(s = sessionbyuser(username)))
|
||||||
|
error = 503;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = session[s].tunnel;
|
||||||
|
|
||||||
|
switch (r_code)
|
||||||
|
{
|
||||||
|
case DisconnectRequest: // Packet of Disconnect/Death
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
r_code = DisconnectNAK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(3, s, t, " DAE Disconnect %d (%s)\n", s, session[s].user);
|
||||||
|
r_code = DisconnectACK;
|
||||||
|
|
||||||
|
sessionshutdown(s, "Requested by PoD", 3, 0); // disconnect session
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CoARequest: // Change of Authorization
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
r_code = CoANAK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(3, s, t, " DAE Change %d (%s)\n", s, session[s].user);
|
||||||
|
r_code = CoAACK;
|
||||||
|
|
||||||
|
// reset
|
||||||
|
{
|
||||||
|
struct param_radius_reset p = { &tunnel[session[s].tunnel], &session[s] };
|
||||||
|
run_plugins(PLUGIN_RADIUS_RESET, &p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply filters
|
||||||
|
if (fin != -1 || fout != -1)
|
||||||
|
{
|
||||||
|
if (fin == -1)
|
||||||
|
fin = 0;
|
||||||
|
else
|
||||||
|
LOG(3, s, t, " Filter in %d (%s)\n", fin, ip_filters[fin - 1].name);
|
||||||
|
|
||||||
|
if (fout == -1)
|
||||||
|
fout = 0;
|
||||||
|
else
|
||||||
|
LOG(3, s, t, " Filter out %d (%s)\n", fout, ip_filters[fout - 1].name);
|
||||||
|
|
||||||
|
filter_session(s, fin, fout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// process cisco av-pair(s)
|
||||||
|
for (i = 0; i < avp; i++)
|
||||||
|
{
|
||||||
|
LOG(3, s, t, " Cisco-AVPair: %.*s\n", avpair_len[i], avpair[i]);
|
||||||
|
handle_avpair(s, avpair[i], avpair_len[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster_send_session(s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send response
|
||||||
|
packet = buf;
|
||||||
|
*packet++ = r_code;
|
||||||
|
*packet++ = r_id;
|
||||||
|
packet += 2;
|
||||||
|
memset(packet, 0, 16);
|
||||||
|
packet += 16;
|
||||||
|
len = 20;
|
||||||
|
|
||||||
|
// add attributes
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
// add error cause
|
||||||
|
*packet++ = 101;
|
||||||
|
*packet++ = 6;
|
||||||
|
*(uint32_t *) packet = htonl(error);
|
||||||
|
len += 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
*((uint16_t *)(buf + 2)) = htons(len);
|
||||||
|
|
||||||
|
// make vector
|
||||||
|
i = strlen(config->radiussecret);
|
||||||
|
if (i > 16) i = 16;
|
||||||
|
|
||||||
|
MD5Init(&ctx);
|
||||||
|
MD5Update(&ctx, buf, len);
|
||||||
|
MD5Update(&ctx, config->radiussecret, i);
|
||||||
|
MD5Final(hash, &ctx);
|
||||||
|
memcpy(buf + 4, hash, 16);
|
||||||
|
|
||||||
|
LOG(3, 0, 0, "Sending DAE %s, id=%d\n", radius_code(r_code), r_id);
|
||||||
|
|
||||||
|
// send DAE response
|
||||||
|
if (sendto(daefd, buf, len, MSG_DONTWAIT | MSG_NOSIGNAL, (struct sockaddr *) addr, alen) < 0)
|
||||||
|
LOG(0, 0, 0, "Error sending DAE response packet: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
|
|
||||||
16
sessionctl.c
16
sessionctl.c
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
/* session control */
|
/* session control */
|
||||||
|
|
||||||
char const *cvs_id = "$Id: sessionctl.c,v 1.2 2005/05/10 06:48:16 bodea Exp $";
|
char const *cvs_id = "$Id: sessionctl.c,v 1.3 2005/06/28 14:48:28 bodea Exp $";
|
||||||
|
|
||||||
int plugin_api_version = PLUGIN_API_VERSION;
|
int plugin_api_version = PLUGIN_API_VERSION;
|
||||||
static struct pluginfuncs *p = 0;
|
static struct pluginfuncs *p = 0;
|
||||||
|
|
@ -16,15 +16,6 @@ char *plugin_control_help[] = {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
int plugin_init(struct pluginfuncs *funcs)
|
|
||||||
{
|
|
||||||
if (!funcs)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
p = funcs;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int plugin_control(struct param_control *data)
|
int plugin_control(struct param_control *data)
|
||||||
{
|
{
|
||||||
sessionidt session;
|
sessionidt session;
|
||||||
|
|
@ -76,3 +67,8 @@ int plugin_control(struct param_control *data)
|
||||||
|
|
||||||
return PLUGIN_RET_STOP;
|
return PLUGIN_RET_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int plugin_init(struct pluginfuncs *funcs)
|
||||||
|
{
|
||||||
|
return ((p = funcs)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
23
snoopctl.c
23
snoopctl.c
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
/* snoop control */
|
/* snoop control */
|
||||||
|
|
||||||
char const *cvs_id = "$Id: snoopctl.c,v 1.4 2004/12/16 08:49:53 bodea Exp $";
|
char const *cvs_id = "$Id: snoopctl.c,v 1.5 2005/06/28 14:48:28 bodea Exp $";
|
||||||
|
|
||||||
int plugin_api_version = PLUGIN_API_VERSION;
|
int plugin_api_version = PLUGIN_API_VERSION;
|
||||||
static struct pluginfuncs *p = 0;
|
static struct pluginfuncs *p = 0;
|
||||||
|
|
@ -16,15 +16,6 @@ char *plugin_control_help[] = {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
int plugin_init(struct pluginfuncs *funcs)
|
|
||||||
{
|
|
||||||
if (!funcs)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
p = funcs;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int plugin_control(struct param_control *data)
|
int plugin_control(struct param_control *data)
|
||||||
{
|
{
|
||||||
sessionidt session;
|
sessionidt session;
|
||||||
|
|
@ -124,3 +115,15 @@ int plugin_control(struct param_control *data)
|
||||||
|
|
||||||
return PLUGIN_RET_STOP;
|
return PLUGIN_RET_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int plugin_radius_reset(struct param_radius_reset *data)
|
||||||
|
{
|
||||||
|
data->s->snoop_ip = 0;
|
||||||
|
data->s->snoop_port = 0;
|
||||||
|
return PLUGIN_RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_init(struct pluginfuncs *funcs)
|
||||||
|
{
|
||||||
|
return ((p = funcs)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
/* throttle control */
|
/* throttle control */
|
||||||
|
|
||||||
char const *cvs_id = "$Id: throttlectl.c,v 1.6 2004/12/01 04:44:29 bodea Exp $";
|
char const *cvs_id = "$Id: throttlectl.c,v 1.7 2005/06/28 14:48:28 bodea Exp $";
|
||||||
|
|
||||||
int plugin_api_version = PLUGIN_API_VERSION;
|
int plugin_api_version = PLUGIN_API_VERSION;
|
||||||
static struct pluginfuncs *p = 0;
|
static struct pluginfuncs *p = 0;
|
||||||
|
|
@ -16,15 +16,6 @@ char *plugin_control_help[] = {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
int plugin_init(struct pluginfuncs *funcs)
|
|
||||||
{
|
|
||||||
if (!funcs)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
p = funcs;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int plugin_control(struct param_control *data)
|
int plugin_control(struct param_control *data)
|
||||||
{
|
{
|
||||||
sessionidt session;
|
sessionidt session;
|
||||||
|
|
@ -137,3 +128,14 @@ int plugin_control(struct param_control *data)
|
||||||
|
|
||||||
return PLUGIN_RET_STOP;
|
return PLUGIN_RET_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int plugin_radius_reset(struct param_radius_reset *data)
|
||||||
|
{
|
||||||
|
p->throttle(p->get_id_by_session(data->s), 0, 0);
|
||||||
|
return PLUGIN_RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_init(struct pluginfuncs *funcs)
|
||||||
|
{
|
||||||
|
return ((p = funcs)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
9
util.c
9
util.c
|
|
@ -1,6 +1,6 @@
|
||||||
/* Misc util functions */
|
/* Misc util functions */
|
||||||
|
|
||||||
char const *cvs_id_util = "$Id: util.c,v 1.11 2005/06/04 15:42:36 bodea Exp $";
|
char const *cvs_id_util = "$Id: util.c,v 1.12 2005/06/28 14:48:28 bodea Exp $";
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
@ -40,7 +40,7 @@ void *shared_malloc(unsigned int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int forked;
|
extern int forked;
|
||||||
extern int udpfd, controlfd, tunfd, snoopfd, ifrfd, ifr6fd, rand_fd, cluster_sockfd;
|
extern int cluster_sockfd, tunfd, udpfd, controlfd, daefd, snoopfd, ifrfd, ifr6fd, rand_fd;
|
||||||
extern int *radfds;
|
extern int *radfds;
|
||||||
|
|
||||||
pid_t fork_and_close()
|
pid_t fork_and_close()
|
||||||
|
|
@ -73,15 +73,16 @@ pid_t fork_and_close()
|
||||||
signal(SIGTERM, SIG_DFL);
|
signal(SIGTERM, SIG_DFL);
|
||||||
|
|
||||||
// Close sockets
|
// Close sockets
|
||||||
|
if (clifd != -1) close(clifd);
|
||||||
|
if (cluster_sockfd != -1) close(cluster_sockfd);
|
||||||
if (tunfd != -1) close(tunfd);
|
if (tunfd != -1) close(tunfd);
|
||||||
if (udpfd != -1) close(udpfd);
|
if (udpfd != -1) close(udpfd);
|
||||||
if (controlfd != -1) close(controlfd);
|
if (controlfd != -1) close(controlfd);
|
||||||
|
if (daefd != -1) close(daefd);
|
||||||
if (snoopfd != -1) close(snoopfd);
|
if (snoopfd != -1) close(snoopfd);
|
||||||
if (ifrfd != -1) close(ifrfd);
|
if (ifrfd != -1) close(ifrfd);
|
||||||
if (ifr6fd != -1) close(ifr6fd);
|
if (ifr6fd != -1) close(ifr6fd);
|
||||||
if (rand_fd != -1) close(rand_fd);
|
if (rand_fd != -1) close(rand_fd);
|
||||||
if (cluster_sockfd != -1) close(cluster_sockfd);
|
|
||||||
if (clifd != -1) close(clifd);
|
|
||||||
if (epollfd != -1) close(epollfd);
|
if (epollfd != -1) close(epollfd);
|
||||||
|
|
||||||
for (i = 0; radfds && i < RADIUS_FDS; i++)
|
for (i = 0; radfds && i < RADIUS_FDS; i++)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue