- Replace flags used for LCP/IPCP with state machine.
- Use openssl MD5, fix DAE vector (Alex Kiernan).
This commit is contained in:
parent
17b2ce31a6
commit
afc8f4c6c0
27 changed files with 1399 additions and 1120 deletions
8
Changes
8
Changes
|
|
@ -1,10 +1,10 @@
|
||||||
* Wed Jun 29 2005 Brendan O'Dea <bod@c47.org> 2.1.2
|
* Sun Jul 31 2005 Brendan O'Dea <bod@> 2.1.2
|
||||||
- Don't resend IPCP while still in progress.
|
|
||||||
- Ignore duplicate ACKs for IPCP.
|
|
||||||
- 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.
|
- Add DAE support (PoD/CoA) from Vladislav Bjelic.
|
||||||
|
- Clean up new warnings from gcc 4.0.
|
||||||
|
- Replace flags used for LCP/IPCP with state machine.
|
||||||
|
- Use openssl MD5, fix DAE vector (Alex Kiernan).
|
||||||
|
|
||||||
* 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.
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,13 @@ the same as the LAC, or authentication will fail. Only actually be
|
||||||
used if the LAC requests authentication.
|
used if the LAC requests authentication.
|
||||||
</LI>
|
</LI>
|
||||||
|
|
||||||
|
<LI><B>ppp_restart_time</B> (int)<BR>
|
||||||
|
<B>ppp_max_configure</B> (int)<BR>
|
||||||
|
<B>ppp_max_failure</B> (int)<BR>
|
||||||
|
PPP counters and timers values, as described in §4.1 of
|
||||||
|
<a href="ftp://ftp.rfc-editor.org/in-notes/rfc1661.txt">RFC1661</a>.
|
||||||
|
</LI>
|
||||||
|
|
||||||
<LI><B>primary_dns</B> (ip address)
|
<LI><B>primary_dns</B> (ip address)
|
||||||
<LI><B>secondary_dns</B> (ip address)<BR>
|
<LI><B>secondary_dns</B> (ip address)<BR>
|
||||||
Whenever a PPP connection is established, DNS servers will be sent to the
|
Whenever a PPP connection is established, DNS servers will be sent to the
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
.de Id
|
.de Id
|
||||||
.ds Dt \\$4 \\$5
|
.ds Dt \\$4 \\$5
|
||||||
..
|
..
|
||||||
.Id $Id: startup-config.5,v 1.11 2005/06/28 14:48:31 bodea Exp $
|
.Id $Id: startup-config.5,v 1.12 2005/07/31 10:04:14 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
|
||||||
|
|
@ -63,6 +63,16 @@ for authenticating tunnel request. Must be the same as the LAC, or
|
||||||
authentication will fail. Only actually be used if the LAC requests
|
authentication will fail. Only actually be used if the LAC requests
|
||||||
authentication.
|
authentication.
|
||||||
.TP
|
.TP
|
||||||
|
.B ppp_restart_time
|
||||||
|
Restart timer for PPP protocol negotiation in seconds (default: 3).
|
||||||
|
.TP
|
||||||
|
.B ppp_max_configure
|
||||||
|
Number of configure requests to send before giving up (default: 10).
|
||||||
|
.TP
|
||||||
|
.B ppp_max_failure
|
||||||
|
Number of Configure-Nak requests to send before sending a
|
||||||
|
Configure-Reject (default: 5).
|
||||||
|
.TP
|
||||||
.BR primary_dns , " secondary_dns"
|
.BR primary_dns , " secondary_dns"
|
||||||
Whenever a PPP connection is established, DNS servers will be sent to the
|
Whenever a PPP connection is established, DNS servers will be sent to the
|
||||||
user, both a primary and a secondary. If either is set to 0.0.0.0, then that
|
user, both a primary and a secondary. If either is set to 0.0.0.0, then that
|
||||||
|
|
|
||||||
15
Makefile
15
Makefile
|
|
@ -23,10 +23,10 @@ LDFLAGS =
|
||||||
LDLIBS =
|
LDLIBS =
|
||||||
INSTALL = install -c -D -o root -g root
|
INSTALL = install -c -D -o root -g root
|
||||||
|
|
||||||
l2tpns.LIBS = -lm -lcli -ldl
|
l2tpns.LIBS = -lcrypto -lm -lcli -ldl
|
||||||
|
|
||||||
OBJS = arp.o cli.o cluster.o constants.o control.o icmp.o l2tpns.o \
|
OBJS = arp.o cli.o cluster.o constants.o control.o icmp.o l2tpns.o \
|
||||||
ll.o md5.o ppp.o radius.o tbf.o util.o
|
ll.o ppp.o radius.o tbf.o util.o
|
||||||
|
|
||||||
PROGRAMS = l2tpns nsctl
|
PROGRAMS = l2tpns nsctl
|
||||||
PLUGINS = autosnoop.so autothrottle.so garden.so sessionctl.so \
|
PLUGINS = autosnoop.so autothrottle.so garden.so sessionctl.so \
|
||||||
|
|
@ -109,20 +109,19 @@ install: all
|
||||||
|
|
||||||
## Dependencies: (autogenerated) ##
|
## Dependencies: (autogenerated) ##
|
||||||
arp.o: arp.c l2tpns.h
|
arp.o: arp.c l2tpns.h
|
||||||
cli.o: cli.c l2tpns.h util.h cluster.h tbf.h ll.h bgp.h
|
cli.o: cli.c l2tpns.h constants.h util.h cluster.h tbf.h ll.h bgp.h
|
||||||
cluster.o: cluster.c l2tpns.h cluster.h util.h tbf.h bgp.h
|
cluster.o: cluster.c l2tpns.h cluster.h util.h tbf.h bgp.h
|
||||||
constants.o: constants.c constants.h
|
constants.o: constants.c constants.h
|
||||||
control.o: control.c l2tpns.h control.h
|
control.o: control.c l2tpns.h control.h
|
||||||
icmp.o: icmp.c l2tpns.h
|
icmp.o: icmp.c l2tpns.h
|
||||||
l2tpns.o: l2tpns.c md5.h l2tpns.h cluster.h plugin.h ll.h constants.h \
|
l2tpns.o: l2tpns.c l2tpns.h cluster.h plugin.h ll.h constants.h control.h \
|
||||||
control.h util.h tbf.h bgp.h
|
util.h tbf.h bgp.h fake_epoll.h
|
||||||
ll.o: ll.c ll.h
|
ll.o: ll.c ll.h
|
||||||
md5.o: md5.c md5.h
|
|
||||||
ppp.o: ppp.c l2tpns.h constants.h plugin.h util.h tbf.h cluster.h
|
ppp.o: ppp.c l2tpns.h constants.h plugin.h util.h tbf.h cluster.h
|
||||||
radius.o: radius.c md5.h constants.h l2tpns.h plugin.h util.h
|
radius.o: radius.c constants.h l2tpns.h plugin.h util.h cluster.h
|
||||||
tbf.o: tbf.c l2tpns.h util.h tbf.h
|
tbf.o: tbf.c l2tpns.h util.h tbf.h
|
||||||
util.o: util.c l2tpns.h bgp.h
|
util.o: util.c l2tpns.h bgp.h
|
||||||
bgp.o: bgp.c l2tpns.h bgp.h util.h
|
bgp.o: bgp.c l2tpns.h bgp.h util.h fake_epoll.h
|
||||||
autosnoop.so: autosnoop.c l2tpns.h plugin.h
|
autosnoop.so: autosnoop.c l2tpns.h plugin.h
|
||||||
autothrottle.so: autothrottle.c l2tpns.h plugin.h
|
autothrottle.so: autothrottle.c l2tpns.h plugin.h
|
||||||
garden.so: garden.c l2tpns.h plugin.h control.h
|
garden.so: garden.c l2tpns.h plugin.h control.h
|
||||||
|
|
|
||||||
1
THANKS
1
THANKS
|
|
@ -16,3 +16,4 @@ Bj
|
||||||
Roberto Chostakovis <rchostakovis@users.sourceforge.net>
|
Roberto Chostakovis <rchostakovis@users.sourceforge.net>
|
||||||
Jordan Hrycaj <jordan@mjh.teddy-net.com>
|
Jordan Hrycaj <jordan@mjh.teddy-net.com>
|
||||||
Vladislav Bjelic <vladislav@gmail.com>
|
Vladislav Bjelic <vladislav@gmail.com>
|
||||||
|
Alex Kiernan <alex.kiernan@gmail.com>
|
||||||
|
|
|
||||||
4
arp.c
4
arp.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS: arp
|
// L2TPNS: arp
|
||||||
|
|
||||||
char const *cvs_id_arp = "$Id: arp.c,v 1.6 2005/01/07 07:14:14 bodea Exp $";
|
char const *cvs_id_arp = "$Id: arp.c,v 1.7 2005/07/31 10:04:09 bodea Exp $";
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -55,7 +55,7 @@ void sendarp(int ifr_idx, const unsigned char* mac, in_addr_t ip)
|
||||||
|
|
||||||
memset(&sll, 0, sizeof(sll));
|
memset(&sll, 0, sizeof(sll));
|
||||||
sll.sll_family = AF_PACKET;
|
sll.sll_family = AF_PACKET;
|
||||||
strncpy(sll.sll_addr, mac, sizeof(sll.sll_addr) - 1);
|
memcpy(sll.sll_addr, mac, sizeof(sll.sll_addr) - 1);
|
||||||
sll.sll_halen = ETH_ALEN;
|
sll.sll_halen = ETH_ALEN;
|
||||||
sll.sll_ifindex = ifr_idx;
|
sll.sll_ifindex = ifr_idx;
|
||||||
|
|
||||||
|
|
|
||||||
4
bgp.c
4
bgp.c
|
|
@ -10,7 +10,7 @@
|
||||||
* nor RFC2385 (which requires a kernel patch on 2.4 kernels).
|
* nor RFC2385 (which requires a kernel patch on 2.4 kernels).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char const *cvs_id_bgp = "$Id: bgp.c,v 1.10 2005/06/04 15:42:35 bodea Exp $";
|
char const *cvs_id_bgp = "$Id: bgp.c,v 1.11 2005/07/31 10:04:09 bodea Exp $";
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -767,7 +767,7 @@ static int bgp_connect(struct bgp_peer *peer)
|
||||||
static int bgp_handle_connect(struct bgp_peer *peer)
|
static int bgp_handle_connect(struct bgp_peer *peer)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int len = sizeof(int);
|
socklen_t len = sizeof(int);
|
||||||
getsockopt(peer->sock, SOL_SOCKET, SO_ERROR, &err, &len);
|
getsockopt(peer->sock, SOL_SOCKET, SO_ERROR, &err, &len);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
21
cli.c
21
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.63 2005/06/28 14:48:17 bodea Exp $";
|
char const *cvs_id_cli = "$Id: cli.c,v 1.64 2005/07/31 10:04:09 bodea Exp $";
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
@ -25,6 +25,7 @@ char const *cvs_id_cli = "$Id: cli.c,v 1.63 2005/06/28 14:48:17 bodea Exp $";
|
||||||
#include <libcli.h>
|
#include <libcli.h>
|
||||||
|
|
||||||
#include "l2tpns.h"
|
#include "l2tpns.h"
|
||||||
|
#include "constants.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "cluster.h"
|
#include "cluster.h"
|
||||||
#include "tbf.h"
|
#include "tbf.h"
|
||||||
|
|
@ -289,7 +290,7 @@ void cli_do(int sockfd)
|
||||||
{
|
{
|
||||||
int require_auth = 1;
|
int require_auth = 1;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
int l = sizeof(addr);
|
socklen_t l = sizeof(addr);
|
||||||
|
|
||||||
if (fork_and_close()) return;
|
if (fork_and_close()) return;
|
||||||
if (getpeername(sockfd, (struct sockaddr *) &addr, &l) == 0)
|
if (getpeername(sockfd, (struct sockaddr *) &addr, &l) == 0)
|
||||||
|
|
@ -407,6 +408,19 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
|
||||||
cli_print(cli, "\tCalling Num:\t%s", session[s].calling);
|
cli_print(cli, "\tCalling Num:\t%s", session[s].calling);
|
||||||
cli_print(cli, "\tCalled Num:\t%s", session[s].called);
|
cli_print(cli, "\tCalled Num:\t%s", session[s].called);
|
||||||
cli_print(cli, "\tTunnel ID:\t%d", session[s].tunnel);
|
cli_print(cli, "\tTunnel ID:\t%d", session[s].tunnel);
|
||||||
|
cli_print(cli, "\tPPP Phase:\t%s", ppp_phase(session[s].ppp.phase));
|
||||||
|
switch (session[s].ppp.phase)
|
||||||
|
{
|
||||||
|
case Establish:
|
||||||
|
cli_print(cli, "\tLCP state:\t%s", ppp_state(session[s].ppp.lcp));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Authenticate:
|
||||||
|
case Network:
|
||||||
|
cli_print(cli, "\t IPCP state:\t%s", ppp_state(session[s].ppp.ipcp));
|
||||||
|
cli_print(cli, "\t IPV6CP state:\t%s", ppp_state(session[s].ppp.ipv6cp));
|
||||||
|
cli_print(cli, "\t CCP state:\t%s", ppp_state(session[s].ppp.ccp));
|
||||||
|
}
|
||||||
cli_print(cli, "\tIP address:\t%s", fmtaddr(htonl(session[s].ip), 0));
|
cli_print(cli, "\tIP address:\t%s", fmtaddr(htonl(session[s].ip), 0));
|
||||||
cli_print(cli, "\tUnique SID:\t%u", session[s].unique_id);
|
cli_print(cli, "\tUnique SID:\t%u", session[s].unique_id);
|
||||||
cli_print(cli, "\tOpened:\t\t%u seconds", session[s].opened ? abs(time_now - session[s].opened) : 0);
|
cli_print(cli, "\tOpened:\t\t%u seconds", session[s].opened ? abs(time_now - session[s].opened) : 0);
|
||||||
|
|
@ -507,7 +521,7 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
|
||||||
(session[i].snoop_ip && session[i].snoop_port) ? "Y" : "N",
|
(session[i].snoop_ip && session[i].snoop_port) ? "Y" : "N",
|
||||||
(session[i].throttle_in || session[i].throttle_out) ? "Y" : "N",
|
(session[i].throttle_in || session[i].throttle_out) ? "Y" : "N",
|
||||||
(session[i].walled_garden) ? "Y" : "N",
|
(session[i].walled_garden) ? "Y" : "N",
|
||||||
(session[i].flags & SF_IPV6CP_ACKED) ? "Y" : "N",
|
(session[i].ppp.ipv6cp == Opened) ? "Y" : "N",
|
||||||
abs(time_now - (unsigned long)session[i].opened),
|
abs(time_now - (unsigned long)session[i].opened),
|
||||||
(unsigned long)session[i].cout,
|
(unsigned long)session[i].cout,
|
||||||
(unsigned long)session[i].cin,
|
(unsigned long)session[i].cin,
|
||||||
|
|
@ -816,7 +830,6 @@ static int cmd_show_version(struct cli_def *cli, char *command, char **argv, int
|
||||||
cli_print(cli, " %s", cvs_id_icmp);
|
cli_print(cli, " %s", cvs_id_icmp);
|
||||||
cli_print(cli, " %s", cvs_id_l2tpns);
|
cli_print(cli, " %s", cvs_id_l2tpns);
|
||||||
cli_print(cli, " %s", cvs_id_ll);
|
cli_print(cli, " %s", cvs_id_ll);
|
||||||
cli_print(cli, " %s", cvs_id_md5);
|
|
||||||
cli_print(cli, " %s", cvs_id_ppp);
|
cli_print(cli, " %s", cvs_id_ppp);
|
||||||
cli_print(cli, " %s", cvs_id_radius);
|
cli_print(cli, " %s", cvs_id_radius);
|
||||||
cli_print(cli, " %s", cvs_id_tbf);
|
cli_print(cli, " %s", cvs_id_tbf);
|
||||||
|
|
|
||||||
93
cluster.c
93
cluster.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS Clustering Stuff
|
// L2TPNS Clustering Stuff
|
||||||
|
|
||||||
char const *cvs_id_cluster = "$Id: cluster.c,v 1.44 2005/06/28 14:48:19 bodea Exp $";
|
char const *cvs_id_cluster = "$Id: cluster.c,v 1.45 2005/07/31 10:04:09 bodea Exp $";
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -56,7 +56,7 @@ static struct {
|
||||||
static struct {
|
static struct {
|
||||||
int seq;
|
int seq;
|
||||||
int size;
|
int size;
|
||||||
char data[MAX_HEART_SIZE];
|
uint8_t data[MAX_HEART_SIZE];
|
||||||
} past_hearts[HB_HISTORY_SIZE]; // Ring buffer of heartbeats that we've recently sent out. Needed so
|
} past_hearts[HB_HISTORY_SIZE]; // Ring buffer of heartbeats that we've recently sent out. Needed so
|
||||||
// we can re-transmit if needed.
|
// we can re-transmit if needed.
|
||||||
|
|
||||||
|
|
@ -178,7 +178,7 @@ static int cluster_send_data(void *data, int datalen)
|
||||||
// Maintains the format. Assumes that the caller
|
// Maintains the format. Assumes that the caller
|
||||||
// has passed in a big enough buffer!
|
// has passed in a big enough buffer!
|
||||||
//
|
//
|
||||||
static void add_type(char **p, int type, int more, char *data, int size)
|
static void add_type(uint8_t **p, int type, int more, uint8_t *data, int size)
|
||||||
{
|
{
|
||||||
*((uint32_t *) (*p)) = type;
|
*((uint32_t *) (*p)) = type;
|
||||||
*p += sizeof(uint32_t);
|
*p += sizeof(uint32_t);
|
||||||
|
|
@ -231,7 +231,7 @@ static void cluster_uptodate(void)
|
||||||
// Send a unicast UDP packet to a peer with 'data' as the
|
// Send a unicast UDP packet to a peer with 'data' as the
|
||||||
// contents.
|
// contents.
|
||||||
//
|
//
|
||||||
static int peer_send_data(in_addr_t peer, char *data, int size)
|
static int peer_send_data(in_addr_t peer, uint8_t *data, int size)
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr = {0};
|
struct sockaddr_in addr = {0};
|
||||||
|
|
||||||
|
|
@ -259,10 +259,10 @@ static int peer_send_data(in_addr_t peer, char *data, int size)
|
||||||
//
|
//
|
||||||
// Send a structured message to a peer with a single element of type 'type'.
|
// Send a structured message to a peer with a single element of type 'type'.
|
||||||
//
|
//
|
||||||
static int peer_send_message(in_addr_t peer, int type, int more, char *data, int size)
|
static int peer_send_message(in_addr_t peer, int type, int more, uint8_t *data, int size)
|
||||||
{
|
{
|
||||||
char buf[65536]; // Vast overkill.
|
uint8_t buf[65536]; // Vast overkill.
|
||||||
char *p = buf;
|
uint8_t *p = buf;
|
||||||
|
|
||||||
LOG(4, 0, 0, "Sending message to peer (type %d, more %d, size %d)\n", type, more, size);
|
LOG(4, 0, 0, "Sending message to peer (type %d, more %d, size %d)\n", type, more, size);
|
||||||
add_type(&p, type, more, data, size);
|
add_type(&p, type, more, data, size);
|
||||||
|
|
@ -271,10 +271,10 @@ static int peer_send_message(in_addr_t peer, int type, int more, char *data, int
|
||||||
}
|
}
|
||||||
|
|
||||||
// send a packet to the master
|
// send a packet to the master
|
||||||
static int _forward_packet(char *data, int size, in_addr_t addr, int port, int type)
|
static int _forward_packet(uint8_t *data, int size, in_addr_t addr, int port, int type)
|
||||||
{
|
{
|
||||||
char buf[65536]; // Vast overkill.
|
uint8_t buf[65536]; // Vast overkill.
|
||||||
char *p = buf;
|
uint8_t *p = buf;
|
||||||
|
|
||||||
if (!config->cluster_master_address) // No election has been held yet. Just skip it.
|
if (!config->cluster_master_address) // No election has been held yet. Just skip it.
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -282,7 +282,7 @@ static int _forward_packet(char *data, int size, in_addr_t addr, int port, int t
|
||||||
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, type, addr, (char *) &port, sizeof(port)); // ick. should be uint16_t
|
add_type(&p, type, addr, (uint8_t *) &port, sizeof(port)); // ick. should be uint16_t
|
||||||
memcpy(p, data, size);
|
memcpy(p, data, size);
|
||||||
p += size;
|
p += size;
|
||||||
|
|
||||||
|
|
@ -295,13 +295,13 @@ static int _forward_packet(char *data, int size, in_addr_t addr, int port, int t
|
||||||
// The master just processes the payload as if it had
|
// The master just processes the payload as if it had
|
||||||
// received it off the tun device.
|
// received it off the tun device.
|
||||||
//
|
//
|
||||||
int master_forward_packet(char *data, int size, in_addr_t addr, int port)
|
int master_forward_packet(uint8_t *data, int size, in_addr_t addr, int port)
|
||||||
{
|
{
|
||||||
return _forward_packet(data, size, addr, port, C_FORWARD);
|
return _forward_packet(data, size, addr, port, C_FORWARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward a DAE RADIUS packet to the master.
|
// Forward a DAE RADIUS packet to the master.
|
||||||
int master_forward_dae_packet(char *data, int size, in_addr_t addr, int port)
|
int master_forward_dae_packet(uint8_t *data, int size, in_addr_t addr, int port)
|
||||||
{
|
{
|
||||||
return _forward_packet(data, size, addr, port, C_FORWARD_DAE);
|
return _forward_packet(data, size, addr, port, C_FORWARD_DAE);
|
||||||
}
|
}
|
||||||
|
|
@ -313,10 +313,10 @@ int master_forward_dae_packet(char *data, int size, in_addr_t addr, int port)
|
||||||
// token bucket queue, and lets normal processing take care
|
// token bucket queue, and lets normal processing take care
|
||||||
// of it.
|
// of it.
|
||||||
//
|
//
|
||||||
int master_throttle_packet(int tbfid, char *data, int size)
|
int master_throttle_packet(int tbfid, uint8_t *data, int size)
|
||||||
{
|
{
|
||||||
char buf[65536]; // Vast overkill.
|
uint8_t buf[65536]; // Vast overkill.
|
||||||
char *p = buf;
|
uint8_t *p = buf;
|
||||||
|
|
||||||
if (!config->cluster_master_address) // No election has been held yet. Just skip it.
|
if (!config->cluster_master_address) // No election has been held yet. Just skip it.
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -338,10 +338,10 @@ int master_throttle_packet(int tbfid, char *data, int size)
|
||||||
//
|
//
|
||||||
// (Note that this must be called with the tun header
|
// (Note that this must be called with the tun header
|
||||||
// as the start of the data).
|
// as the start of the data).
|
||||||
int master_garden_packet(sessionidt s, char *data, int size)
|
int master_garden_packet(sessionidt s, uint8_t *data, int size)
|
||||||
{
|
{
|
||||||
char buf[65536]; // Vast overkill.
|
uint8_t buf[65536]; // Vast overkill.
|
||||||
char *p = buf;
|
uint8_t *p = buf;
|
||||||
|
|
||||||
if (!config->cluster_master_address) // No election has been held yet. Just skip it.
|
if (!config->cluster_master_address) // No election has been held yet. Just skip it.
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -358,7 +358,7 @@ int master_garden_packet(sessionidt s, char *data, int size)
|
||||||
// Send a chunk of data as a heartbeat..
|
// Send a chunk of data as a heartbeat..
|
||||||
// We save it in the history buffer as we do so.
|
// We save it in the history buffer as we do so.
|
||||||
//
|
//
|
||||||
static void send_heartbeat(int seq, char *data, int size)
|
static void send_heartbeat(int seq, uint8_t *data, int size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
@ -380,8 +380,8 @@ static void send_heartbeat(int seq, char *data, int size)
|
||||||
//
|
//
|
||||||
void cluster_send_ping(time_t basetime)
|
void cluster_send_ping(time_t basetime)
|
||||||
{
|
{
|
||||||
char buff[100 + sizeof(pingt)];
|
uint8_t buff[100 + sizeof(pingt)];
|
||||||
char *p = buff;
|
uint8_t *p = buff;
|
||||||
pingt x;
|
pingt x;
|
||||||
|
|
||||||
if (config->cluster_iam_master && basetime) // We're heartbeating so no need to ping.
|
if (config->cluster_iam_master && basetime) // We're heartbeating so no need to ping.
|
||||||
|
|
@ -394,7 +394,7 @@ void cluster_send_ping(time_t basetime)
|
||||||
x.undef = config->cluster_undefined_sessions + config->cluster_undefined_tunnels;
|
x.undef = config->cluster_undefined_sessions + config->cluster_undefined_tunnels;
|
||||||
x.basetime = basetime;
|
x.basetime = basetime;
|
||||||
|
|
||||||
add_type(&p, C_PING, basetime, (char *) &x, sizeof(x));
|
add_type(&p, C_PING, basetime, (uint8_t *) &x, sizeof(x));
|
||||||
cluster_send_data(buff, (p-buff) );
|
cluster_send_data(buff, (p-buff) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -456,7 +456,7 @@ void master_update_counts(void)
|
||||||
|
|
||||||
// Forward the data to the master.
|
// Forward the data to the master.
|
||||||
LOG(4, 0, 0, "Sending byte counters to master (%d elements)\n", c);
|
LOG(4, 0, 0, "Sending byte counters to master (%d elements)\n", c);
|
||||||
peer_send_message(config->cluster_master_address, C_BYTES, c, (char *) &b, sizeof(b[0]) * c);
|
peer_send_message(config->cluster_master_address, C_BYTES, c, (uint8_t *) &b, sizeof(b[0]) * c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -738,7 +738,7 @@ static void cluster_check_sessions(int highsession, int freesession_ptr, int hig
|
||||||
cluster_uptodate();
|
cluster_uptodate();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hb_add_type(char **p, int type, int id)
|
static int hb_add_type(uint8_t **p, int type, int id)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case C_CSESSION: { // Compressed C_SESSION.
|
case C_CSESSION: { // Compressed C_SESSION.
|
||||||
|
|
@ -752,13 +752,13 @@ static int hb_add_type(char **p, int type, int id)
|
||||||
// Did we compress the full structure, and is the size actually
|
// Did we compress the full structure, and is the size actually
|
||||||
// reduced??
|
// reduced??
|
||||||
if ( (d - orig) == sizeof(sessiont) && size < sizeof(sessiont) ) {
|
if ( (d - orig) == sizeof(sessiont) && size < sizeof(sessiont) ) {
|
||||||
add_type(p, C_CSESSION, id, (char *) c, size);
|
add_type(p, C_CSESSION, id, c, size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Failed to compress : Fall through.
|
// Failed to compress : Fall through.
|
||||||
}
|
}
|
||||||
case C_SESSION: add_type(p, C_SESSION, id,
|
case C_SESSION:
|
||||||
(char *) &session[id], sizeof(sessiont));
|
add_type(p, C_SESSION, id, (uint8_t *) &session[id], sizeof(sessiont));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case C_CTUNNEL: { // Compressed C_TUNNEL
|
case C_CTUNNEL: { // Compressed C_TUNNEL
|
||||||
|
|
@ -777,8 +777,8 @@ static int hb_add_type(char **p, int type, int id)
|
||||||
}
|
}
|
||||||
// Failed to compress : Fall through.
|
// Failed to compress : Fall through.
|
||||||
}
|
}
|
||||||
case C_TUNNEL: add_type(p, C_TUNNEL, id,
|
case C_TUNNEL:
|
||||||
(char *) &tunnel[id], sizeof(tunnelt));
|
add_type(p, C_TUNNEL, id, (uint8_t *) &tunnel[id], sizeof(tunnelt));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG(0, 0, 0, "Found an invalid type in heart queue! (%d)\n", type);
|
LOG(0, 0, 0, "Found an invalid type in heart queue! (%d)\n", type);
|
||||||
|
|
@ -794,9 +794,9 @@ static int hb_add_type(char **p, int type, int id)
|
||||||
void cluster_heartbeat()
|
void cluster_heartbeat()
|
||||||
{
|
{
|
||||||
int i, count = 0, tcount = 0;
|
int i, count = 0, tcount = 0;
|
||||||
char buff[MAX_HEART_SIZE + sizeof(heartt) + sizeof(int) ];
|
uint8_t buff[MAX_HEART_SIZE + sizeof(heartt) + sizeof(int) ];
|
||||||
heartt h;
|
heartt h;
|
||||||
char *p = buff;
|
uint8_t *p = buff;
|
||||||
|
|
||||||
if (!config->cluster_iam_master) // Only the master does this.
|
if (!config->cluster_iam_master) // Only the master does this.
|
||||||
return;
|
return;
|
||||||
|
|
@ -820,7 +820,7 @@ void cluster_heartbeat()
|
||||||
h.timeout = config->cluster_hb_timeout;
|
h.timeout = config->cluster_hb_timeout;
|
||||||
h.table_version = config->cluster_table_version;
|
h.table_version = config->cluster_table_version;
|
||||||
|
|
||||||
add_type(&p, C_HEARTBEAT, HB_VERSION, (char *) &h, sizeof(h));
|
add_type(&p, C_HEARTBEAT, HB_VERSION, (uint8_t *) &h, sizeof(h));
|
||||||
|
|
||||||
for (i = 0; i < config->cluster_num_changes; ++i) {
|
for (i = 0; i < config->cluster_num_changes; ++i) {
|
||||||
hb_add_type(&p, cluster_changes[i].type, cluster_changes[i].id);
|
hb_add_type(&p, cluster_changes[i].type, cluster_changes[i].id);
|
||||||
|
|
@ -1099,7 +1099,7 @@ static int cluster_set_master(in_addr_t peer, in_addr_t master)
|
||||||
// Note that we don't mark the session as dirty; We rely on
|
// Note that we don't mark the session as dirty; We rely on
|
||||||
// the slow table walk to propogate this back out to the slaves.
|
// the slow table walk to propogate this back out to the slaves.
|
||||||
//
|
//
|
||||||
static int cluster_handle_bytes(char *data, int size)
|
static int cluster_handle_bytes(uint8_t *data, int size)
|
||||||
{
|
{
|
||||||
bytest *b;
|
bytest *b;
|
||||||
|
|
||||||
|
|
@ -1238,6 +1238,9 @@ struct oldsession {
|
||||||
uint32_t tx_connect_speed;
|
uint32_t tx_connect_speed;
|
||||||
uint32_t rx_connect_speed;
|
uint32_t rx_connect_speed;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
#define SF_IPCP_ACKED 1 // Has this session seen an IPCP Ack?
|
||||||
|
#define SF_LCP_ACKED 2 // LCP negotiated
|
||||||
|
#define SF_CCP_ACKED 4 // CCP negotiated
|
||||||
in_addr_t snoop_ip;
|
in_addr_t snoop_ip;
|
||||||
uint16_t snoop_port;
|
uint16_t snoop_port;
|
||||||
uint16_t sid;
|
uint16_t sid;
|
||||||
|
|
@ -1257,7 +1260,6 @@ static uint8_t *convert_session(struct oldsession *old)
|
||||||
new.far = old->far;
|
new.far = old->far;
|
||||||
new.tunnel = old->tunnel;
|
new.tunnel = old->tunnel;
|
||||||
new.l2tp_flags = old->l2tp_flags;
|
new.l2tp_flags = old->l2tp_flags;
|
||||||
new.flags = old->flags;
|
|
||||||
new.ip = old->ip;
|
new.ip = old->ip;
|
||||||
new.ip_pool_index = old->ip_pool_index;
|
new.ip_pool_index = old->ip_pool_index;
|
||||||
new.unique_id = old->unique_id;
|
new.unique_id = old->unique_id;
|
||||||
|
|
@ -1297,6 +1299,21 @@ static uint8_t *convert_session(struct oldsession *old)
|
||||||
for (i = 0; i < MAXROUTE; i++)
|
for (i = 0; i < MAXROUTE; i++)
|
||||||
memcpy(&new.route[i], &old->route[i], sizeof(new.route[i]));
|
memcpy(&new.route[i], &old->route[i], sizeof(new.route[i]));
|
||||||
|
|
||||||
|
if (new.opened)
|
||||||
|
{
|
||||||
|
new.ppp.phase = Establish;
|
||||||
|
if (old->flags & (SF_IPCP_ACKED|SF_LCP_ACKED))
|
||||||
|
{
|
||||||
|
new.ppp.phase = Network;
|
||||||
|
new.ppp.lcp = Opened;
|
||||||
|
new.ppp.ipcp = (old->flags & SF_IPCP_ACKED) ? Opened : Starting;
|
||||||
|
new.ppp.ccp = (old->flags & SF_CCP_ACKED) ? Opened : Stopped;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no PPPv6 in old session
|
||||||
|
new.ppp.ipv6cp = Stopped;
|
||||||
|
}
|
||||||
|
|
||||||
return (uint8_t *) &new;
|
return (uint8_t *) &new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1572,10 +1589,10 @@ shortpacket:
|
||||||
// We got a packet on the cluster port!
|
// We got a packet on the cluster port!
|
||||||
// Handle pings, lastseens, and heartbeats!
|
// Handle pings, lastseens, and heartbeats!
|
||||||
//
|
//
|
||||||
int processcluster(char *data, int size, in_addr_t addr)
|
int processcluster(uint8_t *data, int size, in_addr_t addr)
|
||||||
{
|
{
|
||||||
int type, more;
|
int type, more;
|
||||||
char *p = data;
|
uint8_t *p = data;
|
||||||
int s = size;
|
int s = size;
|
||||||
|
|
||||||
if (addr == my_address)
|
if (addr == my_address)
|
||||||
|
|
@ -1814,7 +1831,7 @@ static int rle_decompress(uint8_t **src_p, int ssize, uint8_t *dst, int dsize)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
int orig_dsize = dsize;
|
int orig_dsize = dsize;
|
||||||
char *src = *src_p;
|
uint8_t *src = *src_p;
|
||||||
|
|
||||||
while (ssize >0 && dsize > 0) { // While there's more to decompress, and there's room in the decompress buffer...
|
while (ssize >0 && dsize > 0) { // While there's more to decompress, and there's room in the decompress buffer...
|
||||||
count = *src++; --ssize; // get the count byte from the source.
|
count = *src++; --ssize; // get the count byte from the source.
|
||||||
|
|
|
||||||
12
cluster.h
12
cluster.h
|
|
@ -1,5 +1,5 @@
|
||||||
// L2TPNS Clustering Stuff
|
// L2TPNS Clustering Stuff
|
||||||
// $Id: cluster.h,v 1.13 2005/06/28 14:48:19 bodea Exp $
|
// $Id: cluster.h,v 1.14 2005/07/31 10:04:10 bodea Exp $
|
||||||
|
|
||||||
#ifndef __CLUSTER_H__
|
#ifndef __CLUSTER_H__
|
||||||
#define __CLUSTER_H__
|
#define __CLUSTER_H__
|
||||||
|
|
@ -72,13 +72,13 @@ typedef struct {
|
||||||
} pingt;
|
} pingt;
|
||||||
|
|
||||||
int cluster_init(void);
|
int cluster_init(void);
|
||||||
int processcluster(char *buf, int size, in_addr_t addr);
|
int processcluster(uint8_t *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(uint8_t *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_forward_dae_packet(uint8_t *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, uint8_t *data, int size);
|
||||||
int master_garden_packet(sessionidt s, char *data, int size);
|
int master_garden_packet(sessionidt s, uint8_t *data, int size);
|
||||||
void master_update_counts(void);
|
void master_update_counts(void);
|
||||||
void cluster_send_ping(time_t basetime);
|
void cluster_send_ping(time_t basetime);
|
||||||
void cluster_heartbeat(void);
|
void cluster_heartbeat(void);
|
||||||
|
|
|
||||||
102
constants.c
102
constants.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS: constants
|
// L2TPNS: constants
|
||||||
|
|
||||||
char const *cvs_id_constants = "$Id: constants.c,v 1.6 2005/06/28 14:48:20 bodea Exp $";
|
char const *cvs_id_constants = "$Id: constants.c,v 1.7 2005/07/31 10:04:10 bodea Exp $";
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
|
@ -19,19 +19,27 @@ char const *cvs_id_constants = "$Id: constants.c,v 1.6 2005/06/28 14:48:20 bodea
|
||||||
return n; \
|
return n; \
|
||||||
}
|
}
|
||||||
|
|
||||||
CONSTANT(lcp_type,
|
CONSTANT(l2tp_code,
|
||||||
0, // 0
|
0, // 0
|
||||||
"Maximum-Receive-Unit", // 1
|
"SCCRQ", // 1
|
||||||
"Async-Control-Map", // 2
|
"SCCRP", // 2
|
||||||
"Authentication-Protocol", // 3
|
"SCCCN", // 3
|
||||||
"Quality-Protocol", // 4
|
"StopCCN", // 4
|
||||||
"Magic-Number", // 5
|
0, // 5
|
||||||
0, // 6
|
"HELLO", // 6
|
||||||
"Protocol-Field-Compression", // 7
|
"OCRQ", // 7
|
||||||
"Address-and-Control-Field-Compression" // 8
|
"OCRP", // 8
|
||||||
|
"OCCN", // 9
|
||||||
|
"ICRQ", // 10
|
||||||
|
"ICRP", // 11
|
||||||
|
"ICCN", // 12
|
||||||
|
0, // 13
|
||||||
|
"CDN", // 14
|
||||||
|
"WEN", // 15
|
||||||
|
"SLI" // 16
|
||||||
)
|
)
|
||||||
|
|
||||||
CONSTANT(avp_name,
|
CONSTANT(l2tp_avp_name,
|
||||||
"Message Type", // 0
|
"Message Type", // 0
|
||||||
"Result Code", // 1
|
"Result Code", // 1
|
||||||
"Protocol Version", // 2
|
"Protocol Version", // 2
|
||||||
|
|
@ -74,7 +82,7 @@ CONSTANT(avp_name,
|
||||||
"Sequencing Required" // 39
|
"Sequencing Required" // 39
|
||||||
)
|
)
|
||||||
|
|
||||||
CONSTANT(stopccn_result_code,
|
CONSTANT(l2tp_stopccn_result_code,
|
||||||
0, // 0
|
0, // 0
|
||||||
"General request to clear control connection", // 1
|
"General request to clear control connection", // 1
|
||||||
"General error--Error Code indicates the problem", // 2
|
"General error--Error Code indicates the problem", // 2
|
||||||
|
|
@ -87,7 +95,7 @@ CONSTANT(stopccn_result_code,
|
||||||
"Finite State Machine error" // 7
|
"Finite State Machine error" // 7
|
||||||
)
|
)
|
||||||
|
|
||||||
CONSTANT(cdn_result_code,
|
CONSTANT(l2tp_cdn_result_code,
|
||||||
0, // 0
|
0, // 0
|
||||||
"Call disconnected due to loss of carrier", // 1
|
"Call disconnected due to loss of carrier", // 1
|
||||||
"Call disconnected for the reason indicated in"
|
"Call disconnected for the reason indicated in"
|
||||||
|
|
@ -107,7 +115,7 @@ CONSTANT(cdn_result_code,
|
||||||
" detected" // 11
|
" detected" // 11
|
||||||
)
|
)
|
||||||
|
|
||||||
CONSTANT(error_code,
|
CONSTANT(l2tp_error_code,
|
||||||
"No general error", // 0
|
"No general error", // 0
|
||||||
"No control connection exists yet for this LAC-LNS"
|
"No control connection exists yet for this LAC-LNS"
|
||||||
" pair", // 1
|
" pair", // 1
|
||||||
|
|
@ -124,7 +132,28 @@ CONSTANT(error_code,
|
||||||
" an unknown AVP with the M-bit set" // 8
|
" an unknown AVP with the M-bit set" // 8
|
||||||
)
|
)
|
||||||
|
|
||||||
CONSTANT(auth_type,
|
CONSTANT(ppp_phase,
|
||||||
|
"Dead", // 0
|
||||||
|
"Establish", // 1
|
||||||
|
"Authenticate", // 2
|
||||||
|
"Network", // 3
|
||||||
|
"Terminate", // 4
|
||||||
|
)
|
||||||
|
|
||||||
|
CONSTANT(ppp_state,
|
||||||
|
"Initial", // 0
|
||||||
|
"Starting", // 1
|
||||||
|
"Closed", // 2
|
||||||
|
"Stopped", // 3
|
||||||
|
"Closing", // 4
|
||||||
|
"Stopping", // 5
|
||||||
|
"Request-Sent", // 6
|
||||||
|
"Ack-Received", // 7
|
||||||
|
"Ack-Sent", // 8
|
||||||
|
"Opened" // 9
|
||||||
|
)
|
||||||
|
|
||||||
|
CONSTANT(ppp_auth_type,
|
||||||
0, // 0
|
0, // 0
|
||||||
"Textual username/password exchange", // 1
|
"Textual username/password exchange", // 1
|
||||||
"PPP CHAP", // 2
|
"PPP CHAP", // 2
|
||||||
|
|
@ -133,7 +162,7 @@ CONSTANT(auth_type,
|
||||||
"Microsoft CHAP Version 1 (MSCHAPv1)" // 5
|
"Microsoft CHAP Version 1 (MSCHAPv1)" // 5
|
||||||
)
|
)
|
||||||
|
|
||||||
CONSTANT(ppp_lcp_type,
|
CONSTANT(ppp_code,
|
||||||
0, // 0
|
0, // 0
|
||||||
"ConfigReq", // 1
|
"ConfigReq", // 1
|
||||||
"ConfigAck", // 2
|
"ConfigAck", // 2
|
||||||
|
|
@ -149,15 +178,26 @@ CONSTANT(ppp_lcp_type,
|
||||||
"IdentRequest" // 12
|
"IdentRequest" // 12
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CONSTANT(ppp_lcp_option,
|
||||||
|
0, // 0
|
||||||
|
"Maximum-Receive-Unit", // 1
|
||||||
|
"Async-Control-Map", // 2
|
||||||
|
"Authentication-Protocol", // 3
|
||||||
|
"Quality-Protocol", // 4
|
||||||
|
"Magic-Number", // 5
|
||||||
|
0, // 6
|
||||||
|
"Protocol-Field-Compression", // 7
|
||||||
|
"Address-and-Control-Field-Compression" // 8
|
||||||
|
)
|
||||||
|
|
||||||
CONSTANT(radius_state,
|
CONSTANT(radius_state,
|
||||||
"RADIUSNULL", // 0
|
"RADIUSNULL", // 0
|
||||||
"RADIUSCHAP", // 1
|
"RADIUSCHAP", // 1
|
||||||
"RADIUSAUTH", // 2
|
"RADIUSAUTH", // 2
|
||||||
"RADIUSIPCP", // 3
|
"RADIUSSTART", // 3
|
||||||
"RADIUSSTART", // 4
|
"RADIUSSTOP", // 4
|
||||||
"RADIUSSTOP", // 5
|
"RADIUSINTERIM", // 5
|
||||||
"RADIUSINTERIM", // 6
|
"RADIUSWAIT" // 6
|
||||||
"RADIUSWAIT" // 7
|
|
||||||
)
|
)
|
||||||
|
|
||||||
CONSTANT(radius_code,
|
CONSTANT(radius_code,
|
||||||
|
|
@ -185,23 +225,3 @@ CONSTANT(radius_code,
|
||||||
"CoA-ACK", // 44
|
"CoA-ACK", // 44
|
||||||
"CoA-NAK" // 45
|
"CoA-NAK" // 45
|
||||||
)
|
)
|
||||||
|
|
||||||
CONSTANT(l2tp_message_type,
|
|
||||||
0, // 0
|
|
||||||
"SCCRQ", // 1
|
|
||||||
"SCCRP", // 2
|
|
||||||
"SCCCN", // 3
|
|
||||||
"StopCCN", // 4
|
|
||||||
0, // 5
|
|
||||||
"HELLO", // 6
|
|
||||||
"OCRQ", // 7
|
|
||||||
"OCRP", // 8
|
|
||||||
"OCCN", // 9
|
|
||||||
"ICRQ", // 10
|
|
||||||
"ICRP", // 11
|
|
||||||
"ICCN", // 12
|
|
||||||
0, // 13
|
|
||||||
"CDN", // 14
|
|
||||||
"WEN", // 15
|
|
||||||
"SLI" // 16
|
|
||||||
)
|
|
||||||
|
|
|
||||||
18
constants.h
18
constants.h
|
|
@ -1,15 +1,17 @@
|
||||||
#ifndef __CONSTANTS_H__
|
#ifndef __CONSTANTS_H__
|
||||||
#define __CONSTANTS_H__
|
#define __CONSTANTS_H__
|
||||||
|
|
||||||
char const *lcp_type(int type);
|
char const *l2tp_code(int type);
|
||||||
char const *avp_name(int avp);
|
char const *l2tp_avp_name(int avp);
|
||||||
char const *stopccn_result_code(int code);
|
char const *l2tp_stopccn_result_code(int code);
|
||||||
char const *cdn_result_code(int code);
|
char const *l2tp_cdn_result_code(int code);
|
||||||
char const *error_code(int code);
|
char const *l2tp_error_code(int code);
|
||||||
char const *auth_type(int type);
|
char const *ppp_phase(int code);
|
||||||
char const *ppp_lcp_type(int type);
|
char const *ppp_state(int code);
|
||||||
|
char const *ppp_auth_type(int type);
|
||||||
|
char const *ppp_code(int type);
|
||||||
|
char const *ppp_lcp_option(int type);
|
||||||
char const *radius_state(int state);
|
char const *radius_state(int state);
|
||||||
char const *radius_code(int code);
|
char const *radius_code(int code);
|
||||||
char const *l2tp_message_type(int type);
|
|
||||||
|
|
||||||
#endif /* __CONSTANTS_H__ */
|
#endif /* __CONSTANTS_H__ */
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
// L2TPNS: control
|
// L2TPNS: control
|
||||||
|
|
||||||
char const *cvs_id_control = "$Id: control.c,v 1.4 2004/12/16 08:49:53 bodea Exp $";
|
char const *cvs_id_control = "$Id: control.c,v 1.5 2005/07/31 10:04:10 bodea Exp $";
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "l2tpns.h"
|
#include "l2tpns.h"
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
|
|
||||||
int pack_control(char *data, int len, uint8_t type, int argc, char *argv[])
|
int pack_control(uint8_t *data, int len, uint8_t type, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct nsctl_packet pkt;
|
struct nsctl_packet pkt;
|
||||||
struct nsctl_args arg;
|
struct nsctl_args arg;
|
||||||
|
|
@ -62,7 +62,7 @@ int pack_control(char *data, int len, uint8_t type, int argc, char *argv[])
|
||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unpack_control(struct nsctl *control, char *data, int len)
|
int unpack_control(struct nsctl *control, uint8_t *data, int len)
|
||||||
{
|
{
|
||||||
struct nsctl_packet pkt;
|
struct nsctl_packet pkt;
|
||||||
char *p = pkt.argv;
|
char *p = pkt.argv;
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,8 @@ struct nsctl {
|
||||||
char *argv[0xff];
|
char *argv[0xff];
|
||||||
};
|
};
|
||||||
|
|
||||||
int pack_control(char *data, int len, uint8_t type, int argc, char *argv[]);
|
int pack_control(uint8_t *data, int len, uint8_t type, int argc, char *argv[]);
|
||||||
int unpack_control(struct nsctl *packet, char *data, int len);
|
int unpack_control(struct nsctl *packet, uint8_t *data, int len);
|
||||||
void dump_control(struct nsctl *control, FILE *stream);
|
void dump_control(struct nsctl *control, FILE *stream);
|
||||||
|
|
||||||
#endif /* __CONTROL_H__ */
|
#endif /* __CONTROL_H__ */
|
||||||
|
|
|
||||||
14
icmp.c
14
icmp.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS: icmp
|
// L2TPNS: icmp
|
||||||
|
|
||||||
char const *cvs_id_icmp = "$Id: icmp.c,v 1.8 2005/06/04 15:42:06 bodea Exp $";
|
char const *cvs_id_icmp = "$Id: icmp.c,v 1.9 2005/07/31 10:04:10 bodea Exp $";
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
@ -18,7 +18,7 @@ char const *cvs_id_icmp = "$Id: icmp.c,v 1.8 2005/06/04 15:42:06 bodea Exp $";
|
||||||
|
|
||||||
#include "l2tpns.h"
|
#include "l2tpns.h"
|
||||||
|
|
||||||
static uint16_t _checksum(unsigned char *addr, int count);
|
static uint16_t _checksum(uint8_t *addr, int count);
|
||||||
|
|
||||||
struct ipv6_pseudo_hdr {
|
struct ipv6_pseudo_hdr {
|
||||||
struct in6_addr src;
|
struct in6_addr src;
|
||||||
|
|
@ -28,7 +28,7 @@ struct ipv6_pseudo_hdr {
|
||||||
uint32_t nexthdr : 8;
|
uint32_t nexthdr : 8;
|
||||||
};
|
};
|
||||||
|
|
||||||
void host_unreachable(in_addr_t destination, uint16_t id, in_addr_t source, char *packet, int packet_len)
|
void host_unreachable(in_addr_t destination, uint16_t id, in_addr_t source, uint8_t *packet, int packet_len)
|
||||||
{
|
{
|
||||||
char buf[128] = {0};
|
char buf[128] = {0};
|
||||||
struct iphdr *iph;
|
struct iphdr *iph;
|
||||||
|
|
@ -72,15 +72,15 @@ void host_unreachable(in_addr_t destination, uint16_t id, in_addr_t source, char
|
||||||
|
|
||||||
icmp->type = ICMP_DEST_UNREACH;
|
icmp->type = ICMP_DEST_UNREACH;
|
||||||
icmp->code = ICMP_HOST_UNREACH;
|
icmp->code = ICMP_HOST_UNREACH;
|
||||||
icmp->checksum = _checksum((char *) icmp, sizeof(struct icmphdr) + packet_len);
|
icmp->checksum = _checksum((uint8_t *) icmp, sizeof(struct icmphdr) + packet_len);
|
||||||
|
|
||||||
iph->check = _checksum((char *) iph, sizeof(struct iphdr));
|
iph->check = _checksum((uint8_t *) iph, sizeof(struct iphdr));
|
||||||
|
|
||||||
sendto(icmp_socket, (char *)buf, len, 0, (struct sockaddr *)&whereto, sizeof(struct sockaddr));
|
sendto(icmp_socket, buf, len, 0, (struct sockaddr *)&whereto, sizeof(struct sockaddr));
|
||||||
close(icmp_socket);
|
close(icmp_socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t _checksum(unsigned char *addr, int count)
|
static uint16_t _checksum(uint8_t *addr, int count)
|
||||||
{
|
{
|
||||||
register long sum = 0;
|
register long sum = 0;
|
||||||
|
|
||||||
|
|
|
||||||
333
l2tpns.c
333
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.114 2005/07/04 05:49:46 bodea Exp $";
|
char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.115 2005/07/31 10:04:10 bodea Exp $";
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
@ -38,9 +38,9 @@ char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.114 2005/07/04 05:49:46 bodea Exp
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
|
#include <openssl/md5.h>
|
||||||
#include <libcli.h>
|
#include <libcli.h>
|
||||||
|
|
||||||
#include "md5.h"
|
|
||||||
#include "l2tpns.h"
|
#include "l2tpns.h"
|
||||||
#include "cluster.h"
|
#include "cluster.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
@ -105,6 +105,9 @@ config_descriptt config_values[] = {
|
||||||
CONFIG("pid_file", pid_file, STRING),
|
CONFIG("pid_file", pid_file, STRING),
|
||||||
CONFIG("random_device", random_device, STRING),
|
CONFIG("random_device", random_device, STRING),
|
||||||
CONFIG("l2tp_secret", l2tpsecret, STRING),
|
CONFIG("l2tp_secret", l2tpsecret, STRING),
|
||||||
|
CONFIG("ppp_restart_time", ppp_restart_time, INT),
|
||||||
|
CONFIG("ppp_max_configure", ppp_max_configure, INT),
|
||||||
|
CONFIG("ppp_max_failure", ppp_max_failure, INT),
|
||||||
CONFIG("primary_dns", default_dns1, IPv4),
|
CONFIG("primary_dns", default_dns1, IPv4),
|
||||||
CONFIG("secondary_dns", default_dns2, IPv4),
|
CONFIG("secondary_dns", default_dns2, IPv4),
|
||||||
CONFIG("primary_radius", radiusserver[0], IPv4),
|
CONFIG("primary_radius", radiusserver[0], IPv4),
|
||||||
|
|
@ -182,7 +185,7 @@ static void sighup_handler(int sig);
|
||||||
static void sigalrm_handler(int sig);
|
static void sigalrm_handler(int sig);
|
||||||
static void shutdown_handler(int sig);
|
static void shutdown_handler(int sig);
|
||||||
static void sigchild_handler(int sig);
|
static void sigchild_handler(int sig);
|
||||||
static void build_chap_response(char *challenge, uint8_t id, uint16_t challenge_length, char **challenge_response);
|
static void build_chap_response(uint8_t *challenge, uint8_t id, uint16_t challenge_length, uint8_t **challenge_response);
|
||||||
static void update_config(void);
|
static void update_config(void);
|
||||||
static void read_config_file(void);
|
static void read_config_file(void);
|
||||||
static void initplugins(void);
|
static void initplugins(void);
|
||||||
|
|
@ -258,10 +261,10 @@ void _log(int level, sessionidt s, tunnelidt t, const char *format, ...)
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _log_hex(int level, const char *title, const char *data, int maxsize)
|
void _log_hex(int level, const char *title, const uint8_t *data, int maxsize)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
const uint8_t *d = (const uint8_t *) data;
|
const uint8_t *d = data;
|
||||||
|
|
||||||
if (config->debug < level) return;
|
if (config->debug < level) return;
|
||||||
|
|
||||||
|
|
@ -551,7 +554,7 @@ static void inittun(void)
|
||||||
tunidx = ifr.ifr_ifindex;
|
tunidx = ifr.ifr_ifindex;
|
||||||
|
|
||||||
// Only setup IPv6 on the tun device if we have a configured prefix
|
// Only setup IPv6 on the tun device if we have a configured prefix
|
||||||
if (config->ipv6_prefix.s6_addr[0] > 0) {
|
if (config->ipv6_prefix.s6_addr[0]) {
|
||||||
ifr6fd = socket(PF_INET6, SOCK_DGRAM, 0);
|
ifr6fd = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
// Link local address is FE80::1
|
// Link local address is FE80::1
|
||||||
|
|
@ -702,8 +705,11 @@ sessionidt sessionbyipv6(struct in6_addr ip)
|
||||||
CSTAT(sessionbyipv6);
|
CSTAT(sessionbyipv6);
|
||||||
|
|
||||||
if (!memcmp(&config->ipv6_prefix, &ip, 8) ||
|
if (!memcmp(&config->ipv6_prefix, &ip, 8) ||
|
||||||
(ip.s6_addr[0] == 0xFE && ip.s6_addr[1] == 0x80 &&
|
(ip.s6_addr[0] == 0xFE &&
|
||||||
(ip.s6_addr16[1] == ip.s6_addr16[2] == ip.s6_addr16[3] == 0))) {
|
ip.s6_addr[1] == 0x80 &&
|
||||||
|
ip.s6_addr16[1] == 0 &&
|
||||||
|
ip.s6_addr16[2] == 0 &&
|
||||||
|
ip.s6_addr16[3] == 0)) {
|
||||||
s = lookup_ipmap(*(in_addr_t *) &ip.s6_addr[8]);
|
s = lookup_ipmap(*(in_addr_t *) &ip.s6_addr[8]);
|
||||||
} else {
|
} else {
|
||||||
s = lookup_ipv6map(ip);
|
s = lookup_ipv6map(ip);
|
||||||
|
|
@ -980,7 +986,7 @@ static void processipout(uint8_t * buf, int len)
|
||||||
tunnelidt t;
|
tunnelidt t;
|
||||||
in_addr_t ip;
|
in_addr_t ip;
|
||||||
|
|
||||||
char *data = buf; // Keep a copy of the originals.
|
uint8_t *data = buf; // Keep a copy of the originals.
|
||||||
int size = len;
|
int size = len;
|
||||||
|
|
||||||
uint8_t b[MAXETHER + 20];
|
uint8_t b[MAXETHER + 20];
|
||||||
|
|
@ -1126,7 +1132,7 @@ static void processipv6out(uint8_t * buf, int len)
|
||||||
in_addr_t ip;
|
in_addr_t ip;
|
||||||
struct in6_addr ip6;
|
struct in6_addr ip6;
|
||||||
|
|
||||||
char *data = buf; // Keep a copy of the originals.
|
uint8_t *data = buf; // Keep a copy of the originals.
|
||||||
int size = len;
|
int size = len;
|
||||||
|
|
||||||
uint8_t b[MAXETHER + 20];
|
uint8_t b[MAXETHER + 20];
|
||||||
|
|
@ -1313,7 +1319,7 @@ static void controls(controlt * c, uint16_t avp, char *val, uint8_t m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a binary AVP
|
// add a binary AVP
|
||||||
static void controlb(controlt * c, uint16_t avp, char *val, unsigned int len, uint8_t m)
|
static void controlb(controlt * c, uint16_t avp, uint8_t *val, unsigned int len, uint8_t m)
|
||||||
{
|
{
|
||||||
uint16_t l = ((m ? 0x8000 : 0) + len + 6);
|
uint16_t l = ((m ? 0x8000 : 0) + len + 6);
|
||||||
*(uint16_t *) (c->buf + c->length + 0) = htons(l);
|
*(uint16_t *) (c->buf + c->length + 0) = htons(l);
|
||||||
|
|
@ -1493,10 +1499,7 @@ void sessionshutdown(sessionidt s, char *reason, int result, int error)
|
||||||
if (session[s].ip && !walled_garden && !session[s].die)
|
if (session[s].ip && !walled_garden && !session[s].die)
|
||||||
{
|
{
|
||||||
// RADIUS Stop message
|
// RADIUS Stop message
|
||||||
uint16_t r = sess_local[s].radius;
|
uint16_t r = radiusnew(s);
|
||||||
if (!r)
|
|
||||||
r = radiusnew(s);
|
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
// stop, if not already trying
|
// stop, if not already trying
|
||||||
|
|
@ -1534,7 +1537,7 @@ void sessionshutdown(sessionidt s, char *reason, int result, int error)
|
||||||
free_ip_address(s);
|
free_ip_address(s);
|
||||||
|
|
||||||
// unroute IPv6, if setup
|
// unroute IPv6, if setup
|
||||||
if (session[s].flags & SF_IPV6_ROUTED)
|
if (session[s].ppp.ipv6cp == Opened && session[s].ipv6prefixlen)
|
||||||
route6set(s, session[s].ipv6route, session[s].ipv6prefixlen, 0);
|
route6set(s, session[s].ipv6route, session[s].ipv6prefixlen, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1546,7 +1549,7 @@ void sessionshutdown(sessionidt s, char *reason, int result, int error)
|
||||||
controlt *c = controlnew(14); // sending CDN
|
controlt *c = controlnew(14); // sending CDN
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
char buf[4];
|
uint8_t buf[4];
|
||||||
*(uint16_t *) buf = htons(result);
|
*(uint16_t *) buf = htons(result);
|
||||||
*(uint16_t *) (buf+2) = htons(error);
|
*(uint16_t *) (buf+2) = htons(error);
|
||||||
controlb(c, 1, buf, 4, 1);
|
controlb(c, 1, buf, 4, 1);
|
||||||
|
|
@ -1565,79 +1568,67 @@ void sessionshutdown(sessionidt s, char *reason, int result, int error)
|
||||||
if (session[s].filter_in) ip_filters[session[s].filter_in - 1].used--;
|
if (session[s].filter_in) ip_filters[session[s].filter_in - 1].used--;
|
||||||
if (session[s].filter_out) ip_filters[session[s].filter_out - 1].used--;
|
if (session[s].filter_out) ip_filters[session[s].filter_out - 1].used--;
|
||||||
|
|
||||||
|
// clear PPP state
|
||||||
|
memset(&session[s].ppp, 0, sizeof(session[s].ppp));
|
||||||
|
sess_local[s].lcp.restart = 0;
|
||||||
|
sess_local[s].ipcp.restart = 0;
|
||||||
|
sess_local[s].ipv6cp.restart = 0;
|
||||||
|
sess_local[s].ccp.restart = 0;
|
||||||
|
|
||||||
cluster_send_session(s);
|
cluster_send_session(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendipcp(tunnelidt t, sessionidt s)
|
void sendipcp(tunnelidt t, sessionidt s)
|
||||||
{
|
{
|
||||||
uint8_t buf[MAXCONTROL];
|
uint8_t buf[MAXCONTROL];
|
||||||
uint16_t r = sess_local[s].radius;
|
|
||||||
uint8_t *q;
|
uint8_t *q;
|
||||||
|
|
||||||
CSTAT(sendipcp);
|
CSTAT(sendipcp);
|
||||||
|
|
||||||
if (!r)
|
if (!session[s].unique_id)
|
||||||
r = radiusnew(s);
|
|
||||||
|
|
||||||
if (!r)
|
|
||||||
{
|
{
|
||||||
sessionshutdown(s, "No free RADIUS sessions for IPCP", 3, 0);
|
if (!++last_id) ++last_id; // skip zero
|
||||||
return;
|
session[s].unique_id = last_id;
|
||||||
}
|
|
||||||
|
|
||||||
if (radius[r].state != RADIUSIPCP)
|
|
||||||
{
|
|
||||||
radius[r].state = RADIUSIPCP;
|
|
||||||
radius[r].try = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
radius[r].retry = backoff(radius[r].try++);
|
|
||||||
if (radius[r].try > 10)
|
|
||||||
{
|
|
||||||
radiusclear(r, s); // Clear radius session.
|
|
||||||
sessionshutdown(s, "No reply to IPCP.", 3, 0);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
q = makeppp(buf,sizeof(buf), 0, 0, t, s, PPPIPCP);
|
q = makeppp(buf,sizeof(buf), 0, 0, t, s, PPPIPCP);
|
||||||
if (!q) return;
|
if (!q) return;
|
||||||
|
|
||||||
*q = ConfigReq;
|
*q = ConfigReq;
|
||||||
q[1] = r >> RADIUS_SHIFT; // ID, dont care, we only send one type of request
|
q[1] = session[s].unique_id & 0xf; // ID, dont care, we only send one type of request
|
||||||
*(uint16_t *) (q + 2) = htons(10);
|
*(uint16_t *) (q + 2) = htons(10); // packet length
|
||||||
q[4] = 3;
|
q[4] = 3; // ip address option
|
||||||
q[5] = 6;
|
q[5] = 6; // option length
|
||||||
*(in_addr_t *) (q + 6) = config->peer_address ? config->peer_address :
|
*(in_addr_t *) (q + 6) = config->peer_address ? config->peer_address :
|
||||||
config->bind_address ? config->bind_address :
|
config->bind_address ? config->bind_address :
|
||||||
my_address; // send my IP
|
my_address; // send my IP
|
||||||
|
|
||||||
tunnelsend(buf, 10 + (q - buf), t); // send it
|
tunnelsend(buf, 10 + (q - buf), t); // send it
|
||||||
session[s].flags &= ~SF_IPCP_ACKED; // Clear flag.
|
}
|
||||||
|
|
||||||
// If we have an IPv6 prefix length configured, assume we should
|
void sendipv6cp(tunnelidt t, sessionidt s)
|
||||||
// try to negotiate an IPv6 session as well. Unless we've had a
|
|
||||||
// (N)ACK for IPV6CP.
|
|
||||||
if (config->ipv6_prefix.s6_addr[0] > 0 &&
|
|
||||||
!(session[s].flags & SF_IPV6CP_ACKED) &&
|
|
||||||
!(session[s].flags & SF_IPV6_NACKED))
|
|
||||||
{
|
{
|
||||||
|
uint8_t buf[MAXCONTROL];
|
||||||
|
uint8_t *q;
|
||||||
|
|
||||||
|
CSTAT(sendipv6cp);
|
||||||
|
|
||||||
q = makeppp(buf,sizeof(buf), 0, 0, t, s, PPPIPV6CP);
|
q = makeppp(buf,sizeof(buf), 0, 0, t, s, PPPIPV6CP);
|
||||||
if (!q) return;
|
if (!q) return;
|
||||||
|
|
||||||
*q = ConfigReq;
|
*q = ConfigReq;
|
||||||
q[1] = r >> RADIUS_SHIFT; // ID, don't care, we
|
q[1] = session[s].unique_id & 0xf; // ID, don't care, we
|
||||||
// only send one type
|
// only send one type
|
||||||
// of request
|
// of request
|
||||||
*(uint16_t *) (q + 2) = htons(14);
|
*(uint16_t *) (q + 2) = htons(14);
|
||||||
q[4] = 1;
|
q[4] = 1; // interface identifier option
|
||||||
q[5] = 10;
|
q[5] = 10; // option length
|
||||||
*(uint32_t *) (q + 6) = 0; // We'll be prefix::1
|
*(uint32_t *) (q + 6) = 0; // We'll be prefix::1
|
||||||
*(uint32_t *) (q + 10) = 0;
|
*(uint32_t *) (q + 10) = 0;
|
||||||
q[13] = 1;
|
q[13] = 1;
|
||||||
|
|
||||||
tunnelsend(buf, 14 + (q - buf), t); // send it
|
tunnelsend(buf, 14 + (q - buf), t); // send it
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void sessionclear(sessionidt s)
|
static void sessionclear(sessionidt s)
|
||||||
{
|
{
|
||||||
|
|
@ -1742,7 +1733,7 @@ static void tunnelshutdown(tunnelidt t, char *reason, int result, int error, cha
|
||||||
controlt *c = controlnew(4); // sending StopCCN
|
controlt *c = controlnew(4); // sending StopCCN
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
char buf[64];
|
uint8_t buf[64];
|
||||||
int l = 4;
|
int l = 4;
|
||||||
*(uint16_t *) buf = htons(result);
|
*(uint16_t *) buf = htons(result);
|
||||||
*(uint16_t *) (buf+2) = htons(error);
|
*(uint16_t *) (buf+2) = htons(error);
|
||||||
|
|
@ -1769,7 +1760,7 @@ static void tunnelshutdown(tunnelidt t, char *reason, int result, int error, cha
|
||||||
// read and process packet on tunnel (UDP)
|
// read and process packet on tunnel (UDP)
|
||||||
void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
{
|
{
|
||||||
char *chapresponse = NULL;
|
uint8_t *chapresponse = NULL;
|
||||||
uint16_t l = len, t = 0, s = 0, ns = 0, nr = 0;
|
uint16_t l = len, t = 0, s = 0, ns = 0, nr = 0;
|
||||||
uint8_t *p = buf + 2;
|
uint8_t *p = buf + 2;
|
||||||
|
|
||||||
|
|
@ -2061,7 +2052,7 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
||||||
n = orig_len;
|
n = orig_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(4, s, t, " AVP %d (%s) len %d%s%s\n", mtype, avp_name(mtype), n,
|
LOG(4, s, t, " AVP %d (%s) len %d%s%s\n", mtype, l2tp_avp_name(mtype), n,
|
||||||
flags & 0x40 ? ", hidden" : "", flags & 0x80 ? ", mandatory" : "");
|
flags & 0x40 ? ", hidden" : "", flags & 0x80 ? ", mandatory" : "");
|
||||||
|
|
||||||
switch (mtype)
|
switch (mtype)
|
||||||
|
|
@ -2069,7 +2060,7 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
||||||
case 0: // message type
|
case 0: // message type
|
||||||
message = ntohs(*(uint16_t *) b);
|
message = ntohs(*(uint16_t *) b);
|
||||||
mandatory = flags & 0x80;
|
mandatory = flags & 0x80;
|
||||||
LOG(4, s, t, " Message type = %d (%s)\n", *b, l2tp_message_type(message));
|
LOG(4, s, t, " Message type = %d (%s)\n", *b, l2tp_code(message));
|
||||||
break;
|
break;
|
||||||
case 1: // result code
|
case 1: // result code
|
||||||
{
|
{
|
||||||
|
|
@ -2077,18 +2068,18 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
||||||
const char* resdesc = "(unknown)";
|
const char* resdesc = "(unknown)";
|
||||||
if (message == 4)
|
if (message == 4)
|
||||||
{ /* StopCCN */
|
{ /* StopCCN */
|
||||||
resdesc = stopccn_result_code(rescode);
|
resdesc = l2tp_stopccn_result_code(rescode);
|
||||||
}
|
}
|
||||||
else if (message == 14)
|
else if (message == 14)
|
||||||
{ /* CDN */
|
{ /* CDN */
|
||||||
resdesc = cdn_result_code(rescode);
|
resdesc = l2tp_cdn_result_code(rescode);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(4, s, t, " Result Code %d: %s\n", rescode, resdesc);
|
LOG(4, s, t, " Result Code %d: %s\n", rescode, resdesc);
|
||||||
if (n >= 4)
|
if (n >= 4)
|
||||||
{
|
{
|
||||||
uint16_t errcode = ntohs(*(uint16_t *)(b + 2));
|
uint16_t errcode = ntohs(*(uint16_t *)(b + 2));
|
||||||
LOG(4, s, t, " Error Code %d: %s\n", errcode, error_code(errcode));
|
LOG(4, s, t, " Error Code %d: %s\n", errcode, l2tp_error_code(errcode));
|
||||||
}
|
}
|
||||||
if (n > 4)
|
if (n > 4)
|
||||||
LOG(4, s, t, " Error String: %.*s\n", n-4, b+4);
|
LOG(4, s, t, " Error String: %.*s\n", n-4, b+4);
|
||||||
|
|
@ -2222,7 +2213,7 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
||||||
case 29: // Proxy Authentication Type
|
case 29: // Proxy Authentication Type
|
||||||
{
|
{
|
||||||
uint16_t atype = ntohs(*(uint16_t *)b);
|
uint16_t atype = ntohs(*(uint16_t *)b);
|
||||||
LOG(4, s, t, " Proxy Auth Type %d (%s)\n", atype, auth_type(atype));
|
LOG(4, s, t, " Proxy Auth Type %d (%s)\n", atype, ppp_auth_type(atype));
|
||||||
if (atype == 2)
|
if (atype == 2)
|
||||||
authtype = AUTHCHAP;
|
authtype = AUTHCHAP;
|
||||||
else if (atype == 3)
|
else if (atype == 3)
|
||||||
|
|
@ -2351,7 +2342,7 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
||||||
case 10: // ICRQ
|
case 10: // ICRQ
|
||||||
if (sessionfree && main_quit != QUIT_SHUTDOWN)
|
if (sessionfree && main_quit != QUIT_SHUTDOWN)
|
||||||
{
|
{
|
||||||
uint16_t r;
|
controlt *c = controlnew(11); // ICRP
|
||||||
|
|
||||||
s = sessionfree;
|
s = sessionfree;
|
||||||
sessionfree = session[s].next;
|
sessionfree = session[s].next;
|
||||||
|
|
@ -2360,10 +2351,6 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
||||||
if (s > config->cluster_highest_sessionid)
|
if (s > config->cluster_highest_sessionid)
|
||||||
config->cluster_highest_sessionid = s;
|
config->cluster_highest_sessionid = s;
|
||||||
|
|
||||||
// make a RADIUS session
|
|
||||||
if ((r = radiusnew(s)))
|
|
||||||
{
|
|
||||||
controlt *c = controlnew(11); // sending ICRP
|
|
||||||
session[s].opened = time_now;
|
session[s].opened = time_now;
|
||||||
session[s].tunnel = t;
|
session[s].tunnel = t;
|
||||||
session[s].far = asession;
|
session[s].far = asession;
|
||||||
|
|
@ -2372,29 +2359,26 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
||||||
control16(c, 14, s, 1); // assigned session
|
control16(c, 14, s, 1); // assigned session
|
||||||
controladd(c, t, asession); // send the reply
|
controladd(c, t, asession); // send the reply
|
||||||
|
|
||||||
strncpy(radius[r].calling, calling, sizeof(radius[r].calling) - 1);
|
|
||||||
strncpy(session[s].called, called, sizeof(session[s].called) - 1);
|
strncpy(session[s].called, called, sizeof(session[s].called) - 1);
|
||||||
strncpy(session[s].calling, calling, sizeof(session[s].calling) - 1);
|
strncpy(session[s].calling, calling, sizeof(session[s].calling) - 1);
|
||||||
|
|
||||||
|
session[s].ppp.phase = Establish;
|
||||||
|
session[s].ppp.lcp = Starting;
|
||||||
|
|
||||||
STAT(session_created);
|
STAT(session_created);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
LOG(1, s, t, "No free RADIUS sessions for ICRQ\n");
|
controlt *c = controlnew(14); // CDN
|
||||||
sessionclear(s);
|
if (!sessionfree)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
STAT(session_overflow);
|
STAT(session_overflow);
|
||||||
LOG(1, 0, t, "No free sessions\n");
|
LOG(1, 0, t, "No free sessions\n");
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
controlt *c = controlnew(14); // CDN
|
|
||||||
if (main_quit == QUIT_SHUTDOWN)
|
|
||||||
control16(c, 1, 2, 7); // try another
|
|
||||||
else
|
|
||||||
control16(c, 1, 4, 0); // temporary lack of resources
|
control16(c, 1, 4, 0); // temporary lack of resources
|
||||||
|
}
|
||||||
|
else
|
||||||
|
control16(c, 1, 2, 7); // shutting down, try another
|
||||||
|
|
||||||
controladd(c, t, asession); // send the message
|
controladd(c, t, asession); // send the message
|
||||||
}
|
}
|
||||||
|
|
@ -2408,12 +2392,19 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
||||||
session[s].l2tp_flags = aflags; // set flags received
|
session[s].l2tp_flags = aflags; // set flags received
|
||||||
LOG(3, s, t, "Magic %X Flags %X\n", amagic, aflags);
|
LOG(3, s, t, "Magic %X Flags %X\n", amagic, aflags);
|
||||||
controlnull(t); // ack
|
controlnull(t); // ack
|
||||||
|
|
||||||
// proxy authentication type is not supported
|
// proxy authentication type is not supported
|
||||||
if (!(config->radius_authtypes & authtype))
|
if (!(config->radius_authtypes & authtype))
|
||||||
authtype = config->radius_authprefer;
|
authtype = config->radius_authprefer;
|
||||||
|
|
||||||
// start LCP
|
// start LCP
|
||||||
sendlcp(t, s, authtype);
|
sendlcp(t, s, authtype);
|
||||||
|
sess_local[s].lcp.restart = time_now + config->ppp_restart_time;
|
||||||
|
sess_local[s].lcp.conf_sent = 1;
|
||||||
|
sess_local[s].lcp.nak_sent = 0;
|
||||||
|
sess_local[s].lcp_authtype = authtype;
|
||||||
|
session[s].ppp.lcp = RequestSent;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 14: // CDN
|
case 14: // CDN
|
||||||
controlnull(t); // ack
|
controlnull(t); // ack
|
||||||
|
|
@ -2506,18 +2497,11 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
||||||
processipcp(t, s, p, l);
|
processipcp(t, s, p, l);
|
||||||
}
|
}
|
||||||
else if (prot == PPPIPV6CP)
|
else if (prot == PPPIPV6CP)
|
||||||
{
|
|
||||||
if (config->ipv6_prefix.s6_addr[0] > 0)
|
|
||||||
{
|
{
|
||||||
session[s].last_packet = time_now;
|
session[s].last_packet = time_now;
|
||||||
if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port); return; }
|
if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port); return; }
|
||||||
processipv6cp(t, s, p, l);
|
processipv6cp(t, s, p, l);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG(1, s, t, "IPv6 not configured; ignoring IPv6CP\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (prot == PPPCCP)
|
else if (prot == PPPCCP)
|
||||||
{
|
{
|
||||||
session[s].last_packet = time_now;
|
session[s].last_packet = time_now;
|
||||||
|
|
@ -2543,7 +2527,7 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
||||||
}
|
}
|
||||||
else if (prot == PPPIPV6)
|
else if (prot == PPPIPV6)
|
||||||
{
|
{
|
||||||
if (!config->ipv6_prefix.s6_addr[0] > 0)
|
if (!config->ipv6_prefix.s6_addr[0])
|
||||||
{
|
{
|
||||||
LOG(1, s, t, "IPv6 not configured; yet received IPv6 packet. Ignoring.\n");
|
LOG(1, s, t, "IPv6 not configured; yet received IPv6 packet. Ignoring.\n");
|
||||||
return;
|
return;
|
||||||
|
|
@ -2592,7 +2576,7 @@ static void processtun(uint8_t * buf, int len)
|
||||||
if (*(uint16_t *) (buf + 2) == htons(PKTIP)) // IPv4
|
if (*(uint16_t *) (buf + 2) == htons(PKTIP)) // IPv4
|
||||||
processipout(buf, len);
|
processipout(buf, len);
|
||||||
else if (*(uint16_t *) (buf + 2) == htons(PKTIPV6) // IPV6
|
else if (*(uint16_t *) (buf + 2) == htons(PKTIPV6) // IPV6
|
||||||
&& config->ipv6_prefix.s6_addr[0] > 0)
|
&& config->ipv6_prefix.s6_addr[0])
|
||||||
processipv6out(buf, len);
|
processipv6out(buf, len);
|
||||||
|
|
||||||
// Else discard.
|
// Else discard.
|
||||||
|
|
@ -2734,15 +2718,125 @@ static void regular_cleanups(double period)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session[s].ip && !(session[s].flags & SF_IPCP_ACKED)
|
// PPP timeouts
|
||||||
&& !(sess_local[s].radius && radius[sess_local[s].radius].state == RADIUSIPCP))
|
if (sess_local[s].lcp.restart >= time_now)
|
||||||
{
|
{
|
||||||
// IPCP has not completed yet. Resend
|
int next_state = session[s].ppp.lcp;
|
||||||
LOG(3, s, session[s].tunnel, "No ACK for initial IPCP ConfigReq... resending\n");
|
switch (session[s].ppp.lcp)
|
||||||
sendipcp(session[s].tunnel, s);
|
{
|
||||||
|
case RequestSent:
|
||||||
|
case AckReceived:
|
||||||
|
next_state = RequestSent;
|
||||||
|
|
||||||
|
case AckSent:
|
||||||
|
if (sess_local[s].lcp.conf_sent < config->ppp_max_configure)
|
||||||
|
{
|
||||||
|
LOG(3, s, session[s].tunnel, "No ACK for LCP ConfigReq... resending\n");
|
||||||
|
sess_local[s].lcp.restart = time_now + config->ppp_restart_time;
|
||||||
|
sess_local[s].lcp.conf_sent++;
|
||||||
|
sendlcp(t, s, sess_local[s].lcp_authtype);
|
||||||
|
change_state(s, lcp, next_state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sessionshutdown(s, "No response to LCP ConfigReq.", 3, 0);
|
||||||
|
STAT(session_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
s_actions++;
|
s_actions++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (session[s].die)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sess_local[s].ipcp.restart >= time_now)
|
||||||
|
{
|
||||||
|
int next_state = session[s].ppp.ipcp;
|
||||||
|
switch (session[s].ppp.ipcp)
|
||||||
|
{
|
||||||
|
case RequestSent:
|
||||||
|
case AckReceived:
|
||||||
|
next_state = RequestSent;
|
||||||
|
|
||||||
|
case AckSent:
|
||||||
|
if (sess_local[s].ipcp.conf_sent < config->ppp_max_configure)
|
||||||
|
{
|
||||||
|
LOG(3, s, session[s].tunnel, "No ACK for IPCP ConfigReq... resending\n");
|
||||||
|
sess_local[s].ipcp.restart = time_now + config->ppp_restart_time;
|
||||||
|
sess_local[s].ipcp.conf_sent++;
|
||||||
|
sendipcp(t, s);
|
||||||
|
change_state(s, ipcp, next_state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sessionshutdown(s, "No response to IPCP ConfigReq.", 3, 0);
|
||||||
|
STAT(session_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
s_actions++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session[s].die)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sess_local[s].ipv6cp.restart >= time_now)
|
||||||
|
{
|
||||||
|
int next_state = session[s].ppp.ipv6cp;
|
||||||
|
switch (session[s].ppp.ipv6cp)
|
||||||
|
{
|
||||||
|
case RequestSent:
|
||||||
|
case AckReceived:
|
||||||
|
next_state = RequestSent;
|
||||||
|
|
||||||
|
case AckSent:
|
||||||
|
if (sess_local[s].ipv6cp.conf_sent < config->ppp_max_configure)
|
||||||
|
{
|
||||||
|
LOG(3, s, session[s].tunnel, "No ACK for IPV6CP ConfigReq... resending\n");
|
||||||
|
sess_local[s].ipv6cp.restart = time_now + config->ppp_restart_time;
|
||||||
|
sess_local[s].ipv6cp.conf_sent++;
|
||||||
|
sendipv6cp(t, s);
|
||||||
|
change_state(s, ipv6cp, next_state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG(3, s, session[s].tunnel, "No ACK for IPV6CP ConfigReq\n");
|
||||||
|
change_state(s, ipv6cp, Stopped);
|
||||||
|
}
|
||||||
|
|
||||||
|
s_actions++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sess_local[s].ccp.restart >= time_now)
|
||||||
|
{
|
||||||
|
int next_state = session[s].ppp.ccp;
|
||||||
|
switch (session[s].ppp.ccp)
|
||||||
|
{
|
||||||
|
case RequestSent:
|
||||||
|
case AckReceived:
|
||||||
|
next_state = RequestSent;
|
||||||
|
|
||||||
|
case AckSent:
|
||||||
|
if (sess_local[s].ccp.conf_sent < config->ppp_max_configure)
|
||||||
|
{
|
||||||
|
LOG(3, s, session[s].tunnel, "No ACK for CCP ConfigReq... resending\n");
|
||||||
|
sess_local[s].ccp.restart = time_now + config->ppp_restart_time;
|
||||||
|
sess_local[s].ccp.conf_sent++;
|
||||||
|
sendccp(t, s);
|
||||||
|
change_state(s, ccp, next_state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG(3, s, session[s].tunnel, "No ACK for CCP ConfigReq\n");
|
||||||
|
change_state(s, ccp, Stopped);
|
||||||
|
}
|
||||||
|
|
||||||
|
s_actions++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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))
|
||||||
{
|
{
|
||||||
|
|
@ -2753,7 +2847,7 @@ static void regular_cleanups(double period)
|
||||||
}
|
}
|
||||||
|
|
||||||
// No data in ECHO_TIMEOUT seconds, send LCP ECHO
|
// No data in ECHO_TIMEOUT seconds, send LCP ECHO
|
||||||
if (session[s].user[0] && (time_now - session[s].last_packet >= ECHO_TIMEOUT))
|
if (session[s].ppp.phase >= Establish && (time_now - session[s].last_packet >= ECHO_TIMEOUT))
|
||||||
{
|
{
|
||||||
uint8_t b[MAXCONTROL] = {0};
|
uint8_t b[MAXCONTROL] = {0};
|
||||||
|
|
||||||
|
|
@ -3084,7 +3178,8 @@ static void mainloop(void)
|
||||||
if (n)
|
if (n)
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
int alen, c, s;
|
socklen_t alen;
|
||||||
|
int c, s;
|
||||||
int udp_ready = 0;
|
int udp_ready = 0;
|
||||||
int tun_ready = 0;
|
int tun_ready = 0;
|
||||||
int cluster_ready = 0;
|
int cluster_ready = 0;
|
||||||
|
|
@ -3391,6 +3486,9 @@ static void initdata(int optdebug, char *optconfig)
|
||||||
config->num_tbfs = MAXTBFS;
|
config->num_tbfs = MAXTBFS;
|
||||||
config->rl_rate = 28; // 28kbps
|
config->rl_rate = 28; // 28kbps
|
||||||
config->cluster_master_min_adv = 1;
|
config->cluster_master_min_adv = 1;
|
||||||
|
config->ppp_restart_time = 3;
|
||||||
|
config->ppp_max_configure = 10;
|
||||||
|
config->ppp_max_failure = 5;
|
||||||
strcpy(config->random_device, RANDOMDEVICE);
|
strcpy(config->random_device, RANDOMDEVICE);
|
||||||
|
|
||||||
log_stream = stderr;
|
log_stream = stderr;
|
||||||
|
|
@ -3758,7 +3856,7 @@ static void initippool()
|
||||||
LOG(1, 0, 0, "IP address pool is %d addresses\n", ip_pool_size - 1);
|
LOG(1, 0, 0, "IP address pool is %d addresses\n", ip_pool_size - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void snoop_send_packet(char *packet, uint16_t size, in_addr_t destination, uint16_t port)
|
void snoop_send_packet(uint8_t *packet, uint16_t size, in_addr_t destination, uint16_t port)
|
||||||
{
|
{
|
||||||
struct sockaddr_in snoop_addr = {0};
|
struct sockaddr_in snoop_addr = {0};
|
||||||
if (!destination || !port || snoopfd <= 0 || size <= 0 || !packet)
|
if (!destination || !port || snoopfd <= 0 || size <= 0 || !packet)
|
||||||
|
|
@ -4055,7 +4153,7 @@ static void sigchild_handler(int sig)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void build_chap_response(char *challenge, uint8_t id, uint16_t challenge_length, char **challenge_response)
|
static void build_chap_response(uint8_t *challenge, uint8_t id, uint16_t challenge_length, uint8_t **challenge_response)
|
||||||
{
|
{
|
||||||
MD5_CTX ctx;
|
MD5_CTX ctx;
|
||||||
*challenge_response = NULL;
|
*challenge_response = NULL;
|
||||||
|
|
@ -4068,13 +4166,13 @@ static void build_chap_response(char *challenge, uint8_t id, uint16_t challenge_
|
||||||
|
|
||||||
LOG(4, 0, 0, " Building challenge response for CHAP request\n");
|
LOG(4, 0, 0, " Building challenge response for CHAP request\n");
|
||||||
|
|
||||||
*challenge_response = (char *)calloc(17, 1);
|
*challenge_response = calloc(17, 1);
|
||||||
|
|
||||||
MD5Init(&ctx);
|
MD5_Init(&ctx);
|
||||||
MD5Update(&ctx, &id, 1);
|
MD5_Update(&ctx, &id, 1);
|
||||||
MD5Update(&ctx, config->l2tpsecret, strlen(config->l2tpsecret));
|
MD5_Update(&ctx, config->l2tpsecret, strlen(config->l2tpsecret));
|
||||||
MD5Update(&ctx, challenge, challenge_length);
|
MD5_Update(&ctx, challenge, challenge_length);
|
||||||
MD5Final(*challenge_response, &ctx);
|
MD5_Final(*challenge_response, &ctx);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -4384,13 +4482,8 @@ int sessionsetup(tunnelidt t, sessionidt s)
|
||||||
cache_ipmap(session[s].ip, s);
|
cache_ipmap(session[s].ip, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!session[s].unique_id)
|
sess_local[s].lcp_authtype = 0; // RADIUS authentication complete
|
||||||
{
|
lcp_open(t, s); // transition to Network phase and send initial IPCP
|
||||||
// did this session just finish radius?
|
|
||||||
LOG(3, s, t, "Sending initial IPCP to client\n");
|
|
||||||
sendipcp(t, s);
|
|
||||||
session[s].unique_id = ++last_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the plugin's against this new session.
|
// Run the plugin's against this new session.
|
||||||
{
|
{
|
||||||
|
|
@ -4499,7 +4592,7 @@ int load_session(sessionidt s, sessiont *new)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check v6 routing
|
// check v6 routing
|
||||||
if (new->flags & SF_IPV6_ROUTED && !(session[s].flags & SF_IPV6_ROUTED))
|
if (new->ipv6prefixlen && new->ppp.ipv6cp == Opened && session[s].ppp.ipv6cp != Opened)
|
||||||
route6set(s, new->ipv6route, new->ipv6prefixlen, 1);
|
route6set(s, new->ipv6route, new->ipv6prefixlen, 1);
|
||||||
|
|
||||||
// check filters
|
// check filters
|
||||||
|
|
@ -5040,11 +5133,11 @@ static void unhide_value(uint8_t *value, size_t len, uint16_t type, uint8_t *vec
|
||||||
uint16_t m = htons(type);
|
uint16_t m = htons(type);
|
||||||
|
|
||||||
// Compute initial pad
|
// Compute initial pad
|
||||||
MD5Init(&ctx);
|
MD5_Init(&ctx);
|
||||||
MD5Update(&ctx, (unsigned char *) &m, 2);
|
MD5_Update(&ctx, (unsigned char *) &m, 2);
|
||||||
MD5Update(&ctx, config->l2tpsecret, strlen(config->l2tpsecret));
|
MD5_Update(&ctx, config->l2tpsecret, strlen(config->l2tpsecret));
|
||||||
MD5Update(&ctx, vector, vec_len);
|
MD5_Update(&ctx, vector, vec_len);
|
||||||
MD5Final(digest, &ctx);
|
MD5_Final(digest, &ctx);
|
||||||
|
|
||||||
// pointer to last decoded 16 octets
|
// pointer to last decoded 16 octets
|
||||||
last = value;
|
last = value;
|
||||||
|
|
@ -5054,10 +5147,10 @@ static void unhide_value(uint8_t *value, size_t len, uint16_t type, uint8_t *vec
|
||||||
// calculate a new pad based on the last decoded block
|
// calculate a new pad based on the last decoded block
|
||||||
if (d >= sizeof(digest))
|
if (d >= sizeof(digest))
|
||||||
{
|
{
|
||||||
MD5Init(&ctx);
|
MD5_Init(&ctx);
|
||||||
MD5Update(&ctx, config->l2tpsecret, strlen(config->l2tpsecret));
|
MD5_Update(&ctx, config->l2tpsecret, strlen(config->l2tpsecret));
|
||||||
MD5Update(&ctx, last, sizeof(digest));
|
MD5_Update(&ctx, last, sizeof(digest));
|
||||||
MD5Final(digest, &ctx);
|
MD5_Final(digest, &ctx);
|
||||||
|
|
||||||
d = 0;
|
d = 0;
|
||||||
last = value;
|
last = value;
|
||||||
|
|
|
||||||
96
l2tpns.h
96
l2tpns.h
|
|
@ -1,5 +1,5 @@
|
||||||
// L2TPNS Global Stuff
|
// L2TPNS Global Stuff
|
||||||
// $Id: l2tpns.h,v 1.80 2005/06/28 14:48:27 bodea Exp $
|
// $Id: l2tpns.h,v 1.81 2005/07/31 10:04:10 bodea Exp $
|
||||||
|
|
||||||
#ifndef __L2TPNS_H__
|
#ifndef __L2TPNS_H__
|
||||||
#define __L2TPNS_H__
|
#define __L2TPNS_H__
|
||||||
|
|
@ -121,6 +121,52 @@ enum {
|
||||||
CoANAK
|
CoANAK
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// PPP phases
|
||||||
|
enum {
|
||||||
|
Dead,
|
||||||
|
Establish,
|
||||||
|
Authenticate,
|
||||||
|
Network,
|
||||||
|
Terminate
|
||||||
|
};
|
||||||
|
|
||||||
|
// PPP states
|
||||||
|
enum {
|
||||||
|
Initial,
|
||||||
|
Starting,
|
||||||
|
Closed,
|
||||||
|
Stopped,
|
||||||
|
Closing,
|
||||||
|
Stopping,
|
||||||
|
RequestSent,
|
||||||
|
AckReceived,
|
||||||
|
AckSent,
|
||||||
|
Opened
|
||||||
|
};
|
||||||
|
|
||||||
|
// reset state machine counters
|
||||||
|
#define initialise_restart_count(_s, _fsm) \
|
||||||
|
sess_local[_s]._fsm.conf_sent = sess_local[_s]._fsm.nak_sent
|
||||||
|
|
||||||
|
// stop timer on change to state where timer does not run
|
||||||
|
#define change_state(_s, _fsm, _new) ({ \
|
||||||
|
if (_new != session[_s].ppp._fsm) \
|
||||||
|
{ \
|
||||||
|
switch (_new) \
|
||||||
|
{ \
|
||||||
|
case Initial: \
|
||||||
|
case Starting: \
|
||||||
|
case Closed: \
|
||||||
|
case Stopped: \
|
||||||
|
case Opened: \
|
||||||
|
sess_local[_s]._fsm.restart = 0; \
|
||||||
|
initialise_restart_count(_s, _fsm); \
|
||||||
|
} \
|
||||||
|
session[_s].ppp._fsm = _new; \
|
||||||
|
cluster_send_session(_s); \
|
||||||
|
} \
|
||||||
|
})
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
typedef uint16_t sessionidt;
|
typedef uint16_t sessionidt;
|
||||||
typedef uint16_t tunnelidt;
|
typedef uint16_t tunnelidt;
|
||||||
|
|
@ -174,7 +220,14 @@ typedef struct
|
||||||
sessionidt far; // far end session ID
|
sessionidt far; // far end session ID
|
||||||
tunnelidt tunnel; // near end tunnel ID
|
tunnelidt tunnel; // near end tunnel ID
|
||||||
uint8_t l2tp_flags; // various bit flags from the ICCN on the l2tp tunnel.
|
uint8_t l2tp_flags; // various bit flags from the ICCN on the l2tp tunnel.
|
||||||
uint8_t flags; // Various session flags.
|
struct {
|
||||||
|
uint8_t phase; // PPP phase
|
||||||
|
uint8_t lcp:4; // LCP state
|
||||||
|
uint8_t ipcp:4; // IPCP state
|
||||||
|
uint8_t ipv6cp:4; // IPV6CP state
|
||||||
|
uint8_t ccp:4; // CCP state
|
||||||
|
uint8_t pad; // unused
|
||||||
|
} ppp;
|
||||||
in_addr_t ip; // IP of session set by RADIUS response (host byte order).
|
in_addr_t ip; // IP of session set by RADIUS response (host byte order).
|
||||||
int ip_pool_index; // index to IP pool
|
int ip_pool_index; // index to IP pool
|
||||||
uint32_t unique_id; // unique session id
|
uint32_t unique_id; // unique session id
|
||||||
|
|
@ -198,7 +251,7 @@ typedef struct
|
||||||
uint16_t tbf_in; // filter bucket for throttling in from the user.
|
uint16_t tbf_in; // filter bucket for throttling in from the user.
|
||||||
uint16_t tbf_out; // filter bucket for throttling out to the user.
|
uint16_t tbf_out; // filter bucket for throttling out to the user.
|
||||||
int random_vector_length;
|
int random_vector_length;
|
||||||
char random_vector[MAXTEL];
|
uint8_t random_vector[MAXTEL];
|
||||||
char user[MAXUSER]; // user (needed in seesion for radius stop messages)
|
char user[MAXUSER]; // user (needed in seesion for radius stop messages)
|
||||||
char called[MAXTEL]; // called number
|
char called[MAXTEL]; // called number
|
||||||
char calling[MAXTEL]; // calling number
|
char calling[MAXTEL]; // calling number
|
||||||
|
|
@ -209,17 +262,10 @@ typedef struct
|
||||||
uint8_t walled_garden; // is this session gardened?
|
uint8_t walled_garden; // is this session gardened?
|
||||||
uint8_t ipv6prefixlen; // IPv6 route prefix length
|
uint8_t ipv6prefixlen; // IPv6 route prefix length
|
||||||
struct in6_addr ipv6route; // Static IPv6 route
|
struct in6_addr ipv6route; // Static IPv6 route
|
||||||
char reserved[16]; // Space to expand structure without changing HB_VERSION
|
char reserved[11]; // Space to expand structure without changing HB_VERSION
|
||||||
}
|
}
|
||||||
sessiont;
|
sessiont;
|
||||||
|
|
||||||
#define SF_IPCP_ACKED 1 // Has this session seen an IPCP Ack?
|
|
||||||
#define SF_LCP_ACKED 2 // LCP negotiated
|
|
||||||
#define SF_CCP_ACKED 4 // CCP negotiated
|
|
||||||
#define SF_IPV6CP_ACKED 8 // IPv6 negotiated
|
|
||||||
#define SF_IPV6_NACKED 16 // IPv6 rejected
|
|
||||||
#define SF_IPV6_ROUTED 32 // advertised v6 route
|
|
||||||
|
|
||||||
#define AUTHPAP 1 // allow PAP
|
#define AUTHPAP 1 // allow PAP
|
||||||
#define AUTHCHAP 2 // allow CHAP
|
#define AUTHCHAP 2 // allow CHAP
|
||||||
|
|
||||||
|
|
@ -233,6 +279,16 @@ typedef struct
|
||||||
uint32_t cin;
|
uint32_t cin;
|
||||||
uint32_t cout;
|
uint32_t cout;
|
||||||
|
|
||||||
|
// PPP restart timer/counters
|
||||||
|
struct {
|
||||||
|
time_t restart;
|
||||||
|
int conf_sent;
|
||||||
|
int nak_sent;
|
||||||
|
} lcp, ipcp, ipv6cp, ccp;
|
||||||
|
|
||||||
|
// authentication to use
|
||||||
|
int lcp_authtype;
|
||||||
|
|
||||||
// DoS prevention
|
// DoS prevention
|
||||||
clockt last_packet_out;
|
clockt last_packet_out;
|
||||||
uint32_t packets_out;
|
uint32_t packets_out;
|
||||||
|
|
@ -271,13 +327,12 @@ typedef struct
|
||||||
}
|
}
|
||||||
tunnelt;
|
tunnelt;
|
||||||
|
|
||||||
// 180 bytes per radius session
|
// 160 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
|
||||||
hasht auth; // request authenticator
|
hasht auth; // request authenticator
|
||||||
clockt retry; // when to try next
|
clockt retry; // when to try next
|
||||||
char calling[MAXTEL]; // calling number
|
|
||||||
char pass[129]; // password
|
char pass[129]; // password
|
||||||
uint8_t id; // ID for PPP response
|
uint8_t id; // ID for PPP response
|
||||||
uint8_t try; // which try we are on
|
uint8_t try; // which try we are on
|
||||||
|
|
@ -328,7 +383,6 @@ enum
|
||||||
RADIUSNULL, // Not in use
|
RADIUSNULL, // Not in use
|
||||||
RADIUSCHAP, // sending CHAP down PPP
|
RADIUSCHAP, // sending CHAP down PPP
|
||||||
RADIUSAUTH, // sending auth to RADIUS server
|
RADIUSAUTH, // sending auth to RADIUS server
|
||||||
RADIUSIPCP, // sending IPCP to end user
|
|
||||||
RADIUSSTART, // sending start accounting to RADIUS server
|
RADIUSSTART, // sending start accounting to RADIUS server
|
||||||
RADIUSSTOP, // sending stop accounting to RADIUS server
|
RADIUSSTOP, // sending stop accounting to RADIUS server
|
||||||
RADIUSINTERIM, // sending interim accounting to RADIUS server
|
RADIUSINTERIM, // sending interim accounting to RADIUS server
|
||||||
|
|
@ -391,6 +445,7 @@ struct Tstats
|
||||||
uint32_t call_sessionbyuser;
|
uint32_t call_sessionbyuser;
|
||||||
uint32_t call_sendarp;
|
uint32_t call_sendarp;
|
||||||
uint32_t call_sendipcp;
|
uint32_t call_sendipcp;
|
||||||
|
uint32_t call_sendipv6cp;
|
||||||
uint32_t call_processipv6cp;
|
uint32_t call_processipv6cp;
|
||||||
uint32_t call_tunnelsend;
|
uint32_t call_tunnelsend;
|
||||||
uint32_t call_sessionkill;
|
uint32_t call_sessionkill;
|
||||||
|
|
@ -457,6 +512,10 @@ typedef struct
|
||||||
|
|
||||||
char random_device[256]; // random device path, defaults to RANDOMDEVICE
|
char random_device[256]; // random device path, defaults to RANDOMDEVICE
|
||||||
|
|
||||||
|
int ppp_restart_time; // timeout for PPP restart
|
||||||
|
int ppp_max_configure; // max lcp configure requests to send
|
||||||
|
int ppp_max_failure; // max lcp configure naks to send
|
||||||
|
|
||||||
char radiussecret[64];
|
char radiussecret[64];
|
||||||
int radius_accounting;
|
int radius_accounting;
|
||||||
int radius_interim;
|
int radius_interim;
|
||||||
|
|
@ -601,6 +660,7 @@ void sendarp(int ifr_idx, const unsigned char* mac, in_addr_t ip);
|
||||||
// ppp.c
|
// ppp.c
|
||||||
void processpap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l);
|
void processpap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l);
|
||||||
void processchap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l);
|
void processchap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l);
|
||||||
|
void lcp_open(tunnelidt t, sessionidt s);
|
||||||
void processlcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l);
|
void processlcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l);
|
||||||
void processipcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l);
|
void processipcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l);
|
||||||
void processipv6cp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l);
|
void processipv6cp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l);
|
||||||
|
|
@ -611,6 +671,7 @@ void sendchap(tunnelidt t, sessionidt s);
|
||||||
uint8_t *makeppp(uint8_t *b, int size, uint8_t *p, int l, tunnelidt t, sessionidt s, uint16_t mtype);
|
uint8_t *makeppp(uint8_t *b, int size, uint8_t *p, int l, tunnelidt t, sessionidt s, uint16_t mtype);
|
||||||
void sendlcp(tunnelidt t, sessionidt s, int authtype);
|
void sendlcp(tunnelidt t, sessionidt s, int authtype);
|
||||||
void send_ipin(sessionidt s, uint8_t *buf, int len);
|
void send_ipin(sessionidt s, uint8_t *buf, int len);
|
||||||
|
void sendccp(tunnelidt t, sessionidt s);
|
||||||
|
|
||||||
|
|
||||||
// radius.c
|
// radius.c
|
||||||
|
|
@ -638,8 +699,9 @@ 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 sendipv6cp(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(uint8_t *packet, uint16_t size, in_addr_t destination, uint16_t port);
|
||||||
int find_filter(char const *name, size_t len);
|
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);
|
||||||
|
|
@ -652,7 +714,7 @@ int cmd_show_hist_open(struct cli_def *cli, char *command, char **argv, int argc
|
||||||
#define LOG_HEX(D, t, d, s) ({ if (D <= config->debug) _log_hex(D, t, d, s); })
|
#define LOG_HEX(D, t, d, s) ({ if (D <= config->debug) _log_hex(D, t, d, s); })
|
||||||
|
|
||||||
void _log(int level, sessionidt s, tunnelidt t, const char *format, ...) __attribute__((format (printf, 4, 5)));
|
void _log(int level, sessionidt s, tunnelidt t, const char *format, ...) __attribute__((format (printf, 4, 5)));
|
||||||
void _log_hex(int level, const char *title, const char *data, int maxsize);
|
void _log_hex(int level, const char *title, const uint8_t *data, int maxsize);
|
||||||
|
|
||||||
int sessionsetup(tunnelidt t, sessionidt s);
|
int sessionsetup(tunnelidt t, sessionidt s);
|
||||||
int run_plugins(int plugin_type, void *data);
|
int run_plugins(int plugin_type, void *data);
|
||||||
|
|
@ -670,7 +732,7 @@ int cli_arg_help(struct cli_def *cli, int cr_ok, char *entry, ...);
|
||||||
|
|
||||||
|
|
||||||
// icmp.c
|
// icmp.c
|
||||||
void host_unreachable(in_addr_t destination, uint16_t id, in_addr_t source, char *packet, int packet_len);
|
void host_unreachable(in_addr_t destination, uint16_t id, in_addr_t source, uint8_t *packet, int packet_len);
|
||||||
|
|
||||||
|
|
||||||
extern tunnelt *tunnel;
|
extern tunnelt *tunnel;
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ Source: http://optusnet.dl.sourceforge.net/sourceforge/l2tpns/l2tpns-%{version}.
|
||||||
URL: http://sourceforge.net/projects/l2tpns
|
URL: http://sourceforge.net/projects/l2tpns
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
||||||
Prereq: /sbin/chkconfig
|
Prereq: /sbin/chkconfig
|
||||||
BuildRequires: libcli >= 1.8.5
|
BuildRequires: libcli >= 1.8.5, openssl-devel
|
||||||
Requires: libcli >= 1.8.5
|
Requires: libcli >= 1.8.5, openssl
|
||||||
|
|
||||||
%description
|
%description
|
||||||
l2tpns is a layer 2 tunneling protocol network server (LNS). It
|
l2tpns is a layer 2 tunneling protocol network server (LNS). It
|
||||||
|
|
@ -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 Jun 29 2005 Brendan O'Dea <bod@c47.org> 2.1.2-1
|
* Sun Jul 31 2005 Brendan O'Dea <bod@> 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
|
||||||
|
|
|
||||||
296
md5.c
296
md5.c
|
|
@ -1,296 +0,0 @@
|
||||||
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
|
|
||||||
*/
|
|
||||||
|
|
||||||
char const *cvs_id_md5 = "$Id: md5.c,v 1.3 2004/08/13 00:02:50 fred_nerk Exp $";
|
|
||||||
|
|
||||||
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
|
||||||
rights reserved.
|
|
||||||
|
|
||||||
License to copy and use this software is granted provided that it
|
|
||||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
|
||||||
Algorithm" in all material mentioning or referencing this software
|
|
||||||
or this function.
|
|
||||||
|
|
||||||
License is also granted to make and use derivative works provided
|
|
||||||
that such works are identified as "derived from the RSA Data
|
|
||||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
|
||||||
mentioning or referencing the derived work.
|
|
||||||
|
|
||||||
RSA Data Security, Inc. makes no representations concerning either
|
|
||||||
the merchantability of this software or the suitability of this
|
|
||||||
software for any particular purpose. It is provided "as is"
|
|
||||||
without express or implied warranty of any kind.
|
|
||||||
|
|
||||||
These notices must be retained in any copies of any part of this
|
|
||||||
documentation and/or software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "md5.h"
|
|
||||||
|
|
||||||
/* Constants for MD5Transform routine.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define S11 7
|
|
||||||
#define S12 12
|
|
||||||
#define S13 17
|
|
||||||
#define S14 22
|
|
||||||
#define S21 5
|
|
||||||
#define S22 9
|
|
||||||
#define S23 14
|
|
||||||
#define S24 20
|
|
||||||
#define S31 4
|
|
||||||
#define S32 11
|
|
||||||
#define S33 16
|
|
||||||
#define S34 23
|
|
||||||
#define S41 6
|
|
||||||
#define S42 10
|
|
||||||
#define S43 15
|
|
||||||
#define S44 21
|
|
||||||
|
|
||||||
static void MD5Transform PROTO_LIST((UINT4[4], unsigned char[64]));
|
|
||||||
static void Encode PROTO_LIST((unsigned char *, UINT4 *, unsigned int));
|
|
||||||
static void Decode PROTO_LIST((UINT4 *, unsigned char *, unsigned int));
|
|
||||||
|
|
||||||
static unsigned char PADDING[64] = {
|
|
||||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/* F, G, H and I are basic MD5 functions.
|
|
||||||
*/
|
|
||||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
|
||||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
|
||||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
|
||||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
|
||||||
|
|
||||||
/* ROTATE_LEFT rotates x left n bits.
|
|
||||||
*/
|
|
||||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
|
||||||
|
|
||||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
|
||||||
Rotation is separate from addition to prevent recomputation.
|
|
||||||
*/
|
|
||||||
#define FF(a, b, c, d, x, s, ac) { \
|
|
||||||
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
|
||||||
(a) = ROTATE_LEFT ((a), (s)); \
|
|
||||||
(a) += (b); \
|
|
||||||
}
|
|
||||||
#define GG(a, b, c, d, x, s, ac) { \
|
|
||||||
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
|
||||||
(a) = ROTATE_LEFT ((a), (s)); \
|
|
||||||
(a) += (b); \
|
|
||||||
}
|
|
||||||
#define HH(a, b, c, d, x, s, ac) { \
|
|
||||||
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
|
||||||
(a) = ROTATE_LEFT ((a), (s)); \
|
|
||||||
(a) += (b); \
|
|
||||||
}
|
|
||||||
#define II(a, b, c, d, x, s, ac) { \
|
|
||||||
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
|
||||||
(a) = ROTATE_LEFT ((a), (s)); \
|
|
||||||
(a) += (b); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MD5 initialization. Begins an MD5 operation, writing a new context.
|
|
||||||
*/
|
|
||||||
void MD5Init(MD5_CTX *context)
|
|
||||||
{
|
|
||||||
context->count[0] = context->count[1] = 0;
|
|
||||||
// Load magic initialization constants.
|
|
||||||
context->state[0] = 0x67452301;
|
|
||||||
context->state[1] = 0xefcdab89;
|
|
||||||
context->state[2] = 0x98badcfe;
|
|
||||||
context->state[3] = 0x10325476;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MD5 block update operation. Continues an MD5 message-digest
|
|
||||||
operation, processing another message block, and updating the
|
|
||||||
context.
|
|
||||||
*/
|
|
||||||
void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputLen)
|
|
||||||
|
|
||||||
{
|
|
||||||
unsigned int i,
|
|
||||||
index,
|
|
||||||
partLen;
|
|
||||||
|
|
||||||
/* Compute number of bytes mod 64 */
|
|
||||||
index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
|
|
||||||
|
|
||||||
/* Update number of bits */
|
|
||||||
if ((context->count[0] += ((UINT4) inputLen << 3)) < ((UINT4) inputLen << 3))
|
|
||||||
context->count[1]++;
|
|
||||||
context->count[1] += ((UINT4) inputLen >> 29);
|
|
||||||
|
|
||||||
partLen = 64 - index;
|
|
||||||
|
|
||||||
/* Transform as many times as possible.
|
|
||||||
*/
|
|
||||||
if (inputLen >= partLen)
|
|
||||||
{
|
|
||||||
memcpy(&context->buffer[index], input, partLen);
|
|
||||||
MD5Transform(context->state, context->buffer);
|
|
||||||
|
|
||||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
|
||||||
MD5Transform(context->state, &input[i]);
|
|
||||||
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
/* Buffer remaining input */
|
|
||||||
memcpy(&context->buffer[index], &input[i], inputLen - i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
|
|
||||||
the message digest and zeroizing the context.
|
|
||||||
*/
|
|
||||||
void MD5Final(unsigned char digest[16], MD5_CTX *context)
|
|
||||||
{
|
|
||||||
unsigned char bits[8];
|
|
||||||
unsigned int index, padLen;
|
|
||||||
|
|
||||||
/* Save number of bits */
|
|
||||||
Encode(bits, context->count, 8);
|
|
||||||
|
|
||||||
/* Pad out to 56 mod 64.
|
|
||||||
*/
|
|
||||||
index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
|
|
||||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
|
||||||
MD5Update(context, PADDING, padLen);
|
|
||||||
|
|
||||||
/* Append length (before padding) */
|
|
||||||
MD5Update(context, bits, 8);
|
|
||||||
|
|
||||||
/* Store state in digest */
|
|
||||||
Encode(digest, context->state, 16);
|
|
||||||
|
|
||||||
/* Zeroize sensitive information.
|
|
||||||
*/
|
|
||||||
memset(context, 0, sizeof(*context));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MD5 basic transformation. Transforms state based on block.
|
|
||||||
*/
|
|
||||||
static void MD5Transform(UINT4 state[4], unsigned char block[64])
|
|
||||||
{
|
|
||||||
UINT4 a = state[0],
|
|
||||||
b = state[1],
|
|
||||||
c = state[2],
|
|
||||||
d = state[3],
|
|
||||||
x[16];
|
|
||||||
|
|
||||||
Decode(x, block, 64);
|
|
||||||
|
|
||||||
/* Round 1 */
|
|
||||||
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
|
|
||||||
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
|
|
||||||
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
|
|
||||||
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
|
|
||||||
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
|
|
||||||
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
|
|
||||||
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
|
|
||||||
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
|
|
||||||
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
|
|
||||||
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
|
|
||||||
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
|
||||||
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
|
||||||
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
|
||||||
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
|
||||||
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
|
||||||
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
|
||||||
|
|
||||||
/* Round 2 */
|
|
||||||
GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
|
|
||||||
GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
|
|
||||||
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
|
||||||
GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
|
|
||||||
GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
|
|
||||||
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
|
||||||
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
|
||||||
GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
|
|
||||||
GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
|
|
||||||
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
|
||||||
GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
|
|
||||||
|
|
||||||
GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
|
|
||||||
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
|
||||||
GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
|
|
||||||
GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
|
|
||||||
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
|
||||||
|
|
||||||
/* Round 3 */
|
|
||||||
HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
|
|
||||||
HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
|
|
||||||
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
|
||||||
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
|
||||||
HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
|
|
||||||
HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
|
|
||||||
HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
|
|
||||||
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
|
||||||
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
|
||||||
HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
|
|
||||||
HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
|
|
||||||
HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
|
|
||||||
HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
|
|
||||||
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
|
||||||
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
|
||||||
HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
|
|
||||||
|
|
||||||
/* Round 4 */
|
|
||||||
II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
|
|
||||||
II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
|
|
||||||
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
|
||||||
II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
|
|
||||||
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
|
||||||
II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
|
|
||||||
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
|
||||||
II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
|
|
||||||
II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
|
|
||||||
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
|
||||||
II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
|
|
||||||
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
|
||||||
II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
|
|
||||||
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
|
||||||
II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
|
|
||||||
II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
|
|
||||||
|
|
||||||
state[0] += a;
|
|
||||||
state[1] += b;
|
|
||||||
state[2] += c;
|
|
||||||
state[3] += d;
|
|
||||||
|
|
||||||
// Zeroize sensitive information.
|
|
||||||
memset(x, 0, sizeof(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
|
|
||||||
a multiple of 4.
|
|
||||||
*/
|
|
||||||
static void Encode(unsigned char *output, UINT4 *input, unsigned int len)
|
|
||||||
{
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
|
||||||
{
|
|
||||||
output[j] = (unsigned char) (input[i] & 0xff);
|
|
||||||
output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
|
|
||||||
output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
|
|
||||||
output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
|
|
||||||
a multiple of 4.
|
|
||||||
*/
|
|
||||||
static void Decode(UINT4 *output, unsigned char *input, unsigned int len)
|
|
||||||
{
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
|
||||||
output[i] = ((UINT4) input[j]) | (((UINT4) input[j + 1]) << 8) | (((UINT4) input[j + 2]) << 16) | (((UINT4) input[j + 3]) << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
74
md5.h
74
md5.h
|
|
@ -1,74 +0,0 @@
|
||||||
/* RSAREF types and constants
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __MD5_H__
|
|
||||||
#define __MD5_H__
|
|
||||||
|
|
||||||
/* PROTOTYPES should be set to one if and only if the compiler supports
|
|
||||||
function argument prototyping.
|
|
||||||
The following makes PROTOTYPES default to 0 if it has not already
|
|
||||||
|
|
||||||
been defined with C compiler flags.
|
|
||||||
*/
|
|
||||||
#ifndef PROTOTYPES
|
|
||||||
#define PROTOTYPES 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* POINTER defines a generic pointer type */
|
|
||||||
typedef unsigned char *POINTER;
|
|
||||||
|
|
||||||
/* UINT2 defines a two byte word */
|
|
||||||
typedef unsigned short int UINT2;
|
|
||||||
|
|
||||||
/* UINT4 defines a four byte word */
|
|
||||||
typedef unsigned long int UINT4;
|
|
||||||
|
|
||||||
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
|
|
||||||
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
|
|
||||||
returns an empty list.
|
|
||||||
*/
|
|
||||||
#if PROTOTYPES
|
|
||||||
#define PROTO_LIST(list) list
|
|
||||||
#else
|
|
||||||
#define PROTO_LIST(list) ()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* MD5.H - header file for MD5C.C
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
|
||||||
rights reserved.
|
|
||||||
|
|
||||||
License to copy and use this software is granted provided that it
|
|
||||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
|
||||||
Algorithm" in all material mentioning or referencing this software
|
|
||||||
or this function.
|
|
||||||
|
|
||||||
License is also granted to make and use derivative works provided
|
|
||||||
that such works are identified as "derived from the RSA Data
|
|
||||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
|
||||||
mentioning or referencing the derived work.
|
|
||||||
|
|
||||||
RSA Data Security, Inc. makes no representations concerning either
|
|
||||||
the merchantability of this software or the suitability of this
|
|
||||||
software for any particular purpose. It is provided "as is"
|
|
||||||
without express or implied warranty of any kind.
|
|
||||||
|
|
||||||
These notices must be retained in any copies of any part of this
|
|
||||||
documentation and/or software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* MD5 context. */
|
|
||||||
typedef struct {
|
|
||||||
UINT4 state[4]; /* state (ABCD) */
|
|
||||||
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
|
||||||
unsigned char buffer[64]; /* input buffer */
|
|
||||||
} MD5_CTX;
|
|
||||||
|
|
||||||
void MD5Init PROTO_LIST ((MD5_CTX *));
|
|
||||||
void MD5Update PROTO_LIST
|
|
||||||
((MD5_CTX *, unsigned char *, unsigned int));
|
|
||||||
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
|
|
||||||
|
|
||||||
#endif /* __MD5_H__ */
|
|
||||||
2
nsctl.c
2
nsctl.c
|
|
@ -141,7 +141,7 @@ static struct nsctl *request(char *host, int port, int type, int argc, char *arg
|
||||||
socklen_t len = sizeof(peer);
|
socklen_t len = sizeof(peer);
|
||||||
struct hostent *h = gethostbyname(host);
|
struct hostent *h = gethostbyname(host);
|
||||||
int fd;
|
int fd;
|
||||||
char buf[NSCTL_MAX_PKT_SZ];
|
uint8_t buf[NSCTL_MAX_PKT_SZ];
|
||||||
int sz;
|
int sz;
|
||||||
char *err;
|
char *err;
|
||||||
|
|
||||||
|
|
|
||||||
2
plugin.h
2
plugin.h
|
|
@ -28,7 +28,7 @@ enum
|
||||||
struct pluginfuncs
|
struct pluginfuncs
|
||||||
{
|
{
|
||||||
void (*log)(int level, sessionidt s, tunnelidt t, const char *format, ...);
|
void (*log)(int level, sessionidt s, tunnelidt t, const char *format, ...);
|
||||||
void (*log_hex)(int level, const char *title, const char *data, int maxsize);
|
void (*log_hex)(int level, const char *title, const uint8_t *data, int maxsize);
|
||||||
char *(*fmtaddr)(in_addr_t addr, int n);
|
char *(*fmtaddr)(in_addr_t addr, int n);
|
||||||
sessionidt (*get_session_by_username)(char *username);
|
sessionidt (*get_session_by_username)(char *username);
|
||||||
sessiont *(*get_session_by_id)(sessionidt s);
|
sessiont *(*get_session_by_id)(sessionidt s);
|
||||||
|
|
|
||||||
106
radius.c
106
radius.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS Radius Stuff
|
// L2TPNS Radius Stuff
|
||||||
|
|
||||||
char const *cvs_id_radius = "$Id: radius.c,v 1.36 2005/06/30 14:31:26 bodea Exp $";
|
char const *cvs_id_radius = "$Id: radius.c,v 1.37 2005/07/31 10:04:10 bodea Exp $";
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -13,7 +13,7 @@ char const *cvs_id_radius = "$Id: radius.c,v 1.36 2005/06/30 14:31:26 bodea Exp
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "md5.h"
|
#include <openssl/md5.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "l2tpns.h"
|
#include "l2tpns.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
@ -182,7 +182,7 @@ void radiussend(uint16_t r, uint8_t state)
|
||||||
{
|
{
|
||||||
*p = 1; // user name
|
*p = 1; // user name
|
||||||
p[1] = strlen(session[s].user) + 2;
|
p[1] = strlen(session[s].user) + 2;
|
||||||
strcpy(p + 2, session[s].user);
|
strcpy((char *) p + 2, session[s].user);
|
||||||
p += p[1];
|
p += p[1];
|
||||||
}
|
}
|
||||||
if (state == RADIUSAUTH)
|
if (state == RADIUSAUTH)
|
||||||
|
|
@ -212,13 +212,13 @@ void radiussend(uint16_t r, uint8_t state)
|
||||||
while (p < pl)
|
while (p < pl)
|
||||||
{
|
{
|
||||||
MD5_CTX ctx;
|
MD5_CTX ctx;
|
||||||
MD5Init(&ctx);
|
MD5_Init(&ctx);
|
||||||
MD5Update(&ctx, config->radiussecret, strlen(config->radiussecret));
|
MD5_Update(&ctx, config->radiussecret, strlen(config->radiussecret));
|
||||||
if (p)
|
if (p)
|
||||||
MD5Update(&ctx, pass + p - 16, 16);
|
MD5_Update(&ctx, pass + p - 16, 16);
|
||||||
else
|
else
|
||||||
MD5Update(&ctx, radius[r].auth, 16);
|
MD5_Update(&ctx, radius[r].auth, 16);
|
||||||
MD5Final(hash, &ctx);
|
MD5_Final(hash, &ctx);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
pass[p] ^= hash[p & 15];
|
pass[p] ^= hash[p & 15];
|
||||||
|
|
@ -244,7 +244,7 @@ void radiussend(uint16_t r, uint8_t state)
|
||||||
{
|
{
|
||||||
*p = 44; // session ID
|
*p = 44; // session ID
|
||||||
p[1] = 18;
|
p[1] = 18;
|
||||||
sprintf(p + 2, "%08X%08X", session[s].unique_id, session[s].opened);
|
sprintf((char *) p + 2, "%08X%08X", session[s].unique_id, session[s].opened);
|
||||||
p += p[1];
|
p += p[1];
|
||||||
if (state == RADIUSSTART)
|
if (state == RADIUSSTART)
|
||||||
{ // start
|
{ // start
|
||||||
|
|
@ -299,7 +299,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((char *) 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);
|
||||||
|
|
||||||
p[1] = p[7] + 6;
|
p[1] = p[7] + 6;
|
||||||
|
|
@ -325,21 +325,14 @@ void radiussend(uint16_t r, uint8_t state)
|
||||||
{
|
{
|
||||||
*p = 30; // called
|
*p = 30; // called
|
||||||
p[1] = strlen(session[s].called) + 2;
|
p[1] = strlen(session[s].called) + 2;
|
||||||
strcpy(p + 2, session[s].called);
|
strcpy((char *) p + 2, session[s].called);
|
||||||
p += p[1];
|
|
||||||
}
|
|
||||||
if (*radius[r].calling)
|
|
||||||
{
|
|
||||||
*p = 31; // calling
|
|
||||||
p[1] = strlen(radius[r].calling) + 2;
|
|
||||||
strcpy(p + 2, radius[r].calling);
|
|
||||||
p += p[1];
|
p += p[1];
|
||||||
}
|
}
|
||||||
else if (*session[s].calling)
|
else if (*session[s].calling)
|
||||||
{
|
{
|
||||||
*p = 31; // calling
|
*p = 31; // calling
|
||||||
p[1] = strlen(session[s].calling) + 2;
|
p[1] = strlen(session[s].calling) + 2;
|
||||||
strcpy(p + 2, session[s].calling);
|
strcpy((char *) p + 2, session[s].calling);
|
||||||
p += p[1];
|
p += p[1];
|
||||||
}
|
}
|
||||||
// NAS-IP-Address
|
// NAS-IP-Address
|
||||||
|
|
@ -353,15 +346,15 @@ void radiussend(uint16_t r, uint8_t state)
|
||||||
if (state != RADIUSAUTH)
|
if (state != RADIUSAUTH)
|
||||||
{
|
{
|
||||||
// Build auth for accounting packet
|
// Build auth for accounting packet
|
||||||
char z[16] = {0};
|
uint8_t z[16] = {0};
|
||||||
char hash[16] = {0};
|
uint8_t hash[16] = {0};
|
||||||
MD5_CTX ctx;
|
MD5_CTX ctx;
|
||||||
MD5Init(&ctx);
|
MD5_Init(&ctx);
|
||||||
MD5Update(&ctx, b, 4);
|
MD5_Update(&ctx, b, 4);
|
||||||
MD5Update(&ctx, z, 16);
|
MD5_Update(&ctx, z, 16);
|
||||||
MD5Update(&ctx, b + 20, (p - b) - 20);
|
MD5_Update(&ctx, b + 20, (p - b) - 20);
|
||||||
MD5Update(&ctx, config->radiussecret, strlen(config->radiussecret));
|
MD5_Update(&ctx, config->radiussecret, strlen(config->radiussecret));
|
||||||
MD5Final(hash, &ctx);
|
MD5_Final(hash, &ctx);
|
||||||
memcpy(b + 4, hash, 16);
|
memcpy(b + 4, hash, 16);
|
||||||
memcpy(radius[r].auth, hash, 16);
|
memcpy(radius[r].auth, hash, 16);
|
||||||
}
|
}
|
||||||
|
|
@ -381,9 +374,9 @@ void radiussend(uint16_t r, uint8_t state)
|
||||||
|
|
||||||
static void handle_avpair(sessionidt s, uint8_t *avp, int len)
|
static void handle_avpair(sessionidt s, uint8_t *avp, int len)
|
||||||
{
|
{
|
||||||
char *key = avp;
|
uint8_t *key = avp;
|
||||||
char *value = memchr(avp, '=', len);
|
uint8_t *value = memchr(avp, '=', len);
|
||||||
char tmp[2048] = "";
|
uint8_t tmp[2048] = "";
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
|
|
@ -415,7 +408,7 @@ static void handle_avpair(sessionidt s, uint8_t *avp, int len)
|
||||||
|
|
||||||
// Run hooks
|
// Run hooks
|
||||||
{
|
{
|
||||||
struct param_radius_response p = { &tunnel[session[s].tunnel], &session[s], key, value };
|
struct param_radius_response p = { &tunnel[session[s].tunnel], &session[s], (char *) key, (char *) value };
|
||||||
run_plugins(PLUGIN_RADIUS_RESPONSE, &p);
|
run_plugins(PLUGIN_RADIUS_RESPONSE, &p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -463,12 +456,12 @@ void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
t = session[s].tunnel;
|
t = session[s].tunnel;
|
||||||
MD5Init(&ctx);
|
MD5_Init(&ctx);
|
||||||
MD5Update(&ctx, buf, 4);
|
MD5_Update(&ctx, buf, 4);
|
||||||
MD5Update(&ctx, radius[r].auth, 16);
|
MD5_Update(&ctx, radius[r].auth, 16);
|
||||||
MD5Update(&ctx, buf + 20, len - 20);
|
MD5_Update(&ctx, buf + 20, len - 20);
|
||||||
MD5Update(&ctx, config->radiussecret, strlen(config->radiussecret));
|
MD5_Update(&ctx, config->radiussecret, strlen(config->radiussecret));
|
||||||
MD5Final(hash, &ctx);
|
MD5_Final(hash, &ctx);
|
||||||
do {
|
do {
|
||||||
if (memcmp(hash, buf + 4, 16))
|
if (memcmp(hash, buf + 4, 16))
|
||||||
{
|
{
|
||||||
|
|
@ -617,7 +610,7 @@ void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
else if (*p == 11)
|
else if (*p == 11)
|
||||||
{
|
{
|
||||||
// Filter-Id
|
// Filter-Id
|
||||||
char *filter = p + 2;
|
char *filter = (char *) p + 2;
|
||||||
int l = p[1] - 2;
|
int l = p[1] - 2;
|
||||||
char *suffix;
|
char *suffix;
|
||||||
int f;
|
int f;
|
||||||
|
|
@ -680,10 +673,10 @@ void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
int prefixlen;
|
int prefixlen;
|
||||||
uint8_t *n = p + 2;
|
uint8_t *n = p + 2;
|
||||||
uint8_t *e = p + p[1];
|
uint8_t *e = p + p[1];
|
||||||
uint8_t *m = strchr(n, '/');
|
uint8_t *m = memchr(n, '/', e - p);
|
||||||
|
|
||||||
*m++ = 0;
|
*m++ = 0;
|
||||||
inet_pton(AF_INET6, n, &r6);
|
inet_pton(AF_INET6, (char *) n, &r6);
|
||||||
|
|
||||||
prefixlen = 0;
|
prefixlen = 0;
|
||||||
while (m < e && isdigit(*m)) {
|
while (m < e && isdigit(*m)) {
|
||||||
|
|
@ -710,12 +703,12 @@ void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
|
|
||||||
if (!session[s].dns1 && config->default_dns1)
|
if (!session[s].dns1 && config->default_dns1)
|
||||||
{
|
{
|
||||||
session[s].dns1 = htonl(config->default_dns1);
|
session[s].dns1 = ntohl(config->default_dns1);
|
||||||
LOG(3, s, t, " Sending dns1 = %s\n", fmtaddr(config->default_dns1, 0));
|
LOG(3, s, t, " Sending dns1 = %s\n", fmtaddr(config->default_dns1, 0));
|
||||||
}
|
}
|
||||||
if (!session[s].dns2 && config->default_dns2)
|
if (!session[s].dns2 && config->default_dns2)
|
||||||
{
|
{
|
||||||
session[s].dns2 = htonl(config->default_dns2);
|
session[s].dns2 = ntohl(config->default_dns2);
|
||||||
LOG(3, s, t, " Sending dns2 = %s\n", fmtaddr(config->default_dns2, 0));
|
LOG(3, s, t, " Sending dns2 = %s\n", fmtaddr(config->default_dns2, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -750,20 +743,11 @@ void radiusretry(uint16_t r)
|
||||||
case RADIUSCHAP: // sending CHAP down PPP
|
case RADIUSCHAP: // sending CHAP down PPP
|
||||||
sendchap(t, s);
|
sendchap(t, s);
|
||||||
break;
|
break;
|
||||||
case RADIUSIPCP:
|
|
||||||
sendipcp(t, s); // send IPCP
|
|
||||||
break;
|
|
||||||
case RADIUSAUTH: // sending auth to RADIUS server
|
case RADIUSAUTH: // sending auth to RADIUS server
|
||||||
radiussend(r, RADIUSAUTH);
|
|
||||||
break;
|
|
||||||
case RADIUSSTART: // sending start accounting to RADIUS server
|
case RADIUSSTART: // sending start accounting to RADIUS server
|
||||||
radiussend(r, RADIUSSTART);
|
|
||||||
break;
|
|
||||||
case RADIUSSTOP: // sending stop accounting to RADIUS server
|
case RADIUSSTOP: // sending stop accounting to RADIUS server
|
||||||
radiussend(r, RADIUSSTOP);
|
|
||||||
break;
|
|
||||||
case RADIUSINTERIM: // sending interim accounting to RADIUS server
|
case RADIUSINTERIM: // sending interim accounting to RADIUS server
|
||||||
radiussend(r, RADIUSINTERIM);
|
radiussend(r, radius[r].state);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case RADIUSNULL: // Not in use
|
case RADIUSNULL: // Not in use
|
||||||
|
|
@ -832,10 +816,10 @@ void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen)
|
||||||
i = strlen(config->radiussecret);
|
i = strlen(config->radiussecret);
|
||||||
if (i > 16) i = 16;
|
if (i > 16) i = 16;
|
||||||
|
|
||||||
MD5Init(&ctx);
|
MD5_Init(&ctx);
|
||||||
MD5Update(&ctx, buf, len);
|
MD5_Update(&ctx, buf, len);
|
||||||
MD5Update(&ctx, buf, config->radiussecret, i);
|
MD5_Update(&ctx, config->radiussecret, i);
|
||||||
MD5Final(hash, &ctx);
|
MD5_Final(hash, &ctx);
|
||||||
if (memcmp(hash, vector, 16) != 0)
|
if (memcmp(hash, vector, 16) != 0)
|
||||||
{
|
{
|
||||||
LOG(1, 0, 0, "Incorrect vector in DAE request (wrong secret in radius config?)\n");
|
LOG(1, 0, 0, "Incorrect vector in DAE request (wrong secret in radius config?)\n");
|
||||||
|
|
@ -903,7 +887,7 @@ void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen)
|
||||||
}
|
}
|
||||||
|
|
||||||
len = p - packet;
|
len = p - packet;
|
||||||
i = find_filter(packet, len);
|
i = find_filter((char *) packet, len);
|
||||||
if (i < 0 || !*ip_filters[i].name)
|
if (i < 0 || !*ip_filters[i].name)
|
||||||
{
|
{
|
||||||
error = 404;
|
error = 404;
|
||||||
|
|
@ -1063,10 +1047,10 @@ void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen)
|
||||||
i = strlen(config->radiussecret);
|
i = strlen(config->radiussecret);
|
||||||
if (i > 16) i = 16;
|
if (i > 16) i = 16;
|
||||||
|
|
||||||
MD5Init(&ctx);
|
MD5_Init(&ctx);
|
||||||
MD5Update(&ctx, buf, len);
|
MD5_Update(&ctx, buf, len);
|
||||||
MD5Update(&ctx, config->radiussecret, i);
|
MD5_Update(&ctx, config->radiussecret, i);
|
||||||
MD5Final(hash, &ctx);
|
MD5_Final(hash, &ctx);
|
||||||
memcpy(buf + 4, hash, 16);
|
memcpy(buf + 4, hash, 16);
|
||||||
|
|
||||||
LOG(3, 0, 0, "Sending DAE %s, id=%d\n", radius_code(r_code), r_id);
|
LOG(3, 0, 0, "Sending DAE %s, id=%d\n", radius_code(r_code), r_id);
|
||||||
|
|
|
||||||
4
tbf.c
4
tbf.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS: token bucket filters
|
// L2TPNS: token bucket filters
|
||||||
|
|
||||||
char const *cvs_id_tbf = "$Id: tbf.c,v 1.12 2005/05/02 09:55:04 bodea Exp $";
|
char const *cvs_id_tbf = "$Id: tbf.c,v 1.13 2005/07/31 10:04:10 bodea Exp $";
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "l2tpns.h"
|
#include "l2tpns.h"
|
||||||
|
|
@ -159,7 +159,7 @@ void fsck_tbfs(void)
|
||||||
// If we can send it right away, we do. Else we
|
// If we can send it right away, we do. Else we
|
||||||
// try and queue it to send later. Else we drop it.
|
// try and queue it to send later. Else we drop it.
|
||||||
//
|
//
|
||||||
int tbf_queue_packet(int tbf_id, char * data, int size)
|
int tbf_queue_packet(int tbf_id, uint8_t *data, int size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
tbft *f;
|
tbft *f;
|
||||||
|
|
|
||||||
4
tbf.h
4
tbf.h
|
|
@ -30,12 +30,12 @@ typedef struct {
|
||||||
uint32_t p_delayed; // Total packets not sent immediately.
|
uint32_t p_delayed; // Total packets not sent immediately.
|
||||||
|
|
||||||
int sizes[TBF_MAX_QUEUE];
|
int sizes[TBF_MAX_QUEUE];
|
||||||
char packets[TBF_MAX_QUEUE][TBF_MAX_SIZE];
|
uint8_t packets[TBF_MAX_QUEUE][TBF_MAX_SIZE];
|
||||||
} tbft;
|
} tbft;
|
||||||
|
|
||||||
void init_tbf(int num_tbfs);
|
void init_tbf(int num_tbfs);
|
||||||
int tbf_run_timer(void);
|
int tbf_run_timer(void);
|
||||||
int tbf_queue_packet(int tbf_id, char * data, int size);
|
int tbf_queue_packet(int tbf_id, uint8_t * data, int size);
|
||||||
int new_tbf(int sid, int max_credit, int rate, void (*f)(sessionidt, uint8_t *, int));
|
int new_tbf(int sid, int max_credit, int rate, void (*f)(sessionidt, uint8_t *, int));
|
||||||
int free_tbf(int tid);
|
int free_tbf(int tid);
|
||||||
void fsck_tbfs(void);
|
void fsck_tbfs(void);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "../md5.h"
|
#include <openssl/md5.h>
|
||||||
|
|
||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
extern int optind;
|
extern int optind;
|
||||||
|
|
@ -394,16 +394,16 @@ int main(int argc, char *argv[])
|
||||||
for (int j = 0; j < pw_len; j += 16)
|
for (int j = 0; j < pw_len; j += 16)
|
||||||
{
|
{
|
||||||
MD5_CTX ctx;
|
MD5_CTX ctx;
|
||||||
MD5Init(&ctx);
|
MD5_Init(&ctx);
|
||||||
MD5Update(&ctx, secret, strlen(secret));
|
MD5_Update(&ctx, secret, strlen(secret));
|
||||||
if (j)
|
if (j)
|
||||||
MD5Update(&ctx, pass + j - 16, 16);
|
MD5_Update(&ctx, pass + j - 16, 16);
|
||||||
else
|
else
|
||||||
/* authenticator */
|
/* authenticator */
|
||||||
MD5Update(&ctx, u->request + 4, 16);
|
MD5_Update(&ctx, u->request + 4, 16);
|
||||||
|
|
||||||
char digest[16];
|
uint8_t digest[16];
|
||||||
MD5Final(digest, &ctx);
|
MD5_Final(digest, &ctx);
|
||||||
|
|
||||||
for (int k = 0; k < 16; k++)
|
for (int k = 0; k < 16; k++)
|
||||||
pass[j + k] ^= digest[k];
|
pass[j + k] ^= digest[k];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue