From 2ddf1bced884ee587a205bfc156607e52e5a8dec Mon Sep 17 00:00:00 2001 From: bodea Date: Mon, 19 Sep 2005 02:39:57 +0000 Subject: [PATCH 01/16] calc Mbps correctly --- l2tpns.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/l2tpns.c b/l2tpns.c index b94926c..d6fa99e 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -4,7 +4,7 @@ // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced // vim: sw=8 ts=8 -char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.141 2005/09/19 00:29:12 bodea Exp $"; +char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.142 2005/09/19 02:39:57 bodea Exp $"; #include #include @@ -3411,18 +3411,19 @@ static void mainloop(void) if (time_changed) { - double Mbps = ((1024.0 / 1024.0) * 8) / time_changed; - time_changed = 0; + double Mbps = 1024.0 * 1024.0 / 8 * time_changed; // Log current traffic stats snprintf(config->bandwidth, sizeof(config->bandwidth), "UDP-ETH:%1.0f/%1.0f ETH-UDP:%1.0f/%1.0f TOTAL:%0.1f IN:%u OUT:%u", (udp_rx / Mbps), (eth_tx / Mbps), (eth_rx / Mbps), (udp_tx / Mbps), - ((udp_tx + udp_rx + eth_tx + eth_rx) / Mbps), udp_rx_pkt, eth_rx_pkt); + ((udp_tx + udp_rx + eth_tx + eth_rx) / Mbps), + udp_rx_pkt / time_changed, eth_rx_pkt / time_changed); udp_tx = udp_rx = 0; udp_rx_pkt = eth_rx_pkt = 0; eth_tx = eth_rx = 0; + time_changed = 0; if (config->dump_speed) printf("%s\n", config->bandwidth); -- 2.20.1 From c463b012b7aca35620c0b2bdcc241c5f24821cfc Mon Sep 17 00:00:00 2001 From: bodea Date: Fri, 30 Sep 2005 13:13:26 +0000 Subject: [PATCH 02/16] fix Calling-Station-Id in RADIUS accounting records --- Changes | 3 +++ THANKS | 1 + l2tpns.h | 4 ++-- l2tpns.spec | 6 +++--- radius.c | 4 ++-- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Changes b/Changes index 90d7075..e2f237f 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,6 @@ +* Fri Sep 30 2005 Brendan O'Dea 2.1.9 +- Fix Calling-Station-Id in RADIUS accounting records (Slobodan Tomic). + * Mon Sep 19 2005 Brendan O'Dea 2.1.8 - Move code from signal handlers into mainloop, avoiding a race condition when forking CLI. diff --git a/THANKS b/THANKS index 16e4f5b..08ca6e2 100644 --- a/THANKS +++ b/THANKS @@ -19,3 +19,4 @@ Vladislav Bjelic Alex Kiernan Dominique Rousseau Tim Devries +Slobodan Tomic diff --git a/l2tpns.h b/l2tpns.h index 5c09dde..bc99ac1 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -1,5 +1,5 @@ // L2TPNS Global Stuff -// $Id: l2tpns.h,v 1.92 2005/09/19 00:29:12 bodea Exp $ +// $Id: l2tpns.h,v 1.93 2005/09/30 13:13:26 bodea Exp $ #ifndef __L2TPNS_H__ #define __L2TPNS_H__ @@ -15,7 +15,7 @@ #include #include -#define VERSION "2.1.8" +#define VERSION "2.1.9" // Limits #define MAXTUNNEL 500 // could be up to 65535 diff --git a/l2tpns.spec b/l2tpns.spec index 1a278a0..1eab27c 100644 --- a/l2tpns.spec +++ b/l2tpns.spec @@ -1,6 +1,6 @@ Summary: A high-speed clustered L2TP LNS Name: l2tpns -Version: 2.1.8 +Version: 2.1.9 Release: 1 Copyright: GPL Group: System Environment/Daemons @@ -43,5 +43,5 @@ rm -rf %{buildroot} %attr(644,root,root) /usr/share/man/man[58]/* %changelog -* Mon Sep 19 2005 Brendan O'Dea 2.1.8-1 -- 2.1.8 release, see /usr/share/doc/l2tpns-2.1.8/Changes +* Fri Sep 30 2005 Brendan O'Dea 2.1.9-1 +- 2.1.9 release, see /usr/share/doc/l2tpns-2.1.9/Changes diff --git a/radius.c b/radius.c index ce1d39e..1cdfe7d 100644 --- a/radius.c +++ b/radius.c @@ -1,6 +1,6 @@ // L2TPNS Radius Stuff -char const *cvs_id_radius = "$Id: radius.c,v 1.41 2005/08/31 12:41:09 bodea Exp $"; +char const *cvs_id_radius = "$Id: radius.c,v 1.42 2005/09/30 13:13:26 bodea Exp $"; #include #include @@ -326,7 +326,7 @@ void radiussend(uint16_t r, uint8_t state) strcpy((char *) p + 2, session[s].called); p += p[1]; } - else if (*session[s].calling) + if (*session[s].calling) { *p = 31; // calling p[1] = strlen(session[s].calling) + 2; -- 2.20.1 From f3330037865c0bef6e1e63d32d87cfc8c1954eb6 Mon Sep 17 00:00:00 2001 From: foonly Date: Tue, 11 Oct 2005 02:27:40 +0000 Subject: [PATCH 03/16] Fix RADIUS authentication on DAE responses. --- Changes | 3 ++- THANKS | 1 + l2tpns.spec | 2 +- radius.c | 72 ++++++++++++++++++++--------------------------------- 4 files changed, 31 insertions(+), 47 deletions(-) diff --git a/Changes b/Changes index e2f237f..9d913cc 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,6 @@ -* Fri Sep 30 2005 Brendan O'Dea 2.1.9 +* Tue Oct 11 2005 Michael Chapman 2.1.9 - Fix Calling-Station-Id in RADIUS accounting records (Slobodan Tomic). +- Fix RADIUS authentication on DAE responses. * Mon Sep 19 2005 Brendan O'Dea 2.1.8 - Move code from signal handlers into mainloop, avoiding a race diff --git a/THANKS b/THANKS index 08ca6e2..ffe0aa7 100644 --- a/THANKS +++ b/THANKS @@ -20,3 +20,4 @@ Alex Kiernan Dominique Rousseau Tim Devries Slobodan Tomic +Michael Chapman diff --git a/l2tpns.spec b/l2tpns.spec index 1eab27c..3f4e076 100644 --- a/l2tpns.spec +++ b/l2tpns.spec @@ -43,5 +43,5 @@ rm -rf %{buildroot} %attr(644,root,root) /usr/share/man/man[58]/* %changelog -* Fri Sep 30 2005 Brendan O'Dea 2.1.9-1 +* Tue Oct 11 2005 Michael Chapman 2.1.9-1 - 2.1.9 release, see /usr/share/doc/l2tpns-2.1.9/Changes diff --git a/radius.c b/radius.c index 1cdfe7d..0059fcc 100644 --- a/radius.c +++ b/radius.c @@ -1,6 +1,6 @@ // L2TPNS Radius Stuff -char const *cvs_id_radius = "$Id: radius.c,v 1.42 2005/09/30 13:13:26 bodea Exp $"; +char const *cvs_id_radius = "$Id: radius.c,v 1.43 2005/10/11 02:27:40 foonly Exp $"; #include #include @@ -27,6 +27,20 @@ extern configt *config; extern int *radfds; extern ip_filtert *ip_filters; +static const hasht zero; + +static void calc_auth(const void *buf, size_t len, const uint8_t *in, uint8_t *out) +{ + MD5_CTX ctx; + + MD5_Init(&ctx); + MD5_Update(&ctx, (void *)buf, 4); // code, id, length + MD5_Update(&ctx, (void *)in, 16); // auth + MD5_Update(&ctx, (void *)(buf + 20), len - 20); + MD5_Update(&ctx, config->radiussecret, strlen(config->radiussecret)); + MD5_Final(out, &ctx); +} + // Set up socket for radius requests void initrad(void) { @@ -343,18 +357,9 @@ void radiussend(uint16_t r, uint8_t state) *(uint16_t *) (b + 2) = htons(p - b); if (state != RADIUSAUTH) { - // Build auth for accounting packet - uint8_t z[16] = {0}; - uint8_t hash[16] = {0}; - MD5_CTX ctx; - MD5_Init(&ctx); - MD5_Update(&ctx, b, 4); - MD5_Update(&ctx, z, 16); - MD5_Update(&ctx, b + 20, (p - b) - 20); - MD5_Update(&ctx, config->radiussecret, strlen(config->radiussecret)); - MD5_Final(hash, &ctx); - memcpy(b + 4, hash, 16); - memcpy(radius[r].auth, hash, 16); + // Build auth for accounting packet + calc_auth(b, p - b, zero, b + 4); + memcpy(radius[r].auth, b + 4, 16); } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; @@ -415,7 +420,6 @@ static void handle_avpair(sessionidt s, uint8_t *avp, int len) void processrad(uint8_t *buf, int len, char socket_index) { uint8_t b[MAXETHER]; - MD5_CTX ctx; uint16_t r; sessionidt s; tunnelidt t = 0; @@ -454,12 +458,7 @@ void processrad(uint8_t *buf, int len, char socket_index) return; } t = session[s].tunnel; - MD5_Init(&ctx); - MD5_Update(&ctx, buf, 4); - MD5_Update(&ctx, radius[r].auth, 16); - MD5_Update(&ctx, buf + 20, len - 20); - MD5_Update(&ctx, config->radiussecret, strlen(config->radiussecret)); - MD5_Final(hash, &ctx); + calc_auth(buf, len, radius[r].auth, hash); do { if (memcmp(hash, buf + 4, 16)) { @@ -762,8 +761,8 @@ extern int daefd; void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen) { int i, r_code, r_id, length, attribute_length; - uint8_t vector[16], hash[16], *packet, attribute; - MD5_CTX ctx; + uint8_t *packet, attribute; + hasht hash; char username[MAXUSER] = ""; in_addr_t nas = 0; in_addr_t ip = 0; @@ -808,17 +807,8 @@ void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen) LOG(3, 0, 0, "Received DAE %s, id %d\n", radius_code(r_code), r_id); // check authenticator - memcpy(vector, buf + 4, 16); - memset(buf + 4, 0, 16); - - i = strlen(config->radiussecret); - if (i > 16) i = 16; - - MD5_Init(&ctx); - MD5_Update(&ctx, buf, len); - MD5_Update(&ctx, config->radiussecret, i); - MD5_Final(hash, &ctx); - if (memcmp(hash, vector, 16) != 0) + calc_auth(buf, len, zero, hash); + if (memcmp(hash, buf + 4, 16) != 0) { LOG(1, 0, 0, "Incorrect vector in DAE request (wrong secret in radius config?)\n"); return; @@ -1024,10 +1014,9 @@ void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen) packet = buf; *packet++ = r_code; *packet++ = r_id; - packet += 2; - memset(packet, 0, 16); - packet += 16; - len = 20; + // skip len + auth + packet += 2 + 16; + len = packet - buf; // add attributes if (error) @@ -1042,14 +1031,7 @@ void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen) *((uint16_t *)(buf + 2)) = htons(len); // make vector - i = strlen(config->radiussecret); - if (i > 16) i = 16; - - MD5_Init(&ctx); - MD5_Update(&ctx, buf, len); - MD5_Update(&ctx, config->radiussecret, i); - MD5_Final(hash, &ctx); - memcpy(buf + 4, hash, 16); + calc_auth(buf, len, hash, buf + 4); LOG(3, 0, 0, "Sending DAE %s, id=%d\n", radius_code(r_code), r_id); -- 2.20.1 From 86042401144b293807e8d31a29734fa806658ef4 Mon Sep 17 00:00:00 2001 From: bodea Date: Tue, 11 Oct 2005 07:06:56 +0000 Subject: [PATCH 04/16] don't send tunnel HELLO when there are pending control messages --- Changes | 3 ++- l2tpns.c | 6 +++--- l2tpns.h | 4 ++-- l2tpns.spec | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Changes b/Changes index 9d913cc..e245c30 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,7 @@ -* Tue Oct 11 2005 Michael Chapman 2.1.9 +* Tue Oct 11 2005 Brendan O'Dea 2.1.9 - Fix Calling-Station-Id in RADIUS accounting records (Slobodan Tomic). - Fix RADIUS authentication on DAE responses. +- Don't send tunnel HELLO when there are pending control messages. * Mon Sep 19 2005 Brendan O'Dea 2.1.8 - Move code from signal handlers into mainloop, avoiding a race diff --git a/l2tpns.c b/l2tpns.c index d6fa99e..ec2bd17 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -4,7 +4,7 @@ // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced // vim: sw=8 ts=8 -char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.142 2005/09/19 02:39:57 bodea Exp $"; +char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.143 2005/10/11 07:06:56 bodea Exp $"; #include #include @@ -961,7 +961,7 @@ void tunnelsend(uint8_t * buf, uint16_t l, tunnelidt t) { tunnel[t].last = time_now; // control message sent tunnel[t].retry = backoff(tunnel[t].try); // when to resend - if (tunnel[t].try > 1) + if (tunnel[t].try) { STAT(tunnel_retries); LOG(3, 0, t, "Control message resend try %d\n", tunnel[t].try); @@ -2745,7 +2745,7 @@ static void regular_cleanups(double period) } } // Send hello - if (tunnel[t].state == TUNNELOPEN && (time_now - tunnel[t].lastrec) > 60) + if (tunnel[t].state == TUNNELOPEN && !tunnel[t].controlc && (time_now - tunnel[t].lastrec) > 60) { controlt *c = controlnew(6); // sending HELLO controladd(c, 0, t); // send the message diff --git a/l2tpns.h b/l2tpns.h index bc99ac1..9c0aa3f 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -1,5 +1,5 @@ // L2TPNS Global Stuff -// $Id: l2tpns.h,v 1.93 2005/09/30 13:13:26 bodea Exp $ +// $Id: l2tpns.h,v 1.94 2005/10/11 07:06:56 bodea Exp $ #ifndef __L2TPNS_H__ #define __L2TPNS_H__ @@ -323,7 +323,7 @@ typedef struct uint16_t ns; // next send int state; // current state (tunnelstate enum) clockt last; // when last control message sent (used for resend timeout) - clockt retry; // when to try resenting pending control + clockt retry; // when to try resending pending control clockt die; // being closed, when to finally free clockt lastrec; // when the last control message was received char hostname[128]; // tunnel hostname diff --git a/l2tpns.spec b/l2tpns.spec index 3f4e076..e1cf5a5 100644 --- a/l2tpns.spec +++ b/l2tpns.spec @@ -43,5 +43,5 @@ rm -rf %{buildroot} %attr(644,root,root) /usr/share/man/man[58]/* %changelog -* Tue Oct 11 2005 Michael Chapman 2.1.9-1 +* Tue Oct 11 2005 Brendan O'Dea 2.1.9-1 - 2.1.9 release, see /usr/share/doc/l2tpns-2.1.9/Changes -- 2.20.1 From 5d659af7fda3ce995ab61ca4cd296fbdddd6f5e4 Mon Sep 17 00:00:00 2001 From: bodea Date: Tue, 11 Oct 2005 07:59:09 +0000 Subject: [PATCH 05/16] move plugin_radius_reset from *ctl to auto* plugins --- Changes | 1 + autosnoop.c | 9 ++++++++- autothrottle.c | 8 +++++++- snoopctl.c | 9 +-------- throttlectl.c | 8 +------- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/Changes b/Changes index e245c30..dfeabaa 100644 --- a/Changes +++ b/Changes @@ -2,6 +2,7 @@ - Fix Calling-Station-Id in RADIUS accounting records (Slobodan Tomic). - Fix RADIUS authentication on DAE responses. - Don't send tunnel HELLO when there are pending control messages. +- Move plugin_radius_reset from *ctl to auto* plugins. * Mon Sep 19 2005 Brendan O'Dea 2.1.8 - Move code from signal handlers into mainloop, avoiding a race diff --git a/autosnoop.c b/autosnoop.c index 9ed5b1f..4ac2171 100644 --- a/autosnoop.c +++ b/autosnoop.c @@ -4,7 +4,7 @@ /* set up intercept based on RADIUS reply */ -char const *cvs_id = "$Id: autosnoop.c,v 1.10 2004/11/30 05:49:47 bodea Exp $"; +char const *cvs_id = "$Id: autosnoop.c,v 1.11 2005/10/11 07:59:09 bodea Exp $"; int plugin_api_version = PLUGIN_API_VERSION; struct pluginfuncs *p; @@ -36,6 +36,13 @@ int plugin_radius_response(struct param_radius_response *data) return PLUGIN_RET_OK; } +int plugin_radius_reset(struct param_radius_reset *data) +{ + data->s->snoop_ip = 0; + data->s->snoop_port = 0; + return PLUGIN_RET_OK; +} + int plugin_init(struct pluginfuncs *funcs) { return ((p = funcs)) ? 1 : 0; diff --git a/autothrottle.c b/autothrottle.c index 1a37809..8f81776 100644 --- a/autothrottle.c +++ b/autothrottle.c @@ -13,7 +13,7 @@ * throttle=no */ -char const *cvs_id = "$Id: autothrottle.c,v 1.14 2005/05/13 05:28:16 bodea Exp $"; +char const *cvs_id = "$Id: autothrottle.c,v 1.15 2005/10/11 07:59:09 bodea Exp $"; int plugin_api_version = PLUGIN_API_VERSION; struct pluginfuncs *p; @@ -110,6 +110,12 @@ int plugin_radius_response(struct param_radius_response *data) return PLUGIN_RET_OK; } +int plugin_radius_reset(struct param_radius_reset *data) +{ + p->throttle(p->get_id_by_session(data->s), 0, 0); + return PLUGIN_RET_OK; +} + int plugin_init(struct pluginfuncs *funcs) { return ((p = funcs)) ? 1 : 0; diff --git a/snoopctl.c b/snoopctl.c index 5fabe24..0bb46da 100644 --- a/snoopctl.c +++ b/snoopctl.c @@ -5,7 +5,7 @@ /* snoop control */ -char const *cvs_id = "$Id: snoopctl.c,v 1.5 2005/06/28 14:48:28 bodea Exp $"; +char const *cvs_id = "$Id: snoopctl.c,v 1.6 2005/10/11 07:59:09 bodea Exp $"; int plugin_api_version = PLUGIN_API_VERSION; static struct pluginfuncs *p = 0; @@ -116,13 +116,6 @@ int plugin_control(struct param_control *data) return PLUGIN_RET_STOP; } -int plugin_radius_reset(struct param_radius_reset *data) -{ - data->s->snoop_ip = 0; - data->s->snoop_port = 0; - return PLUGIN_RET_OK; -} - int plugin_init(struct pluginfuncs *funcs) { return ((p = funcs)) ? 1 : 0; diff --git a/throttlectl.c b/throttlectl.c index 2e2c5c7..f0106f8 100644 --- a/throttlectl.c +++ b/throttlectl.c @@ -5,7 +5,7 @@ /* throttle control */ -char const *cvs_id = "$Id: throttlectl.c,v 1.7 2005/06/28 14:48:28 bodea Exp $"; +char const *cvs_id = "$Id: throttlectl.c,v 1.8 2005/10/11 07:59:09 bodea Exp $"; int plugin_api_version = PLUGIN_API_VERSION; static struct pluginfuncs *p = 0; @@ -129,12 +129,6 @@ int plugin_control(struct param_control *data) return PLUGIN_RET_STOP; } -int plugin_radius_reset(struct param_radius_reset *data) -{ - p->throttle(p->get_id_by_session(data->s), 0, 0); - return PLUGIN_RET_OK; -} - int plugin_init(struct pluginfuncs *funcs) { return ((p = funcs)) ? 1 : 0; -- 2.20.1 From f6b56a0f4d893dc98cf029de7bd58ac4f2a64db7 Mon Sep 17 00:00:00 2001 From: bodea Date: Tue, 11 Oct 2005 09:04:53 +0000 Subject: [PATCH 06/16] add Cisco-AVPairs to RADIUS accounting records via plugin_radius_account --- Changes | 1 + autosnoop.c | 74 ++++++---- autothrottle.c | 206 ++++++++++++++++------------ garden.c | 359 ++++++++++++++++++++++++++----------------------- l2tpns.c | 3 +- plugin.h | 130 +++++++++--------- radius.c | 17 +-- sessionctl.c | 14 +- setrxspeed.c | 46 ++++--- snoopctl.c | 160 +++++++++++----------- stripdomain.c | 24 ++-- throttlectl.c | 172 +++++++++++------------ 12 files changed, 645 insertions(+), 561 deletions(-) diff --git a/Changes b/Changes index dfeabaa..aee33c3 100644 --- a/Changes +++ b/Changes @@ -3,6 +3,7 @@ - Fix RADIUS authentication on DAE responses. - Don't send tunnel HELLO when there are pending control messages. - Move plugin_radius_reset from *ctl to auto* plugins. +- Add Cisco-AVPairs to RADIUS accounting records via plugin_radius_account. * Mon Sep 19 2005 Brendan O'Dea 2.1.8 - Move code from signal handlers into mainloop, avoiding a race diff --git a/autosnoop.c b/autosnoop.c index 4ac2171..fa3de8b 100644 --- a/autosnoop.c +++ b/autosnoop.c @@ -4,46 +4,72 @@ /* set up intercept based on RADIUS reply */ -char const *cvs_id = "$Id: autosnoop.c,v 1.11 2005/10/11 07:59:09 bodea Exp $"; +char const *cvs_id = "$Id: autosnoop.c,v 1.12 2005/10/11 09:04:53 bodea Exp $"; int plugin_api_version = PLUGIN_API_VERSION; -struct pluginfuncs *p; +static struct pluginfuncs *f = 0; int plugin_radius_response(struct param_radius_response *data) { - if (!strcmp(data->key, "intercept")) + if (!strcmp(data->key, "intercept")) + { + char *p; + data->s->snoop_ip = 0; + data->s->snoop_port = 0; + if ((p = strchr(data->value, ':'))) { - char *x; + *p++ = 0; + if (*data->value) + data->s->snoop_ip = inet_addr(data->value); + + if (data->s->snoop_ip == INADDR_NONE) data->s->snoop_ip = 0; - data->s->snoop_port = 0; - if ((x = strchr(data->value, ':'))) - { - *x++ = 0; - if (*data->value) data->s->snoop_ip = inet_addr(data->value); - if (data->s->snoop_ip == INADDR_NONE) data->s->snoop_ip = 0; - if (*x) data->s->snoop_port = atoi(x); - p->log(3, p->get_id_by_session(data->s), data->s->tunnel, - " Intercepting user to %s:%d\n", - p->fmtaddr(data->s->snoop_ip, 0), data->s->snoop_port); - } - else - { - p->log(3, p->get_id_by_session(data->s), data->s->tunnel, - " Not Intercepting user (reply string should be intercept=ip:port)\n"); - } + + if (*p) + data->s->snoop_port = atoi(p); + + f->log(3, f->get_id_by_session(data->s), data->s->tunnel, + " Intercepting user to %s:%d\n", + f->fmtaddr(data->s->snoop_ip, 0), data->s->snoop_port); + } + else + { + f->log(3, f->get_id_by_session(data->s), data->s->tunnel, + " Not Intercepting user (reply string should" + " be intercept=ip:port)\n"); } + } return PLUGIN_RET_OK; } int plugin_radius_reset(struct param_radius_reset *data) { - data->s->snoop_ip = 0; - data->s->snoop_port = 0; - return PLUGIN_RET_OK; + data->s->snoop_ip = 0; + data->s->snoop_port = 0; + return PLUGIN_RET_OK; +} + +int plugin_radius_account(struct param_radius_account *data) +{ + if (data->s->snoop_ip && data->s->snoop_port) + { + uint8_t *p = *data->packet; + + *p = 26; // vendor-specific + *(uint32_t *) (p + 2) = htonl(9); // Cisco + p[6] = 1; // Cisco-AVPair + p[7] = 2 + sprintf((char *) p + 8, "intercept=%s:%d", + f->fmtaddr(data->s->snoop_ip, 0), data->s->snoop_port); + + p[1] = p[7] + 6; + *data->packet += p[1]; + } + + return PLUGIN_RET_OK; } int plugin_init(struct pluginfuncs *funcs) { - return ((p = funcs)) ? 1 : 0; + return ((f = funcs)) ? 1 : 0; } diff --git a/autothrottle.c b/autothrottle.c index 8f81776..cd42365 100644 --- a/autothrottle.c +++ b/autothrottle.c @@ -13,110 +13,146 @@ * throttle=no */ -char const *cvs_id = "$Id: autothrottle.c,v 1.15 2005/10/11 07:59:09 bodea Exp $"; +char const *cvs_id = "$Id: autothrottle.c,v 1.16 2005/10/11 09:04:53 bodea Exp $"; int plugin_api_version = PLUGIN_API_VERSION; -struct pluginfuncs *p; +static struct pluginfuncs *f = 0; #define THROTTLE_KEY "lcp:interface-config" int plugin_radius_response(struct param_radius_response *data) { - if (!strncmp(data->key, THROTTLE_KEY, sizeof(THROTTLE_KEY) - 1)) + if (!strncmp(data->key, THROTTLE_KEY, sizeof(THROTTLE_KEY) - 1)) + { + char *sp = strchr(data->value, ' '); + char type; + int rate; + + if (!sp || sp - data->value < 4 || + strncmp("service-policy", data->value, sp - data->value)) + return PLUGIN_RET_OK; + + while (*sp == ' ') sp++; + data->value = sp; + + if (!(sp = strchr(data->value, ' ')) || + (strncmp("input", data->value, sp - data->value) && + strncmp("output", data->value, sp - data->value))) { - char *sp = strchr(data->value, ' '); - char type; - int rate; - - if (!sp || sp - data->value < 4 || - strncmp("service-policy", data->value, sp - data->value)) - return PLUGIN_RET_OK; - - while (*sp == ' ') sp++; - data->value = sp; - - if (!(sp = strchr(data->value, ' ')) || - (strncmp("input", data->value, sp - data->value) && - strncmp("output", data->value, sp - data->value))) - { - p->log(3, p->get_id_by_session(data->s), data->s->tunnel, - " Not throttling user (invalid type %.*s)\n", - sp - data->value, data->value); - - return PLUGIN_RET_OK; - } - - type = *data->value; - - while (*sp == ' ') sp++; - data->value = sp; - - if ((rate = strtol(data->value, &sp, 10)) < 0 || *sp) - { - p->log(3, p->get_id_by_session(data->s), data->s->tunnel, - " Not throttling user (invalid rate %s)\n", - data->value); - - return PLUGIN_RET_OK; - } - - if (type == 'i') - { - data->s->throttle_in = rate; - p->log(3, p->get_id_by_session(data->s), data->s->tunnel, - " Throttling user input to %dkb/s\n", - rate); - } - else - { - data->s->throttle_out = rate; - p->log(3, p->get_id_by_session(data->s), data->s->tunnel, - " Throttling user output to %dkb/s\n", - rate); - } + f->log(3, f->get_id_by_session(data->s), data->s->tunnel, + " Not throttling user (invalid type %.*s)\n", + sp - data->value, data->value); + + return PLUGIN_RET_OK; + } + + type = *data->value; + + while (*sp == ' ') sp++; + data->value = sp; + + if ((rate = strtol(data->value, &sp, 10)) < 0 || *sp) + { + f->log(3, f->get_id_by_session(data->s), data->s->tunnel, + " Not throttling user (invalid rate %s)\n", + data->value); + + return PLUGIN_RET_OK; } - if (!strcmp(data->key, "throttle")) + if (type == 'i') { - char *e; - int rate; - - if ((rate = strtol(data->value, &e, 10)) < 0 || *e) - { - rate = -1; - if (!strcmp(data->value, "yes")) - { - unsigned long *ts = p->getconfig("throttle_speed", UNSIGNED_LONG); - if (ts) - rate = *ts; - } - else if (!strcmp(data->value, "no")) - rate = 0; - } - - if (rate < 0) - return PLUGIN_RET_OK; - - if (rate) - p->log(3, p->get_id_by_session(data->s), data->s->tunnel, - " Throttling user to %dkb/s\n", rate); - else - p->log(3, p->get_id_by_session(data->s), data->s->tunnel, - " Not throttling user\n"); - - data->s->throttle_in = data->s->throttle_out = rate; + data->s->throttle_in = rate; + f->log(3, f->get_id_by_session(data->s), data->s->tunnel, + " Throttling user input to %dkb/s\n", rate); } + else + { + data->s->throttle_out = rate; + f->log(3, f->get_id_by_session(data->s), data->s->tunnel, + " Throttling user output to %dkb/s\n", rate); + } + } + else if (!strcmp(data->key, "throttle")) + { + char *e; + int rate; + + if ((rate = strtol(data->value, &e, 10)) < 0 || *e) + { + rate = -1; + if (!strcmp(data->value, "yes")) + { + unsigned long *ts = f->getconfig("throttle_speed", UNSIGNED_LONG); + if (ts) + rate = *ts; + } + else if (!strcmp(data->value, "no")) + rate = 0; + } + + if (rate < 0) + return PLUGIN_RET_OK; - return PLUGIN_RET_OK; + if (rate) + f->log(3, f->get_id_by_session(data->s), data->s->tunnel, + " Throttling user to %dkb/s\n", rate); + else + f->log(3, f->get_id_by_session(data->s), data->s->tunnel, + " Not throttling user\n"); + + data->s->throttle_in = data->s->throttle_out = rate; + } + + return PLUGIN_RET_OK; } int plugin_radius_reset(struct param_radius_reset *data) { - p->throttle(p->get_id_by_session(data->s), 0, 0); - return PLUGIN_RET_OK; + f->throttle(f->get_id_by_session(data->s), 0, 0); + return PLUGIN_RET_OK; +} + +int plugin_radius_account(struct param_radius_account *data) +{ + if (data->s->throttle_in || data->s->throttle_out) + { + uint8_t *p = *data->packet; + int i = 1; + + if (data->s->throttle_in) + { + *p = 26; // vendor-specific + *(uint32_t *) (p + 2) = htonl(9); // Cisco + p[6] = 1; // Cisco-AVPair + p[7] = 2 + sprintf((char *) p + 8, + "lcp:interface-config#%d=service-policy input %d", i++, + data->s->throttle_in); + + p[1] = p[7] + 6; + p += p[1]; + } + + if (data->s->throttle_out) + { + *p = 26; // vendor-specific + *(uint32_t *) (p + 2) = htonl(9); // Cisco + p[6] = 1; // Cisco-AVPair + p[7] = 2 + sprintf((char *) p + 8, + "lcp:interface-config#%d=service-policy output %d", i++, + data->s->throttle_out); + + p[1] = p[7] + 6; + p += p[1]; + } + + *data->packet = p; + } + + return PLUGIN_RET_OK; } int plugin_init(struct pluginfuncs *funcs) { - return ((p = funcs)) ? 1 : 0; + return ((f = funcs)) ? 1 : 0; } diff --git a/garden.c b/garden.c index b352e7b..e445d41 100644 --- a/garden.c +++ b/garden.c @@ -9,35 +9,35 @@ /* walled garden */ -char const *cvs_id = "$Id: garden.c,v 1.23 2005/06/02 11:32:30 bodea Exp $"; +char const *cvs_id = "$Id: garden.c,v 1.24 2005/10/11 09:04:53 bodea Exp $"; int plugin_api_version = PLUGIN_API_VERSION; -static struct pluginfuncs *p = 0; +static struct pluginfuncs *f = 0; static int iam_master = 0; // We're all slaves! Slaves I tell you! char *up_commands[] = { - "iptables -t nat -N garden >/dev/null 2>&1", // Create a chain that all gardened users will go through - "iptables -t nat -F garden", - ". " PLUGINCONF "/build-garden", // Populate with site-specific DNAT rules - "iptables -t nat -N garden_users >/dev/null 2>&1", // Empty chain, users added/removed by garden_session - "iptables -t nat -F garden_users", - "iptables -t nat -A PREROUTING -j garden_users", // DNAT any users on the garden_users chain - "sysctl -w net.ipv4.ip_conntrack_max=512000 >/dev/null", // lots of entries - NULL, + "iptables -t nat -N garden >/dev/null 2>&1", // Create a chain that all gardened users will go through + "iptables -t nat -F garden", + ". " PLUGINCONF "/build-garden", // Populate with site-specific DNAT rules + "iptables -t nat -N garden_users >/dev/null 2>&1", // Empty chain, users added/removed by garden_session + "iptables -t nat -F garden_users", + "iptables -t nat -A PREROUTING -j garden_users", // DNAT any users on the garden_users chain + "sysctl -w net.ipv4.ip_conntrack_max=512000 >/dev/null", // lots of entries + NULL, }; char *down_commands[] = { - "iptables -t nat -F PREROUTING", - "iptables -t nat -F garden_users", - "iptables -t nat -X garden_users", - "iptables -t nat -F garden", - "iptables -t nat -X garden", - "rmmod iptable_nat", // Should also remove ip_conntrack, but + "iptables -t nat -F PREROUTING", + "iptables -t nat -F garden_users", + "iptables -t nat -X garden_users", + "iptables -t nat -F garden", + "iptables -t nat -X garden", + "rmmod iptable_nat", // Should also remove ip_conntrack, but // doing so can take hours... literally. // If a master is re-started as a slave, // either rmmod manually, or reboot. - NULL, + NULL, }; #define F_UNGARDEN 0 @@ -48,234 +48,249 @@ int garden_session(sessiont *s, int flag, char *newuser); int plugin_post_auth(struct param_post_auth *data) { - // Ignore if user authentication was successful - if (data->auth_allowed) return PLUGIN_RET_OK; - - p->log(3, p->get_id_by_session(data->s), data->s->tunnel, "Walled Garden allowing login\n"); - data->auth_allowed = 1; - data->s->walled_garden = 1; + // Ignore if user authentication was successful + if (data->auth_allowed) return PLUGIN_RET_OK; + + f->log(3, f->get_id_by_session(data->s), data->s->tunnel, + "Walled Garden allowing login\n"); + + data->auth_allowed = 1; + data->s->walled_garden = 1; + return PLUGIN_RET_OK; } int plugin_new_session(struct param_new_session *data) { - if (!iam_master) - return PLUGIN_RET_OK; // Slaves don't do walled garden processing. + if (!iam_master) + return PLUGIN_RET_OK; // Slaves don't do walled garden processing. - if (data->s->walled_garden) - garden_session(data->s, F_GARDEN, 0); + if (data->s->walled_garden) + garden_session(data->s, F_GARDEN, 0); - return PLUGIN_RET_OK; + return PLUGIN_RET_OK; } int plugin_kill_session(struct param_new_session *data) { - if (!iam_master) - return PLUGIN_RET_OK; // Slaves don't do walled garden processing. + if (!iam_master) + return PLUGIN_RET_OK; // Slaves don't do walled garden processing. - if (data->s->walled_garden) - garden_session(data->s, F_CLEANUP, 0); + if (data->s->walled_garden) + garden_session(data->s, F_CLEANUP, 0); - return PLUGIN_RET_OK; + return PLUGIN_RET_OK; } char *plugin_control_help[] = { - " garden USER|SID Put user into the walled garden", - " ungarden SID [USER] Release session from garden", - 0 + " garden USER|SID Put user into the walled garden", + " ungarden SID [USER] Release session from garden", + 0 }; int plugin_control(struct param_control *data) { - sessionidt session; - sessiont *s = 0; - int flag; - char *end; + sessionidt session; + sessiont *s = 0; + int flag; + char *end; - if (data->argc < 1) - return PLUGIN_RET_OK; + if (data->argc < 1) + return PLUGIN_RET_OK; - if (strcmp(data->argv[0], "garden") && strcmp(data->argv[0], "ungarden")) - return PLUGIN_RET_OK; // not for us + if (strcmp(data->argv[0], "garden") && strcmp(data->argv[0], "ungarden")) + return PLUGIN_RET_OK; // not for us - if (!iam_master) - return PLUGIN_RET_NOTMASTER; + if (!iam_master) + return PLUGIN_RET_NOTMASTER; - flag = data->argv[0][0] == 'g' ? F_GARDEN : F_UNGARDEN; + flag = data->argv[0][0] == 'g' ? F_GARDEN : F_UNGARDEN; - if (data->argc < 2 || data->argc > 3 || (data->argc > 2 && flag == F_GARDEN)) - { - data->response = NSCTL_RES_ERR; - data->additional = flag == F_GARDEN - ? "requires username or session id" - : "requires session id and optional username"; + if (data->argc < 2 || data->argc > 3 || (data->argc > 2 && flag == F_GARDEN)) + { + data->response = NSCTL_RES_ERR; + data->additional = flag == F_GARDEN + ? "requires username or session id" + : "requires session id and optional username"; - return PLUGIN_RET_STOP; - } + return PLUGIN_RET_STOP; + } - if (!(session = strtol(data->argv[1], &end, 10)) || *end) - { - if (flag) - session = p->get_session_by_username(data->argv[1]); - else - session = 0; // can't ungarden by username - } + if (!(session = strtol(data->argv[1], &end, 10)) || *end) + { + if (flag) + session = f->get_session_by_username(data->argv[1]); + else + session = 0; // can't ungarden by username + } - if (session) - s = p->get_session_by_id(session); + if (session) + s = f->get_session_by_id(session); - if (!s || !s->ip) - { - data->response = NSCTL_RES_ERR; - data->additional = "session not found"; - return PLUGIN_RET_STOP; - } + if (!s || !s->ip) + { + data->response = NSCTL_RES_ERR; + data->additional = "session not found"; + return PLUGIN_RET_STOP; + } - if (s->walled_garden == flag) - { - data->response = NSCTL_RES_ERR; - data->additional = flag ? "already in walled garden" : "not in walled garden"; - return PLUGIN_RET_STOP; - } + if (s->walled_garden == flag) + { + data->response = NSCTL_RES_ERR; + data->additional = flag ? "already in walled garden" : "not in walled garden"; + return PLUGIN_RET_STOP; + } - garden_session(s, flag, data->argc > 2 ? data->argv[2] : 0); - p->session_changed(session); + garden_session(s, flag, data->argc > 2 ? data->argv[2] : 0); + f->session_changed(session); - data->response = NSCTL_RES_OK; - data->additional = 0; + data->response = NSCTL_RES_OK; + data->additional = 0; - return PLUGIN_RET_STOP; + return PLUGIN_RET_STOP; } int plugin_become_master(void) { - int i; - iam_master = 1; // We just became the master. Wow! + int i; + iam_master = 1; // We just became the master. Wow! - for (i = 0; up_commands[i] && *up_commands[i]; i++) - { - p->log(3, 0, 0, "Running %s\n", up_commands[i]); - system(up_commands[i]); - } + for (i = 0; up_commands[i] && *up_commands[i]; i++) + { + f->log(3, 0, 0, "Running %s\n", up_commands[i]); + system(up_commands[i]); + } - return PLUGIN_RET_OK; + return PLUGIN_RET_OK; } // Called for each active session after becoming master int plugin_new_session_master(sessiont *s) { - if (s->walled_garden) - garden_session(s, F_GARDEN, 0); + if (s->walled_garden) + garden_session(s, F_GARDEN, 0); - return PLUGIN_RET_OK; + return PLUGIN_RET_OK; } int garden_session(sessiont *s, int flag, char *newuser) { - char cmd[2048]; - sessionidt sess; + char cmd[2048]; + sessionidt sess; + + if (!s) return 0; + if (!s->opened) return 0; + + sess = f->get_id_by_session(s); + if (flag == F_GARDEN) + { + f->log(2, sess, s->tunnel, "Garden user %s (%s)\n", s->user, + f->fmtaddr(htonl(s->ip), 0)); + + snprintf(cmd, sizeof(cmd), + "iptables -t nat -A garden_users -s %s -j garden", + f->fmtaddr(htonl(s->ip), 0)); + + f->log(3, sess, s->tunnel, "%s\n", cmd); + system(cmd); + s->walled_garden = 1; + } + else + { + sessionidt other; + int count = 40; + + // Normal User + f->log(2, sess, s->tunnel, "Un-Garden user %s (%s)\n", s->user, f->fmtaddr(htonl(s->ip), 0)); + if (newuser) + { + snprintf(s->user, MAXUSER, "%s", newuser); + f->log(2, sess, s->tunnel, " Setting username to %s\n", s->user); + } - if (!s) return 0; - if (!s->opened) return 0; + // Kick off any duplicate usernames + // but make sure not to kick off ourself + if (s->ip && !s->die && (other = f->get_session_by_username(s->user)) && + s != f->get_session_by_id(other)) + { + f->sessionkill(other, + "Duplicate session when user released from walled garden"); + } + + /* Clean up counters */ + s->pin = s->pout = 0; + s->cin = s->cout = 0; + s->cin_delta = s->cout_delta = 0; + s->cin_wrap = s->cout_wrap = 0; - sess = p->get_id_by_session(s); - if (flag == F_GARDEN) + snprintf(cmd, sizeof(cmd), + "iptables -t nat -D garden_users -s %s -j garden", + f->fmtaddr(htonl(s->ip), 0)); + + f->log(3, sess, s->tunnel, "%s\n", cmd); + while (--count) { - p->log(2, sess, s->tunnel, "Garden user %s (%s)\n", s->user, p->fmtaddr(htonl(s->ip), 0)); - snprintf(cmd, sizeof(cmd), "iptables -t nat -A garden_users -s %s -j garden", p->fmtaddr(htonl(s->ip), 0)); - p->log(3, sess, s->tunnel, "%s\n", cmd); - system(cmd); - s->walled_garden = 1; + int status = system(cmd); + if (WEXITSTATUS(status) != 0) break; } - else + + s->walled_garden = 0; + + if (flag != F_CLEANUP) { - sessionidt other; - int count = 40; - - // Normal User - p->log(2, sess, s->tunnel, "Un-Garden user %s (%s)\n", s->user, p->fmtaddr(htonl(s->ip), 0)); - if (newuser) - { - snprintf(s->user, MAXUSER, "%s", newuser); - p->log(2, sess, s->tunnel, " Setting username to %s\n", s->user); - } - - // Kick off any duplicate usernames - // but make sure not to kick off ourself - if (s->ip && !s->die && (other = p->get_session_by_username(s->user)) && s != p->get_session_by_id(other)) { - p->sessionkill(other, "Duplicate session when user released from walled garden"); - } - /* Clean up counters */ - s->pin = s->pout = 0; - s->cin = s->cout = 0; - s->cin_delta = s->cout_delta = 0; - s->cin_wrap = s->cout_wrap = 0; - - snprintf(cmd, sizeof(cmd), "iptables -t nat -D garden_users -s %s -j garden", p->fmtaddr(htonl(s->ip), 0)); - p->log(3, sess, s->tunnel, "%s\n", cmd); - while (--count) - { - int status = system(cmd); - if (WEXITSTATUS(status) != 0) break; - } - - s->walled_garden = 0; - - if (flag != F_CLEANUP) - { - /* OK, we're up! */ - uint16_t r = p->radiusnew(p->get_id_by_session(s)); - if (r) p->radiussend(r, RADIUSSTART); - } + /* OK, we're up! */ + uint16_t r = f->radiusnew(f->get_id_by_session(s)); + if (r) f->radiussend(r, RADIUSSTART); } + } - return 1; + return 1; } int plugin_init(struct pluginfuncs *funcs) { - FILE *tables; - int found_nat = 0; + FILE *tables; + int found_nat = 0; - if (!funcs) - return 0; + if (!funcs) + return 0; - p = funcs; + f = funcs; - if ((tables = fopen("/proc/net/ip_tables_names", "r"))) - { - char buf[1024]; - while (fgets(buf, sizeof(buf), tables) && !found_nat) - found_nat = !strcmp(buf, "nat\n"); + if ((tables = fopen("/proc/net/ip_tables_names", "r"))) + { + char buf[1024]; + while (fgets(buf, sizeof(buf), tables) && !found_nat) + found_nat = !strcmp(buf, "nat\n"); - fclose(tables); - } + fclose(tables); + } - /* master killed/crashed? */ - if (found_nat) + /* master killed/crashed? */ + if (found_nat) + { + int i; + for (i = 0; down_commands[i] && *down_commands[i]; i++) { - int i; - for (i = 0; down_commands[i] && *down_commands[i]; i++) - { - p->log(3, 0, 0, "Running %s\n", down_commands[i]); - system(down_commands[i]); - } + f->log(3, 0, 0, "Running %s\n", down_commands[i]); + system(down_commands[i]); } + } - return 1; + return 1; } void plugin_done() { - int i; + int i; - if (!iam_master) // Never became master. nothing to do. - return; + if (!iam_master) // Never became master. nothing to do. + return; - for (i = 0; down_commands[i] && *down_commands[i]; i++) - { - p->log(3, 0, 0, "Running %s\n", down_commands[i]); - system(down_commands[i]); - } + for (i = 0; down_commands[i] && *down_commands[i]; i++) + { + f->log(3, 0, 0, "Running %s\n", down_commands[i]); + system(down_commands[i]); + } } diff --git a/l2tpns.c b/l2tpns.c index ec2bd17..6d1bb54 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -4,7 +4,7 @@ // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced // vim: sw=8 ts=8 -char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.143 2005/10/11 07:06:56 bodea Exp $"; +char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.144 2005/10/11 09:04:53 bodea Exp $"; #include #include @@ -162,6 +162,7 @@ static char *plugin_functions[] = { "plugin_control", "plugin_radius_response", "plugin_radius_reset", + "plugin_radius_account", "plugin_become_master", "plugin_new_session_master", }; diff --git a/plugin.h b/plugin.h index faf3a5e..a57d700 100644 --- a/plugin.h +++ b/plugin.h @@ -6,18 +6,19 @@ enum { - PLUGIN_PRE_AUTH = 1, - PLUGIN_POST_AUTH, - PLUGIN_PACKET_RX, - PLUGIN_PACKET_TX, - PLUGIN_TIMER, - PLUGIN_NEW_SESSION, - PLUGIN_KILL_SESSION, - PLUGIN_CONTROL, - PLUGIN_RADIUS_RESPONSE, - PLUGIN_RADIUS_RESET, - PLUGIN_BECOME_MASTER, - PLUGIN_NEW_SESSION_MASTER, + PLUGIN_PRE_AUTH = 1, + PLUGIN_POST_AUTH, + PLUGIN_PACKET_RX, + PLUGIN_PACKET_TX, + PLUGIN_TIMER, + PLUGIN_NEW_SESSION, + PLUGIN_KILL_SESSION, + PLUGIN_CONTROL, + PLUGIN_RADIUS_RESPONSE, + PLUGIN_RADIUS_RESET, + PLUGIN_RADIUS_ACCOUNT, + PLUGIN_BECOME_MASTER, + PLUGIN_NEW_SESSION_MASTER, }; #define PLUGIN_RET_ERROR 0 @@ -27,95 +28,102 @@ enum struct pluginfuncs { - void (*log)(int level, sessionidt s, tunnelidt t, const char *format, ...); - void (*log_hex)(int level, const char *title, const uint8_t *data, int maxsize); - char *(*fmtaddr)(in_addr_t addr, int n); - sessionidt (*get_session_by_username)(char *username); - sessiont *(*get_session_by_id)(sessionidt s); - sessionidt (*get_id_by_session)(sessiont *s); - uint16_t (*radiusnew)(sessionidt s); - void (*radiussend)(uint16_t r, uint8_t state); - void *(*getconfig)(char *key, enum config_typet type); - void (*sessionshutdown)(sessionidt s, char *reason, int result, int error); - void (*sessionkill)(sessionidt s, char *reason); - void (*throttle)(sessionidt s, int rate_in, int rate_out); - int (*session_changed)(int sid); + void (*log)(int level, sessionidt s, tunnelidt t, const char *format, ...); + void (*log_hex)(int level, const char *title, const uint8_t *data, int maxsize); + char *(*fmtaddr)(in_addr_t addr, int n); + sessionidt (*get_session_by_username)(char *username); + sessiont *(*get_session_by_id)(sessionidt s); + sessionidt (*get_id_by_session)(sessiont *s); + uint16_t (*radiusnew)(sessionidt s); + void (*radiussend)(uint16_t r, uint8_t state); + void *(*getconfig)(char *key, enum config_typet type); + void (*sessionshutdown)(sessionidt s, char *reason, int result, int error); + void (*sessionkill)(sessionidt s, char *reason); + void (*throttle)(sessionidt s, int rate_in, int rate_out); + int (*session_changed)(int sid); }; struct param_pre_auth { - tunnelt *t; - sessiont *s; - char *username; - char *password; - int protocol; - int continue_auth; + tunnelt *t; + sessiont *s; + char *username; + char *password; + int protocol; + int continue_auth; }; struct param_post_auth { - tunnelt *t; - sessiont *s; - char *username; - short auth_allowed; - int protocol; + tunnelt *t; + sessiont *s; + char *username; + short auth_allowed; + int protocol; }; struct param_packet_rx { - tunnelt *t; - sessiont *s; - char *buf; - int len; + tunnelt *t; + sessiont *s; + char *buf; + int len; }; struct param_packet_tx { - tunnelt *t; - sessiont *s; - char *buf; - int len; + tunnelt *t; + sessiont *s; + char *buf; + int len; }; struct param_timer { - time_t time_now; + time_t time_now; }; struct param_control { - int iam_master; - int argc; - char **argv; - // output - int response; - char *additional; + int iam_master; + int argc; + char **argv; + // output + int response; + char *additional; }; struct param_new_session { - tunnelt *t; - sessiont *s; + tunnelt *t; + sessiont *s; }; struct param_kill_session { - tunnelt *t; - sessiont *s; + tunnelt *t; + sessiont *s; }; struct param_radius_response { - tunnelt *t; - sessiont *s; - char *key; - char *value; + tunnelt *t; + sessiont *s; + char *key; + char *value; }; struct param_radius_reset { - tunnelt *t; - sessiont *s; + tunnelt *t; + sessiont *s; +}; + +struct param_radius_account +{ + tunnelt *t; + sessiont *s; + uint8_t **packet; }; #endif /* __PLUGIN_H__ */ diff --git a/radius.c b/radius.c index 0059fcc..55aa6cb 100644 --- a/radius.c +++ b/radius.c @@ -1,6 +1,6 @@ // L2TPNS Radius Stuff -char const *cvs_id_radius = "$Id: radius.c,v 1.43 2005/10/11 02:27:40 foonly Exp $"; +char const *cvs_id_radius = "$Id: radius.c,v 1.44 2005/10/11 09:04:53 bodea Exp $"; #include #include @@ -304,18 +304,11 @@ void radiussend(uint16_t r, uint8_t state) p[1] = 6; *(uint32_t *) (p + 2) = htonl(session[s].cout_wrap); p += p[1]; - } - - if (session[s].snoop_ip && session[s].snoop_port) - { - *p = 26; // vendor-specific - *(uint32_t *) (p + 2) = htonl(9); // Cisco - p[6] = 1; // Cisco-AVPair - p[7] = 2 + sprintf((char *) p + 8, "intercept=%s:%d", - fmtaddr(session[s].snoop_ip, 0), session[s].snoop_port); - p[1] = p[7] + 6; - p += p[1]; + { + struct param_radius_account acct = { &tunnel[session[s].tunnel], &session[s], &p }; + run_plugins(PLUGIN_RADIUS_ACCOUNT, &acct); + } } } } diff --git a/sessionctl.c b/sessionctl.c index 1b6d7f7..cc6a113 100644 --- a/sessionctl.c +++ b/sessionctl.c @@ -5,10 +5,10 @@ /* session control */ -char const *cvs_id = "$Id: sessionctl.c,v 1.3 2005/06/28 14:48:28 bodea Exp $"; +char const *cvs_id = "$Id: sessionctl.c,v 1.4 2005/10/11 09:04:53 bodea Exp $"; int plugin_api_version = PLUGIN_API_VERSION; -static struct pluginfuncs *p = 0; +static struct pluginfuncs *f = 0; char *plugin_control_help[] = { " drop USER|SID [REASON] Shutdown user session", @@ -40,10 +40,10 @@ int plugin_control(struct param_control *data) } if (!(session = strtol(data->argv[1], &end, 10)) || *end) - session = p->get_session_by_username(data->argv[1]); + session = f->get_session_by_username(data->argv[1]); if (session) - s = p->get_session_by_id(session); + s = f->get_session_by_id(session); if (!s || !s->ip) { @@ -58,9 +58,9 @@ int plugin_control(struct param_control *data) reason = "Requested by administrator."; if (data->argv[0][0] == 'd') - p->sessionshutdown(session, reason, 3, 0); + f->sessionshutdown(session, reason, 3, 0); else - p->sessionkill(session, reason); + f->sessionkill(session, reason); data->response = NSCTL_RES_OK; data->additional = 0; @@ -70,5 +70,5 @@ int plugin_control(struct param_control *data) int plugin_init(struct pluginfuncs *funcs) { - return ((p = funcs)) ? 1 : 0; + return ((f = funcs)) ? 1 : 0; } diff --git a/setrxspeed.c b/setrxspeed.c index fcb129d..2e9e663 100644 --- a/setrxspeed.c +++ b/setrxspeed.c @@ -4,34 +4,38 @@ /* fudge up session rx speed if not set */ -char const *cvs_id = "$Id: setrxspeed.c,v 1.3 2004/11/17 08:23:35 bodea Exp $"; +char const *cvs_id = "$Id: setrxspeed.c,v 1.4 2005/10/11 09:04:53 bodea Exp $"; int plugin_api_version = PLUGIN_API_VERSION; -static struct pluginfuncs *p = 0; +static struct pluginfuncs *f = 0; int plugin_post_auth(struct param_post_auth *data) { - if (!data->auth_allowed) return PLUGIN_RET_OK; - - if (!data->s->rx_connect_speed) - { - switch (data->s->tx_connect_speed) - { - case 256 : - data->s->rx_connect_speed = 64; - break; - case 512 : - data->s->rx_connect_speed = 128; - break; - case 1500 : - data->s->rx_connect_speed = 256; - break; - } - } - return PLUGIN_RET_OK; + if (!data->auth_allowed) + return PLUGIN_RET_OK; + + if (data->s->rx_connect_speed) + return PLUGIN_RET_OK; + + switch (data->s->tx_connect_speed) + { + case 256: + data->s->rx_connect_speed = 64; + break; + + case 512: + data->s->rx_connect_speed = 128; + break; + + case 1500: + data->s->rx_connect_speed = 256; + break; + } + + return PLUGIN_RET_OK; } int plugin_init(struct pluginfuncs *funcs) { - return ((p = funcs)) ? 1 : 0; + return ((f = funcs)) ? 1 : 0; } diff --git a/snoopctl.c b/snoopctl.c index 0bb46da..6c79087 100644 --- a/snoopctl.c +++ b/snoopctl.c @@ -5,118 +5,118 @@ /* snoop control */ -char const *cvs_id = "$Id: snoopctl.c,v 1.6 2005/10/11 07:59:09 bodea Exp $"; +char const *cvs_id = "$Id: snoopctl.c,v 1.7 2005/10/11 09:04:53 bodea Exp $"; int plugin_api_version = PLUGIN_API_VERSION; -static struct pluginfuncs *p = 0; +static struct pluginfuncs *f = 0; char *plugin_control_help[] = { - " snoop USER|SID IP PORT Intercept user traffic", - " unsnoop USER|SID Stop intercepting user", - 0 + " snoop USER|SID IP PORT Intercept user traffic", + " unsnoop USER|SID Stop intercepting user", + 0 }; int plugin_control(struct param_control *data) { - sessionidt session; - sessiont *s = 0; - int flag; - char *end; + sessionidt session; + sessiont *s = 0; + int flag; + char *end; - if (data->argc < 1) - return PLUGIN_RET_OK; + if (data->argc < 1) + return PLUGIN_RET_OK; - if (strcmp(data->argv[0], "snoop") && strcmp(data->argv[0], "unsnoop")) - return PLUGIN_RET_OK; // not for us + if (strcmp(data->argv[0], "snoop") && strcmp(data->argv[0], "unsnoop")) + return PLUGIN_RET_OK; // not for us - if (!data->iam_master) - return PLUGIN_RET_NOTMASTER; + if (!data->iam_master) + return PLUGIN_RET_NOTMASTER; - flag = data->argv[0][0] != 'u'; + flag = data->argv[0][0] != 'u'; - if (flag) + if (flag) + { + if (data->argc != 4) { - if (data->argc != 4) - { - data->response = NSCTL_RES_ERR; - data->additional = "requires username or session id and host, port"; - return PLUGIN_RET_STOP; - } + data->response = NSCTL_RES_ERR; + data->additional = "requires username or session id and host, port"; + return PLUGIN_RET_STOP; } - else + } + else + { + if (data->argc != 2) { - if (data->argc != 2) - { - data->response = NSCTL_RES_ERR; - data->additional = "requires username or session id"; - return PLUGIN_RET_STOP; - } + data->response = NSCTL_RES_ERR; + data->additional = "requires username or session id"; + return PLUGIN_RET_STOP; } + } - if (!(session = strtol(data->argv[1], &end, 10)) || *end) - session = p->get_session_by_username(data->argv[1]); + if (!(session = strtol(data->argv[1], &end, 10)) || *end) + session = f->get_session_by_username(data->argv[1]); - if (session) - s = p->get_session_by_id(session); + if (session) + s = f->get_session_by_id(session); - if (!s || !s->ip) + if (!s || !s->ip) + { + data->response = NSCTL_RES_ERR; + data->additional = "session not found"; + return PLUGIN_RET_STOP; + } + + if (flag) + { + in_addr_t ip = inet_addr(data->argv[2]); + uint16_t port = atoi(data->argv[3]); + + if (!ip || ip == INADDR_NONE) { - data->response = NSCTL_RES_ERR; - data->additional = "session not found"; - return PLUGIN_RET_STOP; + data->response = NSCTL_RES_ERR; + data->additional = "invalid ip address"; + return PLUGIN_RET_STOP; } - if (flag) + if (!port) { - in_addr_t ip = inet_addr(data->argv[2]); - uint16_t port = atoi(data->argv[3]); - - if (!ip || ip == INADDR_NONE) - { - data->response = NSCTL_RES_ERR; - data->additional = "invalid ip address"; - return PLUGIN_RET_STOP; - } - - if (!port) - { - data->response = NSCTL_RES_ERR; - data->additional = "invalid port"; - return PLUGIN_RET_STOP; - } - - if (ip == s->snoop_ip && port == s->snoop_port) - { - data->response = NSCTL_RES_ERR; - data->additional = "already intercepted"; - return PLUGIN_RET_STOP; - } - - s->snoop_ip = ip; - s->snoop_port = port; + data->response = NSCTL_RES_ERR; + data->additional = "invalid port"; + return PLUGIN_RET_STOP; } - else + + if (ip == s->snoop_ip && port == s->snoop_port) { - if (!s->snoop_ip) - { - data->response = NSCTL_RES_ERR; - data->additional = "not intercepted"; - return PLUGIN_RET_STOP; - } - - s->snoop_ip = 0; - s->snoop_port = 0; + data->response = NSCTL_RES_ERR; + data->additional = "already intercepted"; + return PLUGIN_RET_STOP; } - p->session_changed(session); + s->snoop_ip = ip; + s->snoop_port = port; + } + else + { + if (!s->snoop_ip) + { + data->response = NSCTL_RES_ERR; + data->additional = "not intercepted"; + return PLUGIN_RET_STOP; + } - data->response = NSCTL_RES_OK; - data->additional = 0; + s->snoop_ip = 0; + s->snoop_port = 0; + } - return PLUGIN_RET_STOP; + f->session_changed(session); + + data->response = NSCTL_RES_OK; + data->additional = 0; + + return PLUGIN_RET_STOP; } int plugin_init(struct pluginfuncs *funcs) { - return ((p = funcs)) ? 1 : 0; + return ((f = funcs)) ? 1 : 0; } diff --git a/stripdomain.c b/stripdomain.c index 37bb53e..748efc9 100644 --- a/stripdomain.c +++ b/stripdomain.c @@ -4,28 +4,28 @@ /* strip domain part of username before sending RADIUS requests */ -char const *cvs_id = "$Id: stripdomain.c,v 1.7 2004/11/29 02:17:18 bodea Exp $"; +char const *cvs_id = "$Id: stripdomain.c,v 1.8 2005/10/11 09:04:53 bodea Exp $"; int plugin_api_version = PLUGIN_API_VERSION; -static struct pluginfuncs *p = 0; +static struct pluginfuncs *f = 0; int plugin_pre_auth(struct param_pre_auth *data) { - char *x; + char *p; - if (!data->continue_auth) return PLUGIN_RET_STOP; + if (!data->continue_auth) return PLUGIN_RET_STOP; - // Strip off @domain - if ((x = strchr(data->username, '@'))) - { - p->log(3, 0, 0, "Stripping off trailing domain name \"%s\"\n", x); - *x = 0; - } + // Strip off @domain + if ((p = strchr(data->username, '@'))) + { + f->log(3, 0, 0, "Stripping off trailing domain name \"%s\"\n", p); + *p = 0; + } - return PLUGIN_RET_OK; + return PLUGIN_RET_OK; } int plugin_init(struct pluginfuncs *funcs) { - return ((p = funcs)) ? 1 : 0; + return ((f = funcs)) ? 1 : 0; } diff --git a/throttlectl.c b/throttlectl.c index f0106f8..0f0b055 100644 --- a/throttlectl.c +++ b/throttlectl.c @@ -5,131 +5,131 @@ /* throttle control */ -char const *cvs_id = "$Id: throttlectl.c,v 1.8 2005/10/11 07:59:09 bodea Exp $"; +char const *cvs_id = "$Id: throttlectl.c,v 1.9 2005/10/11 09:04:53 bodea Exp $"; int plugin_api_version = PLUGIN_API_VERSION; -static struct pluginfuncs *p = 0; +static struct pluginfuncs *f = 0; char *plugin_control_help[] = { - " throttle USER|SID [RATE|[in|out] RATE ...] Throttle user traffic", - " unthrottle USER|SID Stop throttling user", - 0 + " throttle USER|SID [RATE|[in|out] RATE ...] Throttle user traffic", + " unthrottle USER|SID Stop throttling user", + 0 }; int plugin_control(struct param_control *data) { - sessionidt session; - sessiont *s = 0; - int flag; - char *end; - int rate_in = 0; - int rate_out = 0; + sessionidt session; + sessiont *s = 0; + int flag; + char *end; + int rate_in = 0; + int rate_out = 0; - if (data->argc < 1) - return PLUGIN_RET_OK; + if (data->argc < 1) + return PLUGIN_RET_OK; - if (strcmp(data->argv[0], "throttle") - && strcmp(data->argv[0], "unthrottle")) - return PLUGIN_RET_OK; // not for us + if (strcmp(data->argv[0], "throttle") && + strcmp(data->argv[0], "unthrottle")) + return PLUGIN_RET_OK; // not for us - if (!data->iam_master) - return PLUGIN_RET_NOTMASTER; + if (!data->iam_master) + return PLUGIN_RET_NOTMASTER; - flag = data->argv[0][0] == 't'; + flag = data->argv[0][0] == 't'; - if (flag) + if (flag) + { + if (data->argc < 2 || data->argc > 6) { - if (data->argc < 2 || data->argc > 6) - { - data->response = NSCTL_RES_ERR; - data->additional = "requires username or session id and optional rate(s)"; - return PLUGIN_RET_STOP; - } + data->response = NSCTL_RES_ERR; + data->additional = "requires username or session id and optional rate(s)"; + return PLUGIN_RET_STOP; } - else + } + else + { + if (data->argc != 2) { - if (data->argc != 2) - { - data->response = NSCTL_RES_ERR; - data->additional = "requires username or session id"; - return PLUGIN_RET_STOP; - } + data->response = NSCTL_RES_ERR; + data->additional = "requires username or session id"; + return PLUGIN_RET_STOP; } + } - if (!(session = strtol(data->argv[1], &end, 10)) || *end) - session = p->get_session_by_username(data->argv[1]); + if (!(session = strtol(data->argv[1], &end, 10)) || *end) + session = f->get_session_by_username(data->argv[1]); - if (session) - s = p->get_session_by_id(session); + if (session) + s = f->get_session_by_id(session); - if (!s || !s->ip) + if (!s || !s->ip) + { + data->response = NSCTL_RES_ERR; + data->additional = "session not found"; + return PLUGIN_RET_STOP; + } + + if (flag) + { + rate_in = rate_out = -1; + if (data->argc == 2) { - data->response = NSCTL_RES_ERR; - data->additional = "session not found"; - return PLUGIN_RET_STOP; + unsigned long *rate = f->getconfig("throttle_speed", UNSIGNED_LONG); + rate_in = rate_out = *rate; } - - if (flag) + else if (data->argc == 3) { - rate_in = rate_out = -1; - if (data->argc == 2) + rate_in = rate_out = atoi(data->argv[2]); + } + else + { + int i; + for (i = 2; i < data->argc - 1; i += 2) + { + int len = strlen(data->argv[i]); + if (!strncmp(data->argv[i], "in", len)) { - unsigned long *rate = p->getconfig("throttle_speed", UNSIGNED_LONG); - rate_in = rate_out = *rate; + rate_in = atoi(data->argv[i+1]); } - else if (data->argc == 3) + else if (!strncmp(data->argv[i], "out", len)) { - rate_in = rate_out = atoi(data->argv[2]); + rate_out = atoi(data->argv[i+1]); } else { - int i; - for (i = 2; i < data->argc - 1; i += 2) - { - int len = strlen(data->argv[i]); - if (!strncmp(data->argv[i], "in", len)) - { - rate_in = atoi(data->argv[i+1]); - } - else if (!strncmp(data->argv[i], "out", len)) - { - rate_out = atoi(data->argv[i+1]); - } - else - { - data->response = NSCTL_RES_ERR; - data->additional = "invalid rate"; - return PLUGIN_RET_STOP; - } - } - } - - if (!rate_in || !rate_out) - { - data->response = NSCTL_RES_ERR; - data->additional = "invalid rate"; - return PLUGIN_RET_STOP; + data->response = NSCTL_RES_ERR; + data->additional = "invalid rate"; + return PLUGIN_RET_STOP; } + } } - if (rate_in != -1 && rate_in == s->throttle_in && - rate_out != -1 && rate_out == s->throttle_out) + if (!rate_in || !rate_out) { - data->response = NSCTL_RES_ERR; - data->additional = flag ? "already throttled" : "not throttled"; - return PLUGIN_RET_STOP; + data->response = NSCTL_RES_ERR; + data->additional = "invalid rate"; + return PLUGIN_RET_STOP; } + } + + if (rate_in != -1 && rate_in == s->throttle_in && + rate_out != -1 && rate_out == s->throttle_out) + { + data->response = NSCTL_RES_ERR; + data->additional = flag ? "already throttled" : "not throttled"; + return PLUGIN_RET_STOP; + } - p->throttle(session, rate_in, rate_out); - p->session_changed(session); + f->throttle(session, rate_in, rate_out); + f->session_changed(session); - data->response = NSCTL_RES_OK; - data->additional = 0; + data->response = NSCTL_RES_OK; + data->additional = 0; - return PLUGIN_RET_STOP; + return PLUGIN_RET_STOP; } int plugin_init(struct pluginfuncs *funcs) { - return ((p = funcs)) ? 1 : 0; + return ((f = funcs)) ? 1 : 0; } -- 2.20.1 From a97b3720a47fd5b8bfef901ddb2afd66a40fd5bc Mon Sep 17 00:00:00 2001 From: bodea Date: Wed, 12 Oct 2005 07:16:13 +0000 Subject: [PATCH 07/16] add intercept-capture script --- Changes | 3 ++ l2tpns.h | 4 +-- l2tpns.spec | 6 ++-- scripts/l2tpns-capture | 68 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 scripts/l2tpns-capture diff --git a/Changes b/Changes index aee33c3..f769dba 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,6 @@ +* Wed Oct 12 2005 Brendan O'Dea 2.1.10 +- Add scripts/l2tpns-capture. + * Tue Oct 11 2005 Brendan O'Dea 2.1.9 - Fix Calling-Station-Id in RADIUS accounting records (Slobodan Tomic). - Fix RADIUS authentication on DAE responses. diff --git a/l2tpns.h b/l2tpns.h index 9c0aa3f..1c768cf 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -1,5 +1,5 @@ // L2TPNS Global Stuff -// $Id: l2tpns.h,v 1.94 2005/10/11 07:06:56 bodea Exp $ +// $Id: l2tpns.h,v 1.95 2005/10/12 07:16:13 bodea Exp $ #ifndef __L2TPNS_H__ #define __L2TPNS_H__ @@ -15,7 +15,7 @@ #include #include -#define VERSION "2.1.9" +#define VERSION "2.1.10" // Limits #define MAXTUNNEL 500 // could be up to 65535 diff --git a/l2tpns.spec b/l2tpns.spec index e1cf5a5..3721f92 100644 --- a/l2tpns.spec +++ b/l2tpns.spec @@ -1,6 +1,6 @@ Summary: A high-speed clustered L2TP LNS Name: l2tpns -Version: 2.1.9 +Version: 2.1.10 Release: 1 Copyright: GPL Group: System Environment/Daemons @@ -43,5 +43,5 @@ rm -rf %{buildroot} %attr(644,root,root) /usr/share/man/man[58]/* %changelog -* Tue Oct 11 2005 Brendan O'Dea 2.1.9-1 -- 2.1.9 release, see /usr/share/doc/l2tpns-2.1.9/Changes +* Wed Oct 12 2005 Brendan O'Dea 2.1.10-1 +- 2.1.10 release, see /usr/share/doc/l2tpns-2.1.10/Changes diff --git a/scripts/l2tpns-capture b/scripts/l2tpns-capture new file mode 100644 index 0000000..d675518 --- /dev/null +++ b/scripts/l2tpns-capture @@ -0,0 +1,68 @@ +#! /usr/bin/perl -w + +# +# Accept intercept data from l2tpns, write to a file in pcap format +# (http://wiki.ethereal.com/Development/LibpcapFileFormat) suffixed +# with timestamp. Killing the process with SIGHUP causes a new file +# to be opened. +# + +use strict; +use IO::File; +use IO::Socket; +use Time::HiRes 'gettimeofday'; + +(my $cmd = $0) =~ s!.*//!!; + +die "Usage: $cmd PREFIX PORT\n" unless @ARGV == 2 and $ARGV[1] =~ /^\d+$/; + +my ($prefix, $port) = @ARGV; +my $sock = IO::Socket::INET->new( + LocalPort => $port, + Proto => 'udp', + Type => SOCK_DGRAM, +) or die "$cmd: can't bind to port $port ($!)\n"; + +my $restart = 0; +$SIG{HUP} = sub { $restart++ }; + +my $header = pack LSSlLLL => + 0xa1b2c3d4, # magic no + 2, # version maj + 4, # version min + 0, # timezone offset (GMT) + 0, # timestamp accuracy + 65536, # snaplen + 12; # link type (RAW_IP) + +my $cap; +my $buf; +my $file; +for (;;) +{ + unless ($cap) + { + $file = $prefix . time; + $cap = IO::File->new("> $file") + or die "$0: can't create capture file $file ($!)\n"; + + $cap->print($header) + or die "$0: error writing to $file ($!)\n"; + } + + while ($sock->recv($buf, 1600)) + { + $cap->print( + # packet header: sec, usec, included size, original size + (pack LLLL => (gettimeofday), (length $buf) x 2), + $buf + ) or die "$0: error writing to $file ($!)\n"; + } + + if ($restart) + { + $restart = 0; + $cap->close; + undef $cap; + } +} -- 2.20.1 From b95726afbe7dd4e338ce26f65e773965988e1c36 Mon Sep 17 00:00:00 2001 From: bodea Date: Wed, 12 Oct 2005 07:16:53 +0000 Subject: [PATCH 08/16] *** empty log message *** --- scripts/l2tpns-capture | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/l2tpns-capture b/scripts/l2tpns-capture index d675518..6b31daf 100644 --- a/scripts/l2tpns-capture +++ b/scripts/l2tpns-capture @@ -12,7 +12,7 @@ use IO::File; use IO::Socket; use Time::HiRes 'gettimeofday'; -(my $cmd = $0) =~ s!.*//!!; +(my $cmd = $0) =~ s!.*/!!; die "Usage: $cmd PREFIX PORT\n" unless @ARGV == 2 and $ARGV[1] =~ /^\d+$/; -- 2.20.1 From fcad08f6137fb6c53c429a8f55531a94d37908fa Mon Sep 17 00:00:00 2001 From: bodea Date: Tue, 18 Oct 2005 07:19:28 +0000 Subject: [PATCH 09/16] fix LCP Echo frequency --- Changes | 3 ++- l2tpns.c | 6 ++++-- l2tpns.h | 5 ++++- l2tpns.spec | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Changes b/Changes index f769dba..220ba22 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,6 @@ -* Wed Oct 12 2005 Brendan O'Dea 2.1.10 +* Tue Oct 18 2005 Brendan O'Dea 2.1.10 - Add scripts/l2tpns-capture. +- Fix LCP Echo frequency. * Tue Oct 11 2005 Brendan O'Dea 2.1.9 - Fix Calling-Station-Id in RADIUS accounting records (Slobodan Tomic). diff --git a/l2tpns.c b/l2tpns.c index 6d1bb54..caa8bd4 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -4,7 +4,7 @@ // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced // vim: sw=8 ts=8 -char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.144 2005/10/11 09:04:53 bodea Exp $"; +char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.145 2005/10/18 07:19:28 bodea Exp $"; #include #include @@ -2932,7 +2932,8 @@ static void regular_cleanups(double period) } // No data in ECHO_TIMEOUT seconds, send LCP ECHO - if (session[s].ppp.phase >= Establish && (time_now - session[s].last_packet >= ECHO_TIMEOUT)) + if (session[s].ppp.phase >= Establish && (time_now - session[s].last_packet >= ECHO_TIMEOUT) && + (time_now - sess_local[s].last_echo >= ECHO_TIMEOUT)) { uint8_t b[MAXETHER]; @@ -2947,6 +2948,7 @@ static void regular_cleanups(double period) LOG(4, s, session[s].tunnel, "No data in %d seconds, sending LCP ECHO\n", (int)(time_now - session[s].last_packet)); tunnelsend(b, 24, session[s].tunnel); // send it + sess_local[s].last_echo = time_now; s_actions++; } diff --git a/l2tpns.h b/l2tpns.h index 1c768cf..8886076 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -1,5 +1,5 @@ // L2TPNS Global Stuff -// $Id: l2tpns.h,v 1.95 2005/10/12 07:16:13 bodea Exp $ +// $Id: l2tpns.h,v 1.96 2005/10/18 07:19:29 bodea Exp $ #ifndef __L2TPNS_H__ #define __L2TPNS_H__ @@ -307,6 +307,9 @@ typedef struct // interim RADIUS time_t last_interim; + + // last LCP Echo + time_t last_echo; } sessionlocalt; #define SESSIONPFC 1 // PFC negotiated flags diff --git a/l2tpns.spec b/l2tpns.spec index 3721f92..de1cc46 100644 --- a/l2tpns.spec +++ b/l2tpns.spec @@ -43,5 +43,5 @@ rm -rf %{buildroot} %attr(644,root,root) /usr/share/man/man[58]/* %changelog -* Wed Oct 12 2005 Brendan O'Dea 2.1.10-1 +* Tue Oct 18 2005 Brendan O'Dea 2.1.10-1 - 2.1.10 release, see /usr/share/doc/l2tpns-2.1.10/Changes -- 2.20.1 From 149c87a729099fa8c2c7c75ca3816f9aa7f8760d Mon Sep 17 00:00:00 2001 From: bodea Date: Wed, 19 Oct 2005 03:09:29 +0000 Subject: [PATCH 10/16] add Framed-Route entries to RADIUS records --- Changes | 3 ++- l2tpns.spec | 2 +- radius.c | 26 +++++++++++++++++++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Changes b/Changes index 220ba22..0a0e445 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,7 @@ -* Tue Oct 18 2005 Brendan O'Dea 2.1.10 +* Wed Oct 19 2005 Brendan O'Dea 2.1.10 - Add scripts/l2tpns-capture. - Fix LCP Echo frequency. +- Add Framed-Route entries to RADIUS records. * Tue Oct 11 2005 Brendan O'Dea 2.1.9 - Fix Calling-Station-Id in RADIUS accounting records (Slobodan Tomic). diff --git a/l2tpns.spec b/l2tpns.spec index de1cc46..53cd8c5 100644 --- a/l2tpns.spec +++ b/l2tpns.spec @@ -43,5 +43,5 @@ rm -rf %{buildroot} %attr(644,root,root) /usr/share/man/man[58]/* %changelog -* Tue Oct 18 2005 Brendan O'Dea 2.1.10-1 +* Wed Oct 19 2005 Brendan O'Dea 2.1.10-1 - 2.1.10 release, see /usr/share/doc/l2tpns-2.1.10/Changes diff --git a/radius.c b/radius.c index 55aa6cb..a2b2339 100644 --- a/radius.c +++ b/radius.c @@ -1,6 +1,6 @@ // L2TPNS Radius Stuff -char const *cvs_id_radius = "$Id: radius.c,v 1.44 2005/10/11 09:04:53 bodea Exp $"; +char const *cvs_id_radius = "$Id: radius.c,v 1.45 2005/10/19 03:09:30 bodea Exp $"; #include #include @@ -326,6 +326,30 @@ void radiussend(uint16_t r, uint8_t state) *(uint32_t *) (p + 2) = htonl(session[s].ip); p += p[1]; } + if (s && session[s].route[0].ip) + { + int r; + for (r = 0; s && r < MAXROUTE && session[s].route[r].ip; r++) + { + int width = 32; + if (session[s].route[r].mask) + { + int mask = session[s].route[r].mask; + while (!(mask & 1)) + { + width--; + mask >>= 1; + } + } + + *p = 22; // Framed-Route + p[1] = sprintf((char *) p + 2, "%s/%d %s 1", + fmtaddr(htonl(session[s].route[r].ip), 0), + width, fmtaddr(htonl(session[s].ip), 1)) + 2; + + p += p[1]; + } + } if (*session[s].called) { *p = 30; // called -- 2.20.1 From 4caf4199d170130c6c9eb4665629604ec67a9d98 Mon Sep 17 00:00:00 2001 From: bodea Date: Fri, 4 Nov 2005 14:41:50 +0000 Subject: [PATCH 11/16] - Reset restart counters correctly. - Reset timers on sending ConfigReq. - Only send one RADIUS Start record, even if IPCP is restarted. --- Changes | 5 ++++- cluster.c | 4 ++-- l2tpns.c | 25 ++++++++----------------- l2tpns.h | 19 ++++++++++++++----- l2tpns.spec | 2 +- ppp.c | 16 ++++++++++++---- 6 files changed, 41 insertions(+), 30 deletions(-) diff --git a/Changes b/Changes index 0a0e445..a975f5b 100644 --- a/Changes +++ b/Changes @@ -1,7 +1,10 @@ -* Wed Oct 19 2005 Brendan O'Dea 2.1.10 +* Sat Nov 5 2005 Brendan O'Dea 2.1.10 - Add scripts/l2tpns-capture. - Fix LCP Echo frequency. - Add Framed-Route entries to RADIUS records. +- Reset restart counters correctly. +- Reset timers on sending ConfigReq. +- Only send one RADIUS Start record, even if IPCP is restarted. * Tue Oct 11 2005 Brendan O'Dea 2.1.9 - Fix Calling-Station-Id in RADIUS accounting records (Slobodan Tomic). diff --git a/cluster.c b/cluster.c index f601f70..fbd0467 100644 --- a/cluster.c +++ b/cluster.c @@ -1,6 +1,6 @@ // L2TPNS Clustering Stuff -char const *cvs_id_cluster = "$Id: cluster.c,v 1.46 2005/09/02 23:59:56 bodea Exp $"; +char const *cvs_id_cluster = "$Id: cluster.c,v 1.47 2005/11/04 14:41:50 bodea Exp $"; #include #include @@ -1268,7 +1268,7 @@ static uint8_t *convert_session(struct oldsession *old) new.next = old->next; new.far = old->far; new.tunnel = old->tunnel; - new.l2tp_flags = old->l2tp_flags; + new.flags = old->l2tp_flags; new.ip = old->ip; new.ip_pool_index = old->ip_pool_index; new.unique_id = old->unique_id; diff --git a/l2tpns.c b/l2tpns.c index caa8bd4..67211ce 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -4,7 +4,7 @@ // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced // vim: sw=8 ts=8 -char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.145 2005/10/18 07:19:28 bodea Exp $"; +char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.146 2005/11/04 14:41:50 bodea Exp $"; #include #include @@ -1682,6 +1682,7 @@ void sendipcp(sessionidt s, tunnelidt t) my_address; // send my IP tunnelsend(buf, 10 + (q - buf), t); // send it + restart_timer(s, ipcp); } void sendipv6cp(sessionidt s, tunnelidt t) @@ -1707,6 +1708,7 @@ void sendipv6cp(sessionidt s, tunnelidt t) q[13] = 1; tunnelsend(buf, 14 + (q - buf), t); // send it + restart_timer(s, ipv6cp); } static void sessionclear(sessionidt s) @@ -2327,9 +2329,9 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr) if (*p == 5 && p[1] == 6) // Magic-Number amagic = ntohl(*(uint32_t *) (p + 2)); else if (*p == 7) // Protocol-Field-Compression - aflags |= SESSIONPFC; + aflags |= SESSION_PFC; else if (*p == 8) // Address-and-Control-Field-Compression - aflags |= SESSIONACFC; + aflags |= SESSION_ACFC; p += p[1]; } } @@ -2456,20 +2458,17 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr) case 12: // ICCN if (amagic == 0) amagic = time_now; session[s].magic = amagic; // set magic number - session[s].l2tp_flags = aflags; // set flags received + session[s].flags = aflags; // set flags received session[s].mru = PPPMTU; // default controlnull(t); // ack // start LCP - 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 = config->radius_authprefer; sess_local[s].ppp_mru = MRU; - session[s].ppp.lcp = RequestSent; sendlcp(s, t); - + change_state(s, lcp, RequestSent); break; + case 14: // CDN controlnull(t); // ack sessionshutdown(s, "Closed (Received CDN).", 0, 0); @@ -2817,8 +2816,6 @@ static void regular_cleanups(double period) 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(s, session[s].tunnel); change_state(s, lcp, next_state); } @@ -2848,8 +2845,6 @@ static void regular_cleanups(double period) 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(s, session[s].tunnel); change_state(s, ipcp, next_state); } @@ -2879,8 +2874,6 @@ static void regular_cleanups(double period) 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(s, session[s].tunnel); change_state(s, ipv6cp, next_state); } @@ -2907,8 +2900,6 @@ static void regular_cleanups(double period) 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(s, session[s].tunnel); change_state(s, ccp, next_state); } diff --git a/l2tpns.h b/l2tpns.h index 8886076..9693dbe 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -1,5 +1,5 @@ // L2TPNS Global Stuff -// $Id: l2tpns.h,v 1.96 2005/10/18 07:19:29 bodea Exp $ +// $Id: l2tpns.h,v 1.97 2005/11/04 14:41:50 bodea Exp $ #ifndef __L2TPNS_H__ #define __L2TPNS_H__ @@ -148,7 +148,14 @@ enum { // reset state machine counters #define initialise_restart_count(_s, _fsm) \ - sess_local[_s]._fsm.conf_sent = sess_local[_s]._fsm.nak_sent + sess_local[_s]._fsm.conf_sent = sess_local[_s]._fsm.nak_sent = 0 + +// increment ConfReq counter and reset timer +#define restart_timer(_s, _fsm) ({ \ + sess_local[_s]._fsm.conf_sent++; \ + sess_local[_s]._fsm.restart = \ + time_now + config->ppp_restart_time; \ +}) // stop timer on change to state where timer does not run #define change_state(_s, _fsm, _new) ({ \ @@ -221,7 +228,7 @@ typedef struct sessionidt next; // next session in linked list sessionidt far; // far end session ID tunnelidt tunnel; // near end tunnel ID - uint8_t l2tp_flags; // various bit flags from the ICCN on the l2tp tunnel. + uint8_t flags; // session flags: see SESSION_* struct { uint8_t phase; // PPP phase uint8_t lcp:4; // LCP state @@ -312,8 +319,10 @@ typedef struct time_t last_echo; } sessionlocalt; -#define SESSIONPFC 1 // PFC negotiated flags -#define SESSIONACFC 2 // ACFC negotiated flags +// session flags +#define SESSION_PFC (1 << 0) // use Protocol-Field-Compression +#define SESSION_ACFC (1 << 1) // use Address-and-Control-Field-Compression +#define SESSION_STARTED (1 << 2) // RADIUS Start record sent // 168 bytes per tunnel typedef struct diff --git a/l2tpns.spec b/l2tpns.spec index 53cd8c5..434f222 100644 --- a/l2tpns.spec +++ b/l2tpns.spec @@ -43,5 +43,5 @@ rm -rf %{buildroot} %attr(644,root,root) /usr/share/man/man[58]/* %changelog -* Wed Oct 19 2005 Brendan O'Dea 2.1.10-1 +* Sat Nov 5 2005 Brendan O'Dea 2.1.10-1 - 2.1.10 release, see /usr/share/doc/l2tpns-2.1.10/Changes diff --git a/ppp.c b/ppp.c index 263fb95..d2411a6 100644 --- a/ppp.c +++ b/ppp.c @@ -1,6 +1,6 @@ // L2TPNS PPP Stuff -char const *cvs_id_ppp = "$Id: ppp.c,v 1.84 2005/09/16 13:20:39 bodea Exp $"; +char const *cvs_id_ppp = "$Id: ppp.c,v 1.85 2005/11/04 14:41:50 bodea Exp $"; #include #include @@ -903,11 +903,17 @@ static void ipcp_open(sessionidt s, tunnelidt t) change_state(s, ipcp, Opened); - if (!session[s].walled_garden) + if (!(session[s].walled_garden || session[s].flags & SESSION_STARTED)) { uint16_t r = radiusnew(s); if (r) + { radiussend(r, RADIUSSTART); // send radius start + + // don't send further Start records if IPCP is restarted + session[s].flags |= SESSION_STARTED; + cluster_send_session(s); + } } // start IPv6 if configured and still in passive state @@ -1747,12 +1753,12 @@ uint8_t *makeppp(uint8_t *b, int size, uint8_t *p, int l, sessionidt s, tunnelid *(uint16_t *) (b + 2) = htons(tunnel[t].far); // tunnel *(uint16_t *) (b + 4) = htons(session[s].far); // session b += 6; - if (mtype == PPPLCP || !(session[s].l2tp_flags & SESSIONACFC)) + if (mtype == PPPLCP || !(session[s].flags & SESSION_ACFC)) { *(uint16_t *) b = htons(0xFF03); // HDLC header b += 2; } - if (mtype < 0x100 && session[s].l2tp_flags & SESSIONPFC) + if (mtype < 0x100 && session[s].flags & SESSION_PFC) *b++ = mtype; else { @@ -1839,6 +1845,7 @@ void sendlcp(sessionidt s, tunnelidt t) if (config->debug > 3) dumplcp(q, l - q); tunnelsend(b, (l - b), t); + restart_timer(s, lcp); } // Send CCP request for no compression @@ -1857,4 +1864,5 @@ void sendccp(sessionidt s, tunnelidt t) LOG_HEX(5, "PPPCCP", q, 4); tunnelsend(b, (q - b) + 4 , t); + restart_timer(s, ccp); } -- 2.20.1 From 0dc8fc58d5e86e164c3f85e63cad8d270d12cee2 Mon Sep 17 00:00:00 2001 From: bodea Date: Mon, 14 Nov 2005 08:38:02 +0000 Subject: [PATCH 12/16] fix fragment handling in ip_filter --- Changes | 3 +++ l2tpns.c | 7 +++++-- l2tpns.h | 4 ++-- l2tpns.spec | 6 +++--- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Changes b/Changes index a975f5b..2e4efa7 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,6 @@ +* Mon Nov 14 2005 Brendan O'Dea 2.1.11 +- Fix fragment handling in ip_filter. + * Sat Nov 5 2005 Brendan O'Dea 2.1.10 - Add scripts/l2tpns-capture. - Fix LCP Echo frequency. diff --git a/l2tpns.c b/l2tpns.c index 67211ce..8af4eb2 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -4,7 +4,7 @@ // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced // vim: sw=8 ts=8 -char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.146 2005/11/04 14:41:50 bodea Exp $"; +char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.147 2005/11/14 08:38:02 bodea Exp $"; #include #include @@ -5350,7 +5350,10 @@ int ip_filter(uint8_t *buf, int len, uint8_t filter) if (frag_offset) { - if (!rule->frag || rule->action == FILTER_ACTION_DENY) + // non-fragmented deny rules are skipped if containing L4 matches + if (!rule->frag && + (rule->src_ports.op || rule->dst_ports.op || rule->tcp_flag_op) && + rule->action == FILTER_ACTION_DENY) continue; } else diff --git a/l2tpns.h b/l2tpns.h index 9693dbe..1412cbd 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -1,5 +1,5 @@ // L2TPNS Global Stuff -// $Id: l2tpns.h,v 1.97 2005/11/04 14:41:50 bodea Exp $ +// $Id: l2tpns.h,v 1.98 2005/11/14 08:38:02 bodea Exp $ #ifndef __L2TPNS_H__ #define __L2TPNS_H__ @@ -15,7 +15,7 @@ #include #include -#define VERSION "2.1.10" +#define VERSION "2.1.11" // Limits #define MAXTUNNEL 500 // could be up to 65535 diff --git a/l2tpns.spec b/l2tpns.spec index 434f222..65d22dd 100644 --- a/l2tpns.spec +++ b/l2tpns.spec @@ -1,6 +1,6 @@ Summary: A high-speed clustered L2TP LNS Name: l2tpns -Version: 2.1.10 +Version: 2.1.11 Release: 1 Copyright: GPL Group: System Environment/Daemons @@ -43,5 +43,5 @@ rm -rf %{buildroot} %attr(644,root,root) /usr/share/man/man[58]/* %changelog -* Sat Nov 5 2005 Brendan O'Dea 2.1.10-1 -- 2.1.10 release, see /usr/share/doc/l2tpns-2.1.10/Changes +* Mon Nov 14 2005 Brendan O'Dea 2.1.11-1 +- 2.1.11 release, see /usr/share/doc/l2tpns-2.1.11/Changes -- 2.20.1 From e6208f516d2437f7effeee7305bd3ecae93e4c11 Mon Sep 17 00:00:00 2001 From: bodea Date: Mon, 14 Nov 2005 09:49:01 +0000 Subject: [PATCH 13/16] exclude counter when comparing filter rules --- Changes | 1 + cli.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Changes b/Changes index 2e4efa7..40f7944 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,6 @@ * Mon Nov 14 2005 Brendan O'Dea 2.1.11 - Fix fragment handling in ip_filter. +- Exclude counter when comparing filter rules. * Sat Nov 5 2005 Brendan O'Dea 2.1.10 - Add scripts/l2tpns-capture. diff --git a/cli.c b/cli.c index 80b92a9..c2e0c13 100644 --- a/cli.c +++ b/cli.c @@ -2,9 +2,10 @@ // vim: sw=8 ts=8 char const *cvs_name = "$Name: $"; -char const *cvs_id_cli = "$Id: cli.c,v 1.66 2005/09/01 06:59:06 bodea Exp $"; +char const *cvs_id_cli = "$Id: cli.c,v 1.67 2005/11/14 09:49:01 bodea Exp $"; #include +#include #include #include #include @@ -2884,7 +2885,7 @@ static int cmd_ip_access_list_rule(struct cli_def *cli, char *command, char **ar return CLI_OK; } - if (!memcmp(&ip_filters[filt].rules[i], rule, sizeof(*rule))) + if (!memcmp(&ip_filters[filt].rules[i], rule, offsetof(ip_filter_rulet, counter))) return CLI_OK; } -- 2.20.1 From 8cb67386de583a4f755e4e0f7835207771d4aa83 Mon Sep 17 00:00:00 2001 From: bodea Date: Mon, 14 Nov 2005 20:19:08 +0000 Subject: [PATCH 14/16] access-list rule counters are unsigned --- cli.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli.c b/cli.c index c2e0c13..34038ef 100644 --- a/cli.c +++ b/cli.c @@ -2,7 +2,7 @@ // vim: sw=8 ts=8 char const *cvs_name = "$Name: $"; -char const *cvs_id_cli = "$Id: cli.c,v 1.67 2005/11/14 09:49:01 bodea Exp $"; +char const *cvs_id_cli = "$Id: cli.c,v 1.68 2005/11/14 20:19:08 bodea Exp $"; #include #include @@ -3069,7 +3069,7 @@ static int cmd_show_access_list(struct cli_def *cli, char *command, char **argv, { char const *r = show_access_list_rule(ip_filters[f].extended, rules); if (rules->counter) - cli_print(cli, "%s (%d match%s)", r, + cli_print(cli, "%s (%u match%s)", r, rules->counter, rules->counter > 1 ? "es" : ""); else cli_print(cli, "%s", r); -- 2.20.1 From 728b8416cfad1cec0ffdf17c871ff1e6b0c386fd Mon Sep 17 00:00:00 2001 From: bodea Date: Mon, 14 Nov 2005 21:08:30 +0000 Subject: [PATCH 15/16] layer 4 info implies !frag --- l2tpns.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/l2tpns.c b/l2tpns.c index 8af4eb2..0d9a2c2 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -4,7 +4,7 @@ // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced // vim: sw=8 ts=8 -char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.147 2005/11/14 08:38:02 bodea Exp $"; +char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.148 2005/11/14 21:08:30 bodea Exp $"; #include #include @@ -5350,10 +5350,9 @@ int ip_filter(uint8_t *buf, int len, uint8_t filter) if (frag_offset) { - // non-fragmented deny rules are skipped if containing L4 matches - if (!rule->frag && - (rule->src_ports.op || rule->dst_ports.op || rule->tcp_flag_op) && - rule->action == FILTER_ACTION_DENY) + // layer 4 deny rules are skipped + if (rule->action == FILTER_ACTION_DENY && + (rule->src_ports.op || rule->dst_ports.op || rule->tcp_flag_op)) continue; } else -- 2.20.1 From 4944040cdb14713ea8ae3522299137393e5dc2c9 Mon Sep 17 00:00:00 2001 From: bodea Date: Thu, 17 Nov 2005 05:24:17 +0000 Subject: [PATCH 16/16] ensure MRU is sane --- ppp.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/ppp.c b/ppp.c index d2411a6..0f87c97 100644 --- a/ppp.c +++ b/ppp.c @@ -1,6 +1,6 @@ // L2TPNS PPP Stuff -char const *cvs_id_ppp = "$Id: ppp.c,v 1.85 2005/11/04 14:41:50 bodea Exp $"; +char const *cvs_id_ppp = "$Id: ppp.c,v 1.86 2005/11/17 05:24:17 bodea Exp $"; #include #include @@ -575,7 +575,18 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) switch (type) { case 1: // Maximum-Receive-Unit - session[s].mru = ntohs(*(uint16_t *)(o + 2)); + { + uint16_t mru = ntohs(*(uint16_t *)(o + 2)); + if (mru >= 576) + { + session[s].mru = mru; + break; + } + + LOG(3, s, t, " Remote requesting MRU of %u. Rejecting.\n", mru); + mru = htons(MRU); + q = ppp_conf_nak(s, b, sizeof(b), PPPLCP, &response, q, p, o, (uint8_t *) &mru, sizeof(mru)); + } break; case 2: // Async-Control-Character-Map -- 2.20.1