make "established" a different tcp flag match

add fragment handling
drop IP address from LOG macro (function)
This commit is contained in:
Brendan O'Dea 2004-11-29 02:17:17 +00:00
parent 80308e8838
commit 2f5b811429
16 changed files with 722 additions and 627 deletions

View file

@ -7,6 +7,7 @@
setup in some instances. setup in some instances.
- Implement named access-lists which may be applied to a session - Implement named access-lists which may be applied to a session
either via Filter-Id RADIUS responses, or using the CLI. either via Filter-Id RADIUS responses, or using the CLI.
- Drop ip address from LOG.
* Sat Nov 20 2004 Brendan O'Dea <bod@optusnet.com.au> 2.0.8 * Sat Nov 20 2004 Brendan O'Dea <bod@optusnet.com.au> 2.0.8
- Ignore gateway address in Framed-Route (from Jonathan McDowell). - Ignore gateway address in Framed-Route (from Jonathan McDowell).

View file

@ -4,7 +4,7 @@
/* set up intercept based on RADIUS reply */ /* set up intercept based on RADIUS reply */
char const *cvs_id = "$Id: autosnoop.c,v 1.8 2004-11-17 08:23:34 bodea Exp $"; char const *cvs_id = "$Id: autosnoop.c,v 1.9 2004-11-29 02:17:17 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION; int plugin_api_version = PLUGIN_API_VERSION;
struct pluginfuncs *p; struct pluginfuncs *p;
@ -22,12 +22,14 @@ int plugin_radius_response(struct param_radius_response *data)
if (*data->value) data->s->snoop_ip = inet_addr(data->value); if (*data->value) data->s->snoop_ip = inet_addr(data->value);
if (data->s->snoop_ip == INADDR_NONE) data->s->snoop_ip = 0; if (data->s->snoop_ip == INADDR_NONE) data->s->snoop_ip = 0;
if (*x) data->s->snoop_port = atoi(x); if (*x) data->s->snoop_port = atoi(x);
p->log(3, 0, 0, 0, " Intercepting user to %s:%d\n", p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
p->inet_toa(data->s->snoop_ip), data->s->snoop_port); " Intercepting user to %s:%d\n",
p->fmtaddr(data->s->snoop_ip, 0), data->s->snoop_port);
} }
else else
{ {
p->log(3, 0, 0, 0, " Not Intercepting user (reply string should be intercept=ip:port)\n"); p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
" Not Intercepting user (reply string should be intercept=ip:port)\n");
} }
} }
return PLUGIN_RET_OK; return PLUGIN_RET_OK;

View file

@ -4,7 +4,7 @@
/* set up throttling based on RADIUS reply */ /* set up throttling based on RADIUS reply */
char const *cvs_id = "$Id: autothrottle.c,v 1.9 2004-11-17 08:23:34 bodea Exp $"; char const *cvs_id = "$Id: autothrottle.c,v 1.10 2004-11-29 02:17:17 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION; int plugin_api_version = PLUGIN_API_VERSION;
struct pluginfuncs *p; struct pluginfuncs *p;
@ -35,17 +35,23 @@ int plugin_radius_response(struct param_radius_response *data)
case 2: // output case 2: // output
data->s->throttle_out = rate; data->s->throttle_out = rate;
free(pt); free(pt);
p->log(3, 0, p->get_id_by_session(data->s), data->s->tunnel, " Set output throttle rate %dkb/s\n", rate); p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
" Set output throttle rate %dkb/s\n", rate);
return PLUGIN_RET_OK; return PLUGIN_RET_OK;
case 3: //input case 3: //input
data->s->throttle_in = rate; data->s->throttle_in = rate;
free(pt); free(pt);
p->log(3, 0, p->get_id_by_session(data->s), data->s->tunnel, " Set input throttle rate %dkb/s\n", rate); p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
" Set input throttle rate %dkb/s\n", rate);
return PLUGIN_RET_OK; return PLUGIN_RET_OK;
default: default:
p->log(1, 0, p->get_id_by_session(data->s), data->s->tunnel, "Syntax error in rate limit AV pair: %s=%s\n", data->key, data->value); p->log(1, p->get_id_by_session(data->s), data->s->tunnel,
"Syntax error in rate limit AV pair: %s=%s\n", data->key, data->value);
free(pt); free(pt);
return PLUGIN_RET_OK; return PLUGIN_RET_OK;
} }
@ -53,8 +59,10 @@ int plugin_radius_response(struct param_radius_response *data)
else else
{ {
free(pt); free(pt);
p->log(1, 0, p->get_id_by_session(data->s), data->s->tunnel, "Syntax error in rate limit AV pair: %s=%s\n", p->log(1, p->get_id_by_session(data->s), data->s->tunnel,
"Syntax error in rate limit AV pair: %s=%s\n",
data->key, data->value); data->key, data->value);
return PLUGIN_RET_OK; return PLUGIN_RET_OK;
} }
} }
@ -68,23 +76,29 @@ int plugin_radius_response(struct param_radius_response *data)
if (rate) if (rate)
{ {
if (*rate) if (*rate)
p->log(3, 0, p->get_id_by_session(data->s), data->s->tunnel, " Throttling user to %dkb/s\n", *rate); p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
" Throttling user to %dkb/s\n", *rate);
else else
p->log(3, 0, p->get_id_by_session(data->s), data->s->tunnel, " Not throttling user (throttle_speed=0)\n"); p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
" Not throttling user (throttle_speed=0)\n");
data->s->throttle_in = data->s->throttle_out = *rate; data->s->throttle_in = data->s->throttle_out = *rate;
} }
else else
p->log(1, 0, p->get_id_by_session(data->s), data->s->tunnel, "Not throttling user (can't get throttle_speed)\n"); p->log(1, p->get_id_by_session(data->s), data->s->tunnel,
"Not throttling user (can't get throttle_speed)\n");
} }
else if (strcmp(data->value, "no") == 0) else if (strcmp(data->value, "no") == 0)
{ {
p->log(3, 0, p->get_id_by_session(data->s), data->s->tunnel, " Not throttling user\n"); 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 = 0; data->s->throttle_in = data->s->throttle_out = 0;
} }
} }
p->log(4, 0, p->get_id_by_session(data->s), data->s->tunnel, "autothrottle module ignoring AV pair %s=%s\n", p->log(4, p->get_id_by_session(data->s), data->s->tunnel,
"autothrottle module ignoring AV pair %s=%s\n",
data->key, data->value); data->key, data->value);
return PLUGIN_RET_OK; return PLUGIN_RET_OK;

92
bgp.c
View file

@ -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.7 2004-11-15 06:49:56 bodea Exp $"; char const *cvs_id_bgp = "$Id: bgp.c,v 1.8 2004-11-29 02:17:17 bodea Exp $";
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
@ -69,7 +69,7 @@ int bgp_setup(int as)
if (!((peer->outbuf = malloc(sizeof(*peer->outbuf))) if (!((peer->outbuf = malloc(sizeof(*peer->outbuf)))
&& (peer->inbuf = malloc(sizeof(*peer->inbuf))))) && (peer->inbuf = malloc(sizeof(*peer->inbuf)))))
{ {
LOG(0, 0, 0, 0, "Can't allocate buffers for bgp peer (%s)\n", LOG(0, 0, 0, "Can't allocate buffers for bgp peer (%s)\n",
strerror(errno)); strerror(errno));
return 0; return 0;
@ -111,7 +111,7 @@ int bgp_start(struct bgp_peer *peer, char *name, int as, int keepalive, int hold
if (!(h = gethostbyname(name)) || h->h_addrtype != AF_INET) if (!(h = gethostbyname(name)) || h->h_addrtype != AF_INET)
{ {
LOG(0, 0, 0, 0, "Can't get address for BGP peer %s (%s)\n", LOG(0, 0, 0, "Can't get address for BGP peer %s (%s)\n",
name, h ? "no address" : hstrerror(h_errno)); name, h ? "no address" : hstrerror(h_errno));
return 0; return 0;
@ -225,7 +225,7 @@ int bgp_start(struct bgp_peer *peer, char *name, int as, int keepalive, int hold
if (!(peer->path_attrs = malloc(peer->path_attr_len))) if (!(peer->path_attrs = malloc(peer->path_attr_len)))
{ {
LOG(0, 0, 0, 0, "Can't allocate path_attrs for %s (%s)\n", LOG(0, 0, 0, "Can't allocate path_attrs for %s (%s)\n",
name, strerror(errno)); name, strerror(errno));
return 0; return 0;
@ -233,7 +233,7 @@ int bgp_start(struct bgp_peer *peer, char *name, int as, int keepalive, int hold
memcpy(peer->path_attrs, path_attrs, peer->path_attr_len); memcpy(peer->path_attrs, path_attrs, peer->path_attr_len);
LOG(4, 0, 0, 0, "Initiating BGP connection to %s (routing %s)\n", LOG(4, 0, 0, "Initiating BGP connection to %s (routing %s)\n",
name, enable ? "enabled" : "suspended"); name, enable ? "enabled" : "suspended");
/* we have at least one peer configured */ /* we have at least one peer configured */
@ -274,7 +274,7 @@ static void bgp_clear(struct bgp_peer *peer)
peer->state = peer->next_state; peer->state = peer->next_state;
peer->state_time = time_now; peer->state_time = time_now;
LOG(4, 0, 0, 0, "BGP peer %s: state %s\n", peer->name, LOG(4, 0, 0, "BGP peer %s: state %s\n", peer->name,
bgp_state_str(peer->next_state)); bgp_state_str(peer->next_state));
} }
} }
@ -282,14 +282,14 @@ static void bgp_clear(struct bgp_peer *peer)
/* initiate a clean shutdown */ /* initiate a clean shutdown */
void bgp_stop(struct bgp_peer *peer) void bgp_stop(struct bgp_peer *peer)
{ {
LOG(4, 0, 0, 0, "Terminating BGP connection to %s\n", peer->name); LOG(4, 0, 0, "Terminating BGP connection to %s\n", peer->name);
bgp_send_notification(peer, BGP_ERR_CEASE, 0); bgp_send_notification(peer, BGP_ERR_CEASE, 0);
} }
/* drop connection (if any) and set state to Disabled */ /* drop connection (if any) and set state to Disabled */
void bgp_halt(struct bgp_peer *peer) void bgp_halt(struct bgp_peer *peer)
{ {
LOG(4, 0, 0, 0, "Aborting BGP connection to %s\n", peer->name); LOG(4, 0, 0, "Aborting BGP connection to %s\n", peer->name);
peer->next_state = Disabled; peer->next_state = Disabled;
bgp_clear(peer); bgp_clear(peer);
} }
@ -399,8 +399,8 @@ int bgp_add_route(in_addr_t ip, in_addr_t mask)
/* insert into route list; sorted */ /* insert into route list; sorted */
if (!(r = malloc(sizeof(*r)))) if (!(r = malloc(sizeof(*r))))
{ {
LOG(0, 0, 0, 0, "Can't allocate route for %s/%d (%s)\n", LOG(0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
inet_toa(add.dest.prefix), add.dest.len, strerror(errno)); fmtaddr(add.dest.prefix, 0), add.dest.len, strerror(errno));
return 0; return 0;
} }
@ -413,8 +413,8 @@ int bgp_add_route(in_addr_t ip, in_addr_t mask)
if (bgp_peers[i].state == Established) if (bgp_peers[i].state == Established)
bgp_peers[i].update_routes = 1; bgp_peers[i].update_routes = 1;
LOG(4, 0, 0, 0, "Registered BGP route %s/%d\n", inet_toa(add.dest.prefix), LOG(4, 0, 0, "Registered BGP route %s/%d\n",
add.dest.len); fmtaddr(add.dest.prefix, 0), add.dest.len);
return 1; return 1;
} }
@ -462,8 +462,8 @@ int bgp_del_route(in_addr_t ip, in_addr_t mask)
if (bgp_peers[i].state == Established) if (bgp_peers[i].state == Established)
bgp_peers[i].update_routes = 1; bgp_peers[i].update_routes = 1;
LOG(4, 0, 0, 0, "Removed BGP route %s/%d\n", inet_toa(del.dest.prefix), LOG(4, 0, 0, "Removed BGP route %s/%d\n",
del.dest.len); fmtaddr(del.dest.prefix, 0), del.dest.len);
return 1; return 1;
} }
@ -482,7 +482,7 @@ void bgp_enable_routing(int enable)
bgp_peers[i].update_routes = 1; bgp_peers[i].update_routes = 1;
} }
LOG(4, 0, 0, 0, "%s BGP routing\n", enable ? "Enabled" : "Suspended"); LOG(4, 0, 0, "%s BGP routing\n", enable ? "Enabled" : "Suspended");
} }
/* return a bitmask indicating if the socket should be added to the /* return a bitmask indicating if the socket should be added to the
@ -588,7 +588,7 @@ int bgp_process(struct bgp_peer *peer, int readable, int writable)
{ {
if (time_now > peer->expire_time) if (time_now > peer->expire_time)
{ {
LOG(1, 0, 0, 0, "No message from BGP peer %s in %ds\n", LOG(1, 0, 0, "No message from BGP peer %s in %ds\n",
peer->name, peer->hold); peer->name, peer->hold);
bgp_send_notification(peer, BGP_ERR_HOLD_TIMER_EXP, 0); bgp_send_notification(peer, BGP_ERR_HOLD_TIMER_EXP, 0);
@ -605,7 +605,7 @@ int bgp_process(struct bgp_peer *peer, int readable, int writable)
} }
else if (time_now > peer->state_time + BGP_STATE_TIME) else if (time_now > peer->state_time + BGP_STATE_TIME)
{ {
LOG(1, 0, 0, 0, "%s timer expired for BGP peer %s\n", LOG(1, 0, 0, "%s timer expired for BGP peer %s\n",
bgp_state_str(peer->state), peer->name); bgp_state_str(peer->state), peer->name);
return bgp_restart(peer); return bgp_restart(peer);
@ -665,7 +665,7 @@ static int bgp_connect(struct bgp_peer *peer)
struct servent *serv; struct servent *serv;
if (!(serv = getservbyname("bgp", "tcp"))) if (!(serv = getservbyname("bgp", "tcp")))
{ {
LOG(0, 0, 0, 0, "Can't get bgp service (%s)\n", strerror(errno)); LOG(0, 0, 0, "Can't get bgp service (%s)\n", strerror(errno));
return 0; return 0;
} }
@ -674,7 +674,7 @@ static int bgp_connect(struct bgp_peer *peer)
if ((peer->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) if ((peer->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{ {
LOG(0, 0, 0, 0, "Can't create a socket for BGP peer %s (%s)\n", LOG(0, 0, 0, "Can't create a socket for BGP peer %s (%s)\n",
peer->name, strerror(errno)); peer->name, strerror(errno));
peer->state = peer->next_state = Disabled; peer->state = peer->next_state = Disabled;
@ -697,7 +697,7 @@ static int bgp_connect(struct bgp_peer *peer)
if (errno != EINPROGRESS) if (errno != EINPROGRESS)
{ {
LOG(1, 0, 0, 0, "Can't connect to BGP peer %s (%s)\n", LOG(1, 0, 0, "Can't connect to BGP peer %s (%s)\n",
inet_ntoa(addr.sin_addr), strerror(errno)); inet_ntoa(addr.sin_addr), strerror(errno));
bgp_set_retry(peer); bgp_set_retry(peer);
@ -707,7 +707,7 @@ static int bgp_connect(struct bgp_peer *peer)
peer->state = Connect; peer->state = Connect;
peer->state_time = time_now; peer->state_time = time_now;
LOG(4, 0, 0, 0, "BGP peer %s: state Connect\n", peer->name); LOG(4, 0, 0, "BGP peer %s: state Connect\n", peer->name);
return 1; return 1;
} }
@ -715,7 +715,7 @@ static int bgp_connect(struct bgp_peer *peer)
peer->state_time = time_now; peer->state_time = time_now;
peer->retry_time = peer->retry_count = 0; peer->retry_time = peer->retry_count = 0;
LOG(4, 0, 0, 0, "BGP peer %s: state Active\n", inet_ntoa(addr.sin_addr)); LOG(4, 0, 0, "BGP peer %s: state Active\n", inet_ntoa(addr.sin_addr));
return bgp_send_open(peer); return bgp_send_open(peer);
} }
@ -728,7 +728,7 @@ static int bgp_handle_connect(struct bgp_peer *peer)
getsockopt(peer->sock, SOL_SOCKET, SO_ERROR, &err, &len); getsockopt(peer->sock, SOL_SOCKET, SO_ERROR, &err, &len);
if (err) if (err)
{ {
LOG(1, 0, 0, 0, "Can't connect to BGP peer %s (%s)\n", peer->name, LOG(1, 0, 0, "Can't connect to BGP peer %s (%s)\n", peer->name,
strerror(err)); strerror(err));
bgp_set_retry(peer); bgp_set_retry(peer);
@ -738,7 +738,7 @@ static int bgp_handle_connect(struct bgp_peer *peer)
peer->state = Active; peer->state = Active;
peer->state_time = time_now; peer->state_time = time_now;
LOG(4, 0, 0, 0, "BGP peer %s: state Active\n", peer->name); LOG(4, 0, 0, "BGP peer %s: state Active\n", peer->name);
return bgp_send_open(peer); return bgp_send_open(peer);
} }
@ -759,9 +759,9 @@ static int bgp_write(struct bgp_peer *peer)
return 1; return 1;
if (errno == EPIPE) if (errno == EPIPE)
LOG(1, 0, 0, 0, "Connection to BGP peer %s closed\n", peer->name); LOG(1, 0, 0, "Connection to BGP peer %s closed\n", peer->name);
else else
LOG(1, 0, 0, 0, "Can't write to BGP peer %s (%s)\n", peer->name, LOG(1, 0, 0, "Can't write to BGP peer %s (%s)\n", peer->name,
strerror(errno)); strerror(errno));
bgp_set_retry(peer); bgp_set_retry(peer);
@ -774,7 +774,7 @@ static int bgp_write(struct bgp_peer *peer)
return 1; return 1;
} }
LOG(4, 0, 0, 0, "Sent %s to BGP peer %s\n", LOG(4, 0, 0, "Sent %s to BGP peer %s\n",
bgp_msg_type_str(peer->outbuf->packet.header.type), peer->name); bgp_msg_type_str(peer->outbuf->packet.header.type), peer->name);
peer->outbuf->packet.header.len = 0; peer->outbuf->packet.header.len = 0;
@ -794,7 +794,7 @@ static int bgp_write(struct bgp_peer *peer)
peer->state = peer->next_state; peer->state = peer->next_state;
peer->state_time = time_now; peer->state_time = time_now;
LOG(4, 0, 0, 0, "BGP peer %s: state %s\n", peer->name, LOG(4, 0, 0, "BGP peer %s: state %s\n", peer->name,
bgp_state_str(peer->state)); bgp_state_str(peer->state));
} }
@ -811,7 +811,7 @@ static int bgp_read(struct bgp_peer *peer)
{ {
if (!r) if (!r)
{ {
LOG(1, 0, 0, 0, "Connection to BGP peer %s closed\n", peer->name); LOG(1, 0, 0, "Connection to BGP peer %s closed\n", peer->name);
} }
else else
{ {
@ -821,7 +821,7 @@ static int bgp_read(struct bgp_peer *peer)
if (errno == EAGAIN) if (errno == EAGAIN)
return 1; return 1;
LOG(1, 0, 0, 0, "Can't read from BGP peer %s (%s)\n", peer->name, LOG(1, 0, 0, "Can't read from BGP peer %s (%s)\n", peer->name,
strerror(errno)); strerror(errno));
} }
@ -841,7 +841,7 @@ static int bgp_handle_input(struct bgp_peer *peer)
if (len > BGP_MAX_PACKET_SIZE) if (len > BGP_MAX_PACKET_SIZE)
{ {
LOG(1, 0, 0, 0, "Bad header length from BGP %s\n", peer->name); LOG(1, 0, 0, "Bad header length from BGP %s\n", peer->name);
bgp_send_notification(peer, BGP_ERR_HEADER, BGP_ERR_HDR_BAD_LEN); bgp_send_notification(peer, BGP_ERR_HEADER, BGP_ERR_HDR_BAD_LEN);
return 0; return 0;
} }
@ -849,7 +849,7 @@ static int bgp_handle_input(struct bgp_peer *peer)
if (peer->inbuf->done < len) if (peer->inbuf->done < len)
return 0; return 0;
LOG(4, 0, 0, 0, "Received %s from BGP peer %s\n", LOG(4, 0, 0, "Received %s from BGP peer %s\n",
bgp_msg_type_str(p->header.type), peer->name); bgp_msg_type_str(p->header.type), peer->name);
switch (p->header.type) switch (p->header.type)
@ -864,7 +864,7 @@ static int bgp_handle_input(struct bgp_peer *peer)
{ {
if ((unsigned char) p->header.marker[i] != 0xff) if ((unsigned char) p->header.marker[i] != 0xff)
{ {
LOG(1, 0, 0, 0, "Invalid marker from BGP peer %s\n", LOG(1, 0, 0, "Invalid marker from BGP peer %s\n",
peer->name); peer->name);
bgp_send_notification(peer, BGP_ERR_HEADER, bgp_send_notification(peer, BGP_ERR_HEADER,
@ -876,7 +876,7 @@ static int bgp_handle_input(struct bgp_peer *peer)
if (peer->state != OpenSent) if (peer->state != OpenSent)
{ {
LOG(1, 0, 0, 0, "OPEN from BGP peer %s in %s state\n", LOG(1, 0, 0, "OPEN from BGP peer %s in %s state\n",
peer->name, bgp_state_str(peer->state)); peer->name, bgp_state_str(peer->state));
bgp_send_notification(peer, BGP_ERR_FSM, 0); bgp_send_notification(peer, BGP_ERR_FSM, 0);
@ -887,7 +887,7 @@ static int bgp_handle_input(struct bgp_peer *peer)
if (data.version != BGP_VERSION) if (data.version != BGP_VERSION)
{ {
LOG(1, 0, 0, 0, "Bad version (%d) sent by BGP peer %s\n", LOG(1, 0, 0, "Bad version (%d) sent by BGP peer %s\n",
(int) data.version, peer->name); (int) data.version, peer->name);
bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_OPN_VERSION); bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_OPN_VERSION);
@ -896,7 +896,7 @@ static int bgp_handle_input(struct bgp_peer *peer)
if (ntohs(data.as) != peer->as) if (ntohs(data.as) != peer->as)
{ {
LOG(1, 0, 0, 0, "Bad AS sent by BGP peer %s (got %d, " LOG(1, 0, 0, "Bad AS sent by BGP peer %s (got %d, "
"expected %d)\n", peer->name, (int) htons(data.as), "expected %d)\n", peer->name, (int) htons(data.as),
(int) peer->as); (int) peer->as);
@ -906,7 +906,7 @@ static int bgp_handle_input(struct bgp_peer *peer)
if ((hold = ntohs(data.hold_time)) < 3) if ((hold = ntohs(data.hold_time)) < 3)
{ {
LOG(1, 0, 0, 0, "Bad hold time (%d) from BGP peer %s\n", LOG(1, 0, 0, "Bad hold time (%d) from BGP peer %s\n",
hold, peer->name); hold, peer->name);
bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_OPN_HOLD_TIME); bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_OPN_HOLD_TIME);
@ -939,7 +939,7 @@ static int bgp_handle_input(struct bgp_peer *peer)
peer->retry_count = 0; peer->retry_count = 0;
peer->retry_time = 0; peer->retry_time = 0;
LOG(4, 0, 0, 0, "BGP peer %s: state Established\n", peer->name); LOG(4, 0, 0, "BGP peer %s: state Established\n", peer->name);
} }
break; break;
@ -952,13 +952,13 @@ static int bgp_handle_input(struct bgp_peer *peer)
if (notification->error_code == BGP_ERR_CEASE) if (notification->error_code == BGP_ERR_CEASE)
{ {
LOG(4, 0, 0, 0, "BGP peer %s sent CEASE\n", peer->name); LOG(4, 0, 0, "BGP peer %s sent CEASE\n", peer->name);
bgp_halt(peer); bgp_halt(peer);
return 0; return 0;
} }
/* FIXME: should handle more notifications */ /* FIXME: should handle more notifications */
LOG(4, 0, 0, 0, "BGP peer %s sent unhandled NOTIFICATION %d\n", LOG(4, 0, 0, "BGP peer %s sent unhandled NOTIFICATION %d\n",
peer->name, (int) notification->error_code); peer->name, (int) notification->error_code);
} }
@ -1077,8 +1077,8 @@ static int bgp_send_update(struct bgp_peer *peer)
unf_len += s; unf_len += s;
len += s; len += s;
LOG(5, 0, 0, 0, "Withdrawing route %s/%d from BGP peer %s\n", LOG(5, 0, 0, "Withdrawing route %s/%d from BGP peer %s\n",
inet_toa(tmp->dest.prefix), tmp->dest.len, peer->name); fmtaddr(tmp->dest.prefix, 0), tmp->dest.len, peer->name);
free(tmp); free(tmp);
@ -1127,8 +1127,8 @@ static int bgp_send_update(struct bgp_peer *peer)
{ {
if (!(e = malloc(sizeof(*e)))) if (!(e = malloc(sizeof(*e))))
{ {
LOG(0, 0, 0, 0, "Can't allocate route for %s/%d (%s)\n", LOG(0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
inet_toa(add->dest.prefix), add->dest.len, strerror(errno)); fmtaddr(add->dest.prefix, 0), add->dest.len, strerror(errno));
return 0; return 0;
} }
@ -1151,8 +1151,8 @@ static int bgp_send_update(struct bgp_peer *peer)
data += s; data += s;
len += s; len += s;
LOG(5, 0, 0, 0, "Advertising route %s/%d to BGP peer %s\n", LOG(5, 0, 0, "Advertising route %s/%d to BGP peer %s\n",
inet_toa(add->dest.prefix), add->dest.len, peer->name); fmtaddr(add->dest.prefix, 0), add->dest.len, peer->name);
} }
else else
{ {

190
cli.c
View file

@ -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.33 2004-11-28 20:09:53 bodea Exp $"; char const *cvs_id_cli = "$Id: cli.c,v 1.34 2004-11-29 02:17:17 bodea Exp $";
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
@ -117,6 +117,7 @@ static int cmd_no_ip_access_list(struct cli_def *cli, char *command, char **argv
static int cmd_ip_access_list_rule(struct cli_def *cli, char *command, char **argv, int argc); static int cmd_ip_access_list_rule(struct cli_def *cli, char *command, char **argv, int argc);
static int cmd_filter(struct cli_def *cli, char *command, char **argv, int argc); static int cmd_filter(struct cli_def *cli, char *command, char **argv, int argc);
static int cmd_no_filter(struct cli_def *cli, char *command, char **argv, int argc); static int cmd_no_filter(struct cli_def *cli, char *command, char **argv, int argc);
static int cmd_show_access_list(struct cli_def *cli, char *command, char **argv, int argc);
/* match if b is a substr of a */ /* match if b is a substr of a */
#define MATCH(a,b) (!strncmp((a), (b), strlen(b))) #define MATCH(a,b) (!strncmp((a), (b), strlen(b)))
@ -153,6 +154,7 @@ void init_cli(char *hostname)
cli_register_command(cli, c, "tunnels", cmd_show_tunnels, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show a list of tunnels or details for a single tunnel"); cli_register_command(cli, c, "tunnels", cmd_show_tunnels, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show a list of tunnels or details for a single tunnel");
cli_register_command(cli, c, "users", cmd_show_users, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show a list of all connected users or details of selected user"); cli_register_command(cli, c, "users", cmd_show_users, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show a list of all connected users or details of selected user");
cli_register_command(cli, c, "version", cmd_show_version, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show currently running software version"); cli_register_command(cli, c, "version", cmd_show_version, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show currently running software version");
cli_register_command(cli, c, "access-list", cmd_show_access_list, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show named access-list");
c2 = cli_register_command(cli, c, "histogram", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL); c2 = cli_register_command(cli, c, "histogram", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
cli_register_command(cli, c2, "idle", cmd_show_hist_idle, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show histogram of session idle times"); cli_register_command(cli, c2, "idle", cmd_show_hist_idle, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show histogram of session idle times");
@ -231,7 +233,7 @@ void init_cli(char *hostname)
if (!(f = fopen(CLIUSERS, "r"))) if (!(f = fopen(CLIUSERS, "r")))
{ {
LOG(0, 0, 0, 0, "WARNING! No users specified. Command-line access is open to all\n"); LOG(0, 0, 0, "WARNING! No users specified. Command-line access is open to all\n");
} }
else else
{ {
@ -247,12 +249,12 @@ void init_cli(char *hostname)
if (!strcmp(buf, "enable")) if (!strcmp(buf, "enable"))
{ {
cli_allow_enable(cli, p); cli_allow_enable(cli, p);
LOG(3, 0, 0, 0, "Setting enable password\n"); LOG(3, 0, 0, "Setting enable password\n");
} }
else else
{ {
cli_allow_user(cli, buf, p); cli_allow_user(cli, buf, p);
LOG(3, 0, 0, 0, "Allowing user %s to connect to the CLI\n", buf); LOG(3, 0, 0, "Allowing user %s to connect to the CLI\n", buf);
} }
} }
fclose(f); fclose(f);
@ -271,7 +273,7 @@ void init_cli(char *hostname)
addr.sin_port = htons(23); addr.sin_port = htons(23);
if (bind(clifd, (void *) &addr, sizeof(addr)) < 0) if (bind(clifd, (void *) &addr, sizeof(addr)) < 0)
{ {
LOG(0, 0, 0, 0, "Error listening on cli port 23: %s\n", strerror(errno)); LOG(0, 0, 0, "Error listening on cli port 23: %s\n", strerror(errno));
return; return;
} }
listen(clifd, 10); listen(clifd, 10);
@ -286,18 +288,18 @@ void cli_do(int sockfd)
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)
{ {
LOG(3, 0, 0, 0, "Accepted connection to CLI from %s\n", inet_toa(addr.sin_addr.s_addr)); LOG(3, 0, 0, "Accepted connection to CLI from %s\n", fmtaddr(addr.sin_addr.s_addr, 0));
require_auth = addr.sin_addr.s_addr != inet_addr("127.0.0.1"); require_auth = addr.sin_addr.s_addr != inet_addr("127.0.0.1");
} }
else else
LOG(0, 0, 0, 0, "getpeername() failed on cli socket. Requiring authentication: %s\n", strerror(errno)); LOG(0, 0, 0, "getpeername() failed on cli socket. Requiring authentication: %s\n", strerror(errno));
if (require_auth) if (require_auth)
{ {
LOG(3, 0, 0, 0, "CLI is remote, requiring authentication\n"); LOG(3, 0, 0, "CLI is remote, requiring authentication\n");
if (!cli->users) /* paranoia */ if (!cli->users) /* paranoia */
{ {
LOG(0, 0, 0, 0, "No users for remote authentication! Exiting CLI\n"); LOG(0, 0, 0, "No users for remote authentication! Exiting CLI\n");
exit(0); exit(0);
} }
} }
@ -318,18 +320,18 @@ void cli_do(int sockfd)
cli_loop(cli, sockfd); cli_loop(cli, sockfd);
close(sockfd); close(sockfd);
LOG(3, 0, 0, 0, "Closed CLI connection from %s\n", inet_toa(addr.sin_addr.s_addr)); LOG(3, 0, 0, "Closed CLI connection from %s\n", fmtaddr(addr.sin_addr.s_addr, 0));
exit(0); exit(0);
} }
static void cli_print_log(struct cli_def *cli, char *string) static void cli_print_log(struct cli_def *cli, char *string)
{ {
LOG(3, 0, 0, 0, "%s\n", string); LOG(3, 0, 0, "%s\n", string);
} }
void cli_do_file(FILE *fh) void cli_do_file(FILE *fh)
{ {
LOG(3, 0, 0, 0, "Reading configuration file\n"); LOG(3, 0, 0, "Reading configuration file\n");
cli_print_callback(cli, cli_print_log); cli_print_callback(cli, cli_print_log);
cli_file(cli, fh, PRIVILEGE_PRIVILEGED, MODE_CONFIG); cli_file(cli, fh, PRIVILEGE_PRIVILEGED, MODE_CONFIG);
cli_print_callback(cli, NULL); cli_print_callback(cli, NULL);
@ -398,7 +400,7 @@ 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, "\tIP address:\t%s", inet_toa(htonl(session[s].ip))); cli_print(cli, "\tIP address:\t%s", fmtaddr(htonl(session[s].ip), 0));
cli_print(cli, "\tUnique SID:\t%lu", session[s].unique_id); cli_print(cli, "\tUnique SID:\t%lu", session[s].unique_id);
cli_print(cli, "\tIdle time:\t%u seconds", abs(time_now - session[s].last_packet)); cli_print(cli, "\tIdle time:\t%u seconds", abs(time_now - session[s].last_packet));
cli_print(cli, "\tNext Recv:\t%u", session[s].nr); cli_print(cli, "\tNext Recv:\t%u", session[s].nr);
@ -414,7 +416,7 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
if (session[s].filter_out && session[s].filter_out <= MAXFILTER) if (session[s].filter_out && session[s].filter_out <= MAXFILTER)
cli_print(cli, "\tFilter out:\t%u (%s)", session[s].filter_out, ip_filters[session[s].filter_out - 1].name); cli_print(cli, "\tFilter out:\t%u (%s)", session[s].filter_out, ip_filters[session[s].filter_out - 1].name);
if (session[s].snoop_ip && session[s].snoop_port) if (session[s].snoop_ip && session[s].snoop_port)
cli_print(cli, "\tIntercepted:\t%s:%d", inet_toa(session[s].snoop_ip), session[s] .snoop_port); cli_print(cli, "\tIntercepted:\t%s:%d", fmtaddr(session[s].snoop_ip, 0), session[s] .snoop_port);
else else
cli_print(cli, "\tIntercepted:\tno"); cli_print(cli, "\tIntercepted:\tno");
@ -488,15 +490,12 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
for (i = 1; i < MAXSESSION; i++) for (i = 1; i < MAXSESSION; i++)
{ {
char *userip, *tunnelip;
if (!session[i].opened) continue; if (!session[i].opened) continue;
userip = strdup(inet_toa(htonl(session[i].ip)));
tunnelip = strdup(inet_toa(htonl(tunnel[ session[i].tunnel ].ip)));
cli_print(cli, "%5d %4d %-32s %-15s %s %s %s %10u %10lu %10lu %4u %-15s %s", cli_print(cli, "%5d %4d %-32s %-15s %s %s %s %10u %10lu %10lu %4u %-15s %s",
i, i,
session[i].tunnel, session[i].tunnel,
session[i].user[0] ? session[i].user : "*", session[i].user[0] ? session[i].user : "*",
userip, fmtaddr(htonl(session[i].ip), 0),
(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",
@ -504,10 +503,8 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
(unsigned long)session[i].total_cout, (unsigned long)session[i].total_cout,
(unsigned long)session[i].total_cin, (unsigned long)session[i].total_cin,
abs(time_now - (session[i].last_packet ? session[i].last_packet : time_now)), abs(time_now - (session[i].last_packet ? session[i].last_packet : time_now)),
tunnelip, fmtaddr(htonl(tunnel[ session[i].tunnel ].ip), 1),
session[i].calling[0] ? session[i].calling : "*"); session[i].calling[0] ? session[i].calling : "*");
if (userip) free(userip);
if (tunnelip) free(tunnelip);
} }
return CLI_OK; return CLI_OK;
} }
@ -558,7 +555,7 @@ static int cmd_show_tunnels(struct cli_def *cli, char *command, char **argv, int
cli_print(cli, "\r\nTunnel %d:", t); cli_print(cli, "\r\nTunnel %d:", t);
cli_print(cli, "\tState:\t\t%s", states[tunnel[t].state]); cli_print(cli, "\tState:\t\t%s", states[tunnel[t].state]);
cli_print(cli, "\tHostname:\t%s", tunnel[t].hostname[0] ? tunnel[t].hostname : "(none)"); cli_print(cli, "\tHostname:\t%s", tunnel[t].hostname[0] ? tunnel[t].hostname : "(none)");
cli_print(cli, "\tRemote IP:\t%s", inet_toa(htonl(tunnel[t].ip))); cli_print(cli, "\tRemote IP:\t%s", fmtaddr(htonl(tunnel[t].ip), 0));
cli_print(cli, "\tRemote Port:\t%d", tunnel[t].port); cli_print(cli, "\tRemote Port:\t%d", tunnel[t].port);
cli_print(cli, "\tRx Window:\t%u", tunnel[t].window); cli_print(cli, "\tRx Window:\t%u", tunnel[t].window);
cli_print(cli, "\tNext Recv:\t%u", tunnel[t].nr); cli_print(cli, "\tNext Recv:\t%u", tunnel[t].nr);
@ -593,7 +590,7 @@ static int cmd_show_tunnels(struct cli_def *cli, char *command, char **argv, int
cli_print(cli, "%4d %20s %20s %6s %6d", cli_print(cli, "%4d %20s %20s %6s %6d",
i, i,
*tunnel[i].hostname ? tunnel[i].hostname : "(null)", *tunnel[i].hostname ? tunnel[i].hostname : "(null)",
inet_toa(htonl(tunnel[i].ip)), fmtaddr(htonl(tunnel[i].ip), 0),
states[tunnel[i].state], states[tunnel[i].state],
sessions); sessions);
} }
@ -802,7 +799,9 @@ static int cmd_show_pool(struct cli_def *cli, char *command, char **argv, int ar
if (!config->cluster_iam_master) if (!config->cluster_iam_master)
{ {
cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address)); cli_print(cli, "Can't do this on a slave. Do it on %s",
fmtaddr(config->cluster_master_address, 0));
return CLI_OK; return CLI_OK;
} }
@ -827,7 +826,9 @@ static int cmd_show_pool(struct cli_def *cli, char *command, char **argv, int ar
if (ip_address_pool[i].assigned) if (ip_address_pool[i].assigned)
{ {
cli_print(cli, "%-15s\tY %8d %s", cli_print(cli, "%-15s\tY %8d %s",
inet_toa(htonl(ip_address_pool[i].address)), ip_address_pool[i].session, session[ip_address_pool[i].session].user); fmtaddr(htonl(ip_address_pool[i].address), 0),
ip_address_pool[i].session,
session[ip_address_pool[i].session].user);
used++; used++;
} }
@ -835,10 +836,11 @@ static int cmd_show_pool(struct cli_def *cli, char *command, char **argv, int ar
{ {
if (ip_address_pool[i].last) if (ip_address_pool[i].last)
cli_print(cli, "%-15s\tN %8s [%s] %ds", cli_print(cli, "%-15s\tN %8s [%s] %ds",
inet_toa(htonl(ip_address_pool[i].address)), "", fmtaddr(htonl(ip_address_pool[i].address), 0), "",
ip_address_pool[i].user, time_now - ip_address_pool[i].last); ip_address_pool[i].user, time_now - ip_address_pool[i].last);
else if (show_all) else if (show_all)
cli_print(cli, "%-15s\tN", inet_toa(htonl(ip_address_pool[i].address))); cli_print(cli, "%-15s\tN", fmtaddr(htonl(ip_address_pool[i].address), 0));
free++; free++;
} }
@ -896,7 +898,7 @@ static int cmd_show_run(struct cli_def *cli, char *command, char **argv, int arg
if (config_values[i].type == STRING) if (config_values[i].type == STRING)
cli_print(cli, "set %s \"%.*s\"", config_values[i].key, config_values[i].size, (char *)value); cli_print(cli, "set %s \"%.*s\"", config_values[i].key, config_values[i].size, (char *)value);
else if (config_values[i].type == IP) else if (config_values[i].type == IP)
cli_print(cli, "set %s %s", config_values[i].key, inet_toa(*(unsigned *)value)); cli_print(cli, "set %s %s", config_values[i].key, fmtaddr(*(unsigned *)value, 0));
else if (config_values[i].type == SHORT) else if (config_values[i].type == SHORT)
cli_print(cli, "set %s %hu", config_values[i].key, *(short *)value); cli_print(cli, "set %s %hu", config_values[i].key, *(short *)value);
else if (config_values[i].type == BOOL) else if (config_values[i].type == BOOL)
@ -1123,7 +1125,9 @@ static int cmd_drop_user(struct cli_def *cli, char *command, char **argv, int ar
if (!config->cluster_iam_master) if (!config->cluster_iam_master)
{ {
cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address)); cli_print(cli, "Can't do this on a slave. Do it on %s",
fmtaddr(config->cluster_master_address, 0));
return CLI_OK; return CLI_OK;
} }
@ -1162,7 +1166,9 @@ static int cmd_drop_tunnel(struct cli_def *cli, char *command, char **argv, int
if (!config->cluster_iam_master) if (!config->cluster_iam_master)
{ {
cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address)); cli_print(cli, "Can't do this on a slave. Do it on %s",
fmtaddr(config->cluster_master_address, 0));
return CLI_OK; return CLI_OK;
} }
@ -1210,7 +1216,9 @@ static int cmd_drop_session(struct cli_def *cli, char *command, char **argv, int
if (!config->cluster_iam_master) if (!config->cluster_iam_master)
{ {
cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address)); cli_print(cli, "Can't do this on a slave. Do it on %s",
fmtaddr(config->cluster_master_address, 0));
return CLI_OK; return CLI_OK;
} }
@ -1275,7 +1283,9 @@ static int cmd_snoop(struct cli_def *cli, char *command, char **argv, int argc)
if (!config->cluster_iam_master) if (!config->cluster_iam_master)
{ {
cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address)); cli_print(cli, "Can't do this on a slave. Do it on %s",
fmtaddr(config->cluster_master_address, 0));
return CLI_OK; return CLI_OK;
} }
@ -1305,7 +1315,7 @@ static int cmd_snoop(struct cli_def *cli, char *command, char **argv, int argc)
return CLI_OK; return CLI_OK;
} }
cli_print(cli, "Snooping user %s to %s:%d", argv[0], inet_toa(ip), port); cli_print(cli, "Snooping user %s to %s:%d", argv[0], fmtaddr(ip, 0), port);
cli_session_actions[s].snoop_ip = ip; cli_session_actions[s].snoop_ip = ip;
cli_session_actions[s].snoop_port = port; cli_session_actions[s].snoop_port = port;
cli_session_actions[s].action |= CLI_SESS_SNOOP; cli_session_actions[s].action |= CLI_SESS_SNOOP;
@ -1324,7 +1334,9 @@ static int cmd_no_snoop(struct cli_def *cli, char *command, char **argv, int arg
if (!config->cluster_iam_master) if (!config->cluster_iam_master)
{ {
cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address)); cli_print(cli, "Can't do this on a slave. Do it on %s",
fmtaddr(config->cluster_master_address, 0));
return CLI_OK; return CLI_OK;
} }
@ -1396,7 +1408,9 @@ static int cmd_throttle(struct cli_def *cli, char *command, char **argv, int arg
if (!config->cluster_iam_master) if (!config->cluster_iam_master)
{ {
cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address)); cli_print(cli, "Can't do this on a slave. Do it on %s",
fmtaddr(config->cluster_master_address, 0));
return CLI_OK; return CLI_OK;
} }
@ -1486,7 +1500,9 @@ static int cmd_no_throttle(struct cli_def *cli, char *command, char **argv, int
if (!config->cluster_iam_master) if (!config->cluster_iam_master)
{ {
cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address)); cli_print(cli, "Can't do this on a slave. Do it on %s",
fmtaddr(config->cluster_master_address, 0));
return CLI_OK; return CLI_OK;
} }
@ -1866,16 +1882,8 @@ int regular_stuff(struct cli_def *cli)
if (show_message) if (show_message)
{ {
ipt address = htonl(ringbuffer->buffer[i].address); cli_print(cli, "\r%s-%u-%u %s",
char *ipaddr;
struct in_addr addr;
memcpy(&addr, &address, sizeof(ringbuffer->buffer[i].address));
ipaddr = inet_ntoa(addr);
cli_print(cli, "\r%s-%s-%u-%u %s",
debug_levels[(int)ringbuffer->buffer[i].level], debug_levels[(int)ringbuffer->buffer[i].level],
ipaddr,
ringbuffer->buffer[i].tunnel, ringbuffer->buffer[i].tunnel,
ringbuffer->buffer[i].session, ringbuffer->buffer[i].session,
ringbuffer->buffer[i].message); ringbuffer->buffer[i].message);
@ -2128,7 +2136,7 @@ static int cmd_show_bgp(struct cli_def *cli, char *command, char **argv, int arg
NULL); NULL);
cli_print(cli, "BGPv%d router identifier %s, local AS number %d", cli_print(cli, "BGPv%d router identifier %s, local AS number %d",
BGP_VERSION, inet_toa(my_address), (int) config->as_number); BGP_VERSION, fmtaddr(my_address, 0), (int) config->as_number);
time(&time_now); time(&time_now);
@ -2137,7 +2145,7 @@ static int cmd_show_bgp(struct cli_def *cli, char *command, char **argv, int arg
if (!*bgp_peers[i].name) if (!*bgp_peers[i].name)
continue; continue;
addr = inet_toa(bgp_peers[i].addr); addr = fmtaddr(bgp_peers[i].addr, 0);
if (argc && strcmp(addr, argv[0]) && if (argc && strcmp(addr, argv[0]) &&
strncmp(bgp_peers[i].name, argv[0], strlen(argv[0]))) strncmp(bgp_peers[i].name, argv[0], strlen(argv[0])))
continue; continue;
@ -2189,7 +2197,7 @@ static int cmd_suspend_bgp(struct cli_def *cli, char *command, char **argv, int
if (!bgp_peers[i].routing) if (!bgp_peers[i].routing)
continue; continue;
addr = inet_toa(bgp_peers[i].addr); addr = fmtaddr(bgp_peers[i].addr, 0);
if (argc && strcmp(addr, argv[0]) && strcmp(bgp_peers[i].name, argv[0])) if (argc && strcmp(addr, argv[0]) && strcmp(bgp_peers[i].name, argv[0]))
continue; continue;
@ -2222,7 +2230,7 @@ static int cmd_no_suspend_bgp(struct cli_def *cli, char *command, char **argv, i
if (bgp_peers[i].routing) if (bgp_peers[i].routing)
continue; continue;
addr = inet_toa(bgp_peers[i].addr); addr = fmtaddr(bgp_peers[i].addr, 0);
if (argc && strcmp(addr, argv[0]) && if (argc && strcmp(addr, argv[0]) &&
strncmp(bgp_peers[i].name, argv[0], strlen(argv[0]))) strncmp(bgp_peers[i].name, argv[0], strlen(argv[0])))
continue; continue;
@ -2253,7 +2261,7 @@ static int cmd_restart_bgp(struct cli_def *cli, char *command, char **argv, int
if (!*bgp_peers[i].name) if (!*bgp_peers[i].name)
continue; continue;
addr = inet_toa(bgp_peers[i].addr); addr = fmtaddr(bgp_peers[i].addr, 0);
if (argc && strcmp(addr, argv[0]) && if (argc && strcmp(addr, argv[0]) &&
strncmp(bgp_peers[i].name, argv[0], strlen(argv[0]))) strncmp(bgp_peers[i].name, argv[0], strlen(argv[0])))
continue; continue;
@ -2385,15 +2393,13 @@ static int cmd_no_ip_access_list(struct cli_def *cli, char *command, char **argv
static int show_ip_wild(char *buf, ipt ip, ipt wild) static int show_ip_wild(char *buf, ipt ip, ipt wild)
{ {
int i;
if (ip == INADDR_ANY && wild == INADDR_BROADCAST) if (ip == INADDR_ANY && wild == INADDR_BROADCAST)
return sprintf(buf, " any"); return sprintf(buf, " any");
if (wild == INADDR_ANY) if (wild == INADDR_ANY)
return sprintf(buf, " host %s", inet_toa(ip)); return sprintf(buf, " host %s", fmtaddr(ip, 0));
i = sprintf(buf, " %s", inet_toa(ip)); return sprintf(buf, " %s %s", fmtaddr(ip, 0), fmtaddr(wild, 1));
return i + sprintf(buf + i, " %s", inet_toa(wild));
} }
static int show_ports(char *buf, ip_filter_portt *ports) static int show_ports(char *buf, ip_filter_portt *ports)
@ -2435,14 +2441,14 @@ static char const *show_access_list_rule(int extended, ip_filter_rulet *rule)
if (rule->proto == IPPROTO_TCP && rule->tcp_flag_op) if (rule->proto == IPPROTO_TCP && rule->tcp_flag_op)
{ {
if (rule->tcp_flag_op == FILTER_FLAG_OP_ANY && switch (rule->tcp_flag_op)
rule->tcp_sflags == (TCP_FLAG_ACK|TCP_FLAG_RST) &&
rule->tcp_cflags == TCP_FLAG_SYN)
{ {
case FILTER_FLAG_OP_EST:
p += sprintf(p, " established"); p += sprintf(p, " established");
} break;
else
{ case FILTER_FLAG_OP_ANY:
case FILTER_FLAG_OP_ALL:
p += sprintf(p, " match-%s", rule->tcp_flag_op == FILTER_FLAG_OP_ALL ? "all" : "any"); p += sprintf(p, " match-%s", rule->tcp_flag_op == FILTER_FLAG_OP_ALL ? "all" : "any");
if (rule->tcp_sflags & TCP_FLAG_FIN) p += sprintf(p, " +fin"); if (rule->tcp_sflags & TCP_FLAG_FIN) p += sprintf(p, " +fin");
if (rule->tcp_cflags & TCP_FLAG_FIN) p += sprintf(p, " -fin"); if (rule->tcp_cflags & TCP_FLAG_FIN) p += sprintf(p, " -fin");
@ -2456,9 +2462,13 @@ static char const *show_access_list_rule(int extended, ip_filter_rulet *rule)
if (rule->tcp_cflags & TCP_FLAG_ACK) p += sprintf(p, " -ack"); if (rule->tcp_cflags & TCP_FLAG_ACK) p += sprintf(p, " -ack");
if (rule->tcp_sflags & TCP_FLAG_URG) p += sprintf(p, " +urg"); if (rule->tcp_sflags & TCP_FLAG_URG) p += sprintf(p, " +urg");
if (rule->tcp_cflags & TCP_FLAG_URG) p += sprintf(p, " -urg"); if (rule->tcp_cflags & TCP_FLAG_URG) p += sprintf(p, " -urg");
break;
} }
} }
if (rule->frag)
p += sprintf(p, " fragments");
return buf; return buf;
} }
@ -2637,9 +2647,7 @@ ip_filter_rulet *access_list_rule_ext(struct cli_def *cli, char *command, char *
{ {
if (MATCH("established", argv[a])) if (MATCH("established", argv[a]))
{ {
rule.tcp_flag_op = FILTER_FLAG_OP_ANY; rule.tcp_flag_op = FILTER_FLAG_OP_EST;
rule.tcp_sflags = (TCP_FLAG_ACK|TCP_FLAG_RST);
rule.tcp_cflags = TCP_FLAG_SYN;
a++; a++;
} }
else if (!strcmp(argv[a], "match-any") || !strcmp(argv[a], "match-an") || else if (!strcmp(argv[a], "match-any") || !strcmp(argv[a], "match-an") ||
@ -2678,6 +2686,12 @@ ip_filter_rulet *access_list_rule_ext(struct cli_def *cli, char *command, char *
} }
} }
if (a < argc && MATCH("fragments", argv[a]))
{
rule.frag = 1;
a++;
}
if (a < argc) if (a < argc)
{ {
cli_print(cli, "Invalid flag \"%s\"", argv[a]); cli_print(cli, "Invalid flag \"%s\"", argv[a]);
@ -2861,7 +2875,9 @@ static int cmd_filter(struct cli_def *cli, char *command, char **argv, int argc)
if (!config->cluster_iam_master) if (!config->cluster_iam_master)
{ {
cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address)); cli_print(cli, "Can't do this on a slave. Do it on %s",
fmtaddr(config->cluster_master_address, 0));
return CLI_OK; return CLI_OK;
} }
@ -2934,7 +2950,9 @@ static int cmd_no_filter(struct cli_def *cli, char *command, char **argv, int ar
if (!config->cluster_iam_master) if (!config->cluster_iam_master)
{ {
cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address)); cli_print(cli, "Can't do this on a slave. Do it on %s",
fmtaddr(config->cluster_master_address, 0));
return CLI_OK; return CLI_OK;
} }
@ -2966,6 +2984,48 @@ static int cmd_no_filter(struct cli_def *cli, char *command, char **argv, int ar
return CLI_OK; return CLI_OK;
} }
static int cmd_show_access_list(struct cli_def *cli, char *command, char **argv, int argc)
{
int i;
if (CLI_HELP_REQUESTED)
return cli_arg_help(cli, argc > 1, "NAME", "Filter name", NULL);
if (argc < 1)
{
cli_print(cli, "Specify a filter name");
return CLI_OK;
}
for (i = 0; i < argc; i++)
{
int f = find_access_list(argv[i]);
ip_filter_rulet *rules;
if (f < 0 || !*ip_filters[f].name)
{
cli_print(cli, "Access-list %s not defined", argv[i]);
return CLI_OK;
}
cli_print(cli, "%s IP access list %s",
ip_filters[f].extended ? "Extended" : "Standard",
ip_filters[f].name);
for (rules = ip_filters[f].rules; rules->action; rules++)
{
char const *r = show_access_list_rule(ip_filters[f].extended, rules);
if (rules->counter)
cli_print(cli, "%s (%d match%s)", r,
rules->counter, rules->counter > 1 ? "es" : "");
else
cli_print(cli, "%s", r);
}
}
return CLI_OK;
}
// Convert a string in the form of abcd.ef12.3456 into char[6] // Convert a string in the form of abcd.ef12.3456 into char[6]
void parsemac(char *string, char mac[6]) void parsemac(char *string, char mac[6])
{ {

170
cluster.c
View file

@ -1,6 +1,6 @@
// L2TPNS Clustering Stuff // L2TPNS Clustering Stuff
char const *cvs_id_cluster = "$Id: cluster.c,v 1.18 2004-11-16 07:54:32 bodea Exp $"; char const *cvs_id_cluster = "$Id: cluster.c,v 1.19 2004-11-29 02:17:17 bodea Exp $";
#include <stdio.h> #include <stdio.h>
#include <sys/file.h> #include <sys/file.h>
@ -101,14 +101,14 @@ int cluster_init()
if (bind(cluster_sockfd, (void *) &addr, sizeof(addr)) < 0) if (bind(cluster_sockfd, (void *) &addr, sizeof(addr)) < 0)
{ {
LOG(0, 0, 0, 0, "Failed to bind cluster socket: %s\n", strerror(errno)); LOG(0, 0, 0, "Failed to bind cluster socket: %s\n", strerror(errno));
return -1; return -1;
} }
strcpy(ifr.ifr_name, config->cluster_interface); strcpy(ifr.ifr_name, config->cluster_interface);
if (ioctl(cluster_sockfd, SIOCGIFADDR, &ifr) < 0) if (ioctl(cluster_sockfd, SIOCGIFADDR, &ifr) < 0)
{ {
LOG(0, 0, 0, 0, "Failed to get interface address for (%s): %s\n", config->cluster_interface, strerror(errno)); LOG(0, 0, 0, "Failed to get interface address for (%s): %s\n", config->cluster_interface, strerror(errno));
return -1; return -1;
} }
@ -125,13 +125,13 @@ int cluster_init()
if (setsockopt(cluster_sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) if (setsockopt(cluster_sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
{ {
LOG(0, 0, 0, 0, "Failed to setsockopt (join mcast group): %s\n", strerror(errno)); LOG(0, 0, 0, "Failed to setsockopt (join mcast group): %s\n", strerror(errno));
return -1; return -1;
} }
if (setsockopt (cluster_sockfd, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr)) < 0) if (setsockopt (cluster_sockfd, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr)) < 0)
{ {
LOG(0, 0, 0, 0, "Failed to setsockopt (set mcast interface): %s\n", strerror(errno)); LOG(0, 0, 0, "Failed to setsockopt (set mcast interface): %s\n", strerror(errno));
return -1; return -1;
} }
@ -158,11 +158,11 @@ static int cluster_send_data(void *data, int datalen)
addr.sin_port = htons(CLUSTERPORT); addr.sin_port = htons(CLUSTERPORT);
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
LOG(5,0,0,0, "Cluster send data: %d bytes\n", datalen); LOG(5, 0, 0, "Cluster send data: %d bytes\n", datalen);
if (sendto(cluster_sockfd, data, datalen, MSG_NOSIGNAL, (void *) &addr, sizeof(addr)) < 0) if (sendto(cluster_sockfd, data, datalen, MSG_NOSIGNAL, (void *) &addr, sizeof(addr)) < 0)
{ {
LOG(0, 0, 0, 0, "sendto: %s\n", strerror(errno)); LOG(0, 0, 0, "sendto: %s\n", strerror(errno));
return -1; return -1;
} }
@ -210,7 +210,7 @@ static void cluster_uptodate(void)
config->cluster_iam_uptodate = 1; config->cluster_iam_uptodate = 1;
LOG(0,0,0,0, "Now uptodate with master.\n"); LOG(0, 0, 0, "Now uptodate with master.\n");
advertise(); advertise();
} }
@ -236,7 +236,7 @@ static int peer_send_data(u32 peer, char * data, int size)
if (sendto(cluster_sockfd, data, size, MSG_NOSIGNAL, (void *) &addr, sizeof(addr)) < 0) if (sendto(cluster_sockfd, data, size, MSG_NOSIGNAL, (void *) &addr, sizeof(addr)) < 0)
{ {
LOG(0, 0, 0, 0, "sendto: %s\n", strerror(errno)); LOG(0, 0, 0, "sendto: %s\n", strerror(errno));
return -1; return -1;
} }
@ -251,7 +251,7 @@ static int peer_send_message(u32 peer, int type, int more, char * data, int size
char buf[65536]; // Vast overkill. char buf[65536]; // Vast overkill.
char * p = buf; char * p = buf;
LOG(4,0,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);
return peer_send_data(peer, buf, (p-buf) ); return peer_send_data(peer, buf, (p-buf) );
@ -271,7 +271,7 @@ int master_forward_packet(char *data, int size, u32 addr, int port)
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;
LOG(4,0,0,0, "Forwarding packet from %s to master (size %d)\n", inet_toa(addr), size); LOG(4, 0, 0, "Forwarding packet from %s to master (size %d)\n", fmtaddr(addr, 0), size);
STAT(c_forwarded); STAT(c_forwarded);
add_type(&p, C_FORWARD, addr, (char*) &port, sizeof(port) ); add_type(&p, C_FORWARD, addr, (char*) &port, sizeof(port) );
@ -297,7 +297,7 @@ int master_throttle_packet(int tbfid, char *data, int size)
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;
LOG(4,0,0,0, "Throttling packet master (size %d, tbfid %d)\n", size, tbfid); LOG(4, 0, 0, "Throttling packet master (size %d, tbfid %d)\n", size, tbfid);
add_type(&p, C_THROTTLE, tbfid, data, size); add_type(&p, C_THROTTLE, tbfid, data, size);
@ -322,7 +322,7 @@ int master_garden_packet(sessionidt s, char *data, int size)
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;
LOG(4,0,0,0, "Walled garden packet to master (size %d)\n", size); LOG(4, 0, 0, "Walled garden packet to master (size %d)\n", size);
add_type(&p, C_GARDEN, s, data, size); add_type(&p, C_GARDEN, s, data, size);
@ -340,7 +340,7 @@ static void send_heartbeat(int seq, char * data, int size)
if (size > sizeof(past_hearts[0].data)) if (size > sizeof(past_hearts[0].data))
{ {
LOG(0,0,0,0, "Tried to heartbeat something larger than the maximum packet!\n"); LOG(0, 0, 0, "Tried to heartbeat something larger than the maximum packet!\n");
kill(0, SIGTERM); kill(0, SIGTERM);
exit(1); exit(1);
} }
@ -363,7 +363,7 @@ void cluster_send_ping(time_t basetime)
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.
return; return;
LOG(5,0,0,0, "Sending cluster ping...\n"); LOG(5, 0, 0, "Sending cluster ping...\n");
x.ver = 1; x.ver = 1;
x.addr = config->bind_address; x.addr = config->bind_address;
@ -422,7 +422,7 @@ void master_update_counts(void)
// Forward the data to the master. // Forward the data to the master.
LOG(4,0,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, (char*) &b, sizeof(b[0]) * c);
return; return;
} }
@ -491,7 +491,7 @@ void cluster_check_master(void)
if (!probed && config->cluster_master_address) if (!probed && config->cluster_master_address)
{ {
probed = 1; probed = 1;
LOG(1, 0, 0, 0, "Heartbeat from master %.1fs late, probing...\n", LOG(1, 0, 0, "Heartbeat from master %.1fs late, probing...\n",
0.1 * (TIME - (config->cluster_last_hb + config->cluster_hb_interval))); 0.1 * (TIME - (config->cluster_last_hb + config->cluster_hb_interval)));
peer_send_message(config->cluster_master_address, peer_send_message(config->cluster_master_address,
@ -506,7 +506,7 @@ void cluster_check_master(void)
config->cluster_last_hb = TIME + 1; // Just the one election thanks. config->cluster_last_hb = TIME + 1; // Just the one election thanks.
LOG(0,0,0,0, "Master timed out! Holding election...\n"); LOG(0, 0, 0, "Master timed out! Holding election...\n");
for (i = 0; i < num_peers; i++) for (i = 0; i < num_peers; i++)
{ {
@ -517,13 +517,13 @@ void cluster_check_master(void)
continue; // Shutdown peer! Skip them. continue; // Shutdown peer! Skip them.
if (peers[i].basetime < basetime) { if (peers[i].basetime < basetime) {
LOG(1,0,0,0, "Expecting %s to become master\n", inet_toa(peers[i].peer) ); LOG(1, 0, 0, "Expecting %s to become master\n", fmtaddr(peers[i].peer, 0));
return; // They'll win the election. Get out of here. return; // They'll win the election. Get out of here.
} }
if (peers[i].basetime == basetime && if (peers[i].basetime == basetime &&
peers[i].peer > my_address) { peers[i].peer > my_address) {
LOG(1,0,0,0, "Expecting %s to become master\n", inet_toa(peers[i].peer) ); LOG(1, 0, 0, "Expecting %s to become master\n", fmtaddr(peers[i].peer, 0));
return; // They'll win the election. Wait for them to come up. return; // They'll win the election. Wait for them to come up.
} }
} }
@ -535,7 +535,7 @@ void cluster_check_master(void)
config->cluster_iam_master = 1; config->cluster_iam_master = 1;
config->cluster_master_address = 0; config->cluster_master_address = 0;
LOG(0,0,0,0, "I am declaring myself the master!\n"); LOG(0, 0, 0, "I am declaring myself the master!\n");
if (config->cluster_seq_number == -1) if (config->cluster_seq_number == -1)
config->cluster_seq_number = 0; config->cluster_seq_number = 0;
@ -607,7 +607,7 @@ void cluster_check_master(void)
// If we're not the very first master, this is a big issue! // If we're not the very first master, this is a big issue!
if(count>0) if(count>0)
LOG(0,0,0,0, "Warning: Fixed %d uninitialized sessions in becoming master!\n", count); LOG(0, 0, 0, "Warning: Fixed %d uninitialized sessions in becoming master!\n", count);
config->cluster_undefined_sessions = 0; config->cluster_undefined_sessions = 0;
config->cluster_undefined_tunnels = 0; config->cluster_undefined_tunnels = 0;
@ -670,7 +670,7 @@ static void cluster_check_sessions(int highsession, int freesession_ptr, int hig
if (config->cluster_undefined_sessions || config->cluster_undefined_tunnels) { if (config->cluster_undefined_sessions || config->cluster_undefined_tunnels) {
LOG(2,0,0,0, "Cleared undefined sessions/tunnels. %d sess (high %d), %d tunn (high %d)\n", LOG(2, 0, 0, "Cleared undefined sessions/tunnels. %d sess (high %d), %d tunn (high %d)\n",
config->cluster_undefined_sessions, highsession, config->cluster_undefined_tunnels, hightunnel); config->cluster_undefined_sessions, highsession, config->cluster_undefined_tunnels, hightunnel);
return; return;
} }
@ -724,7 +724,7 @@ static int hb_add_type(char **p, int type, int id)
(char*) &tunnel[id], sizeof(tunnelt)); (char*) &tunnel[id], sizeof(tunnelt));
break; break;
default: default:
LOG(0,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);
kill(0, SIGTERM); kill(0, SIGTERM);
exit(1); exit(1);
} }
@ -767,7 +767,7 @@ void cluster_heartbeat()
} }
if (p > (buff + sizeof(buff))) { // Did we somehow manage to overun the buffer? if (p > (buff + sizeof(buff))) { // Did we somehow manage to overun the buffer?
LOG(0,0,0,0, "FATAL: Overran the heartbeat buffer! This is fatal. Exiting. (size %d)\n", p - buff); LOG(0, 0, 0, "FATAL: Overran the heartbeat buffer! This is fatal. Exiting. (size %d)\n", p - buff);
kill(0, SIGTERM); kill(0, SIGTERM);
exit(1); exit(1);
} }
@ -812,14 +812,14 @@ void cluster_heartbeat()
// //
// Did we do something wrong? // Did we do something wrong?
if (p > (buff + sizeof(buff))) { // Did we somehow manage to overun the buffer? if (p > (buff + sizeof(buff))) { // Did we somehow manage to overun the buffer?
LOG(0,0,0,0, "Overran the heartbeat buffer now! This is fatal. Exiting. (size %d)\n", p - buff); LOG(0, 0, 0, "Overran the heartbeat buffer now! This is fatal. Exiting. (size %d)\n", p - buff);
kill(0, SIGTERM); kill(0, SIGTERM);
exit(1); exit(1);
} }
LOG(3,0,0,0, "Sending heartbeat #%d with %d changes (%d x-sess, %d x-tunnels, %d highsess, %d hightun, size %d)\n", LOG(3, 0, 0, "Sending heartbeat #%d with %d changes (%d x-sess, %d x-tunnels, %d highsess, %d hightun, size %d)\n",
h.seq, config->cluster_num_changes, count, tcount, config->cluster_highest_sessionid, h.seq, config->cluster_num_changes, count, tcount, config->cluster_highest_sessionid,
config->cluster_highest_tunnelid, (p-buff)); config->cluster_highest_tunnelid, (p-buff));
config->cluster_num_changes = 0; config->cluster_num_changes = 0;
@ -855,7 +855,7 @@ static int type_changed(int type, int id)
int cluster_send_session(int sid) int cluster_send_session(int sid)
{ {
if (!config->cluster_iam_master) { if (!config->cluster_iam_master) {
LOG(0,0,sid,0, "I'm not a master, but I just tried to change a session!\n"); LOG(0, sid, 0, "I'm not a master, but I just tried to change a session!\n");
return -1; return -1;
} }
@ -866,7 +866,7 @@ int cluster_send_session(int sid)
int cluster_send_tunnel(int tid) int cluster_send_tunnel(int tid)
{ {
if (!config->cluster_iam_master) { if (!config->cluster_iam_master) {
LOG(0,0,0,tid, "I'm not a master, but I just tried to change a tunnel!\n"); LOG(0, 0, tid, "I'm not a master, but I just tried to change a tunnel!\n");
return -1; return -1;
} }
@ -884,14 +884,14 @@ static int cluster_catchup_slave(int seq, u32 slave)
int s; int s;
int diff; int diff;
LOG(1,0,0,0, "Slave %s sent LASTSEEN with seq %d\n", inet_toa(slave), seq); LOG(1, 0, 0, "Slave %s sent LASTSEEN with seq %d\n", fmtaddr(slave, 0), seq);
diff = config->cluster_seq_number - seq; // How many packet do we need to send? diff = config->cluster_seq_number - seq; // How many packet do we need to send?
if (diff < 0) if (diff < 0)
diff += HB_MAX_SEQ; diff += HB_MAX_SEQ;
if (diff >= HB_HISTORY_SIZE) { // Ouch. We don't have the packet to send it! if (diff >= HB_HISTORY_SIZE) { // Ouch. We don't have the packet to send it!
LOG(0,0,0,0, "A slaved asked for message %d when our seq number is %d. Killing it.\n", LOG(0, 0, 0, "A slaved asked for message %d when our seq number is %d. Killing it.\n",
seq, config->cluster_seq_number); seq, config->cluster_seq_number);
return peer_send_message(slave, C_KILL, seq, NULL, 0);// Kill the slave. Nothing else to do. return peer_send_message(slave, C_KILL, seq, NULL, 0);// Kill the slave. Nothing else to do.
} }
@ -900,8 +900,8 @@ static int cluster_catchup_slave(int seq, u32 slave)
while (seq != config->cluster_seq_number) { while (seq != config->cluster_seq_number) {
s = seq%HB_HISTORY_SIZE; s = seq%HB_HISTORY_SIZE;
if (seq != past_hearts[s].seq) { if (seq != past_hearts[s].seq) {
LOG(0,0,0,0, "Tried to re-send heartbeat for %s but %d doesn't match %d! (%d,%d)\n", LOG(0, 0, 0, "Tried to re-send heartbeat for %s but %d doesn't match %d! (%d,%d)\n",
inet_toa(slave), seq, past_hearts[s].seq, s, config->cluster_seq_number); fmtaddr(slave, 0), seq, past_hearts[s].seq, s, config->cluster_seq_number);
return -1; // What to do here!? return -1; // What to do here!?
} }
peer_send_data(slave, past_hearts[s].data, past_hearts[s].size); peer_send_data(slave, past_hearts[s].data, past_hearts[s].size);
@ -934,7 +934,7 @@ static int cluster_add_peer(u32 peer, time_t basetime, pingt *pp, int size)
if (clusterid != config->bind_address) if (clusterid != config->bind_address)
{ {
// Is this for us? // Is this for us?
LOG(4,0,0,0, "Skipping ping from %s (different cluster)\n", inet_toa(peer)); LOG(4, 0, 0, "Skipping ping from %s (different cluster)\n", fmtaddr(peer, 0));
return 0; return 0;
} }
@ -952,7 +952,7 @@ static int cluster_add_peer(u32 peer, time_t basetime, pingt *pp, int size)
// Is this the master shutting down?? // Is this the master shutting down??
if (peer == config->cluster_master_address && !basetime) { if (peer == config->cluster_master_address && !basetime) {
LOG(3,0,0,0, "Master %s shutting down...\n", inet_toa(config->cluster_master_address)); LOG(3, 0, 0, "Master %s shutting down...\n", fmtaddr(config->cluster_master_address, 0));
config->cluster_master_address = 0; config->cluster_master_address = 0;
config->cluster_last_hb = 0; // Force an election. config->cluster_last_hb = 0; // Force an election.
cluster_check_master(); cluster_check_master();
@ -961,7 +961,7 @@ static int cluster_add_peer(u32 peer, time_t basetime, pingt *pp, int size)
if (i >= num_peers) if (i >= num_peers)
{ {
LOG(4,0,0,0, "Adding %s as a peer\n", inet_toa(peer)); LOG(4, 0, 0, "Adding %s as a peer\n", fmtaddr(peer, 0));
// Not found. Is there a stale slot to re-use? // Not found. Is there a stale slot to re-use?
for (i = 0; i < num_peers ; ++i) for (i = 0; i < num_peers ; ++i)
@ -976,7 +976,7 @@ static int cluster_add_peer(u32 peer, time_t basetime, pingt *pp, int size)
if (i >= CLUSTER_MAX_SIZE) if (i >= CLUSTER_MAX_SIZE)
{ {
// Too many peers!! // Too many peers!!
LOG(0,0,0,0, "Tried to add %s as a peer, but I already have %d of them!\n", inet_toa(peer), i); LOG(0, 0, 0, "Tried to add %s as a peer, but I already have %d of them!\n", fmtaddr(peer, 0), i);
return -1; return -1;
} }
@ -987,7 +987,7 @@ static int cluster_add_peer(u32 peer, time_t basetime, pingt *pp, int size)
if (i == num_peers) if (i == num_peers)
++num_peers; ++num_peers;
LOG(1,0,0,0, "Added %s as a new peer. Now %d peers\n", inet_toa(peer), num_peers); LOG(1, 0, 0, "Added %s as a new peer. Now %d peers\n", fmtaddr(peer, 0), num_peers);
} }
return 1; return 1;
@ -1004,14 +1004,14 @@ static int cluster_handle_bytes(char * data, int size)
b = (bytest*) data; b = (bytest*) data;
LOG(3,0,0,0, "Got byte counter update (size %d)\n", size); LOG(3, 0, 0, "Got byte counter update (size %d)\n", size);
/* Loop around, adding the byte /* Loop around, adding the byte
counts to each of the sessions. */ counts to each of the sessions. */
while (size >= sizeof(*b) ) { while (size >= sizeof(*b) ) {
if (b->sid > MAXSESSION) { if (b->sid > MAXSESSION) {
LOG(0,0,0,0, "Got C_BYTES with session #%d!\n", b->sid); LOG(0, 0, 0, "Got C_BYTES with session #%d!\n", b->sid);
return -1; /* Abort processing */ return -1; /* Abort processing */
} }
@ -1027,7 +1027,7 @@ static int cluster_handle_bytes(char * data, int size)
} }
if (size != 0) if (size != 0)
LOG(0,0,0,0, "Got C_BYTES with %d bytes of trailing junk!\n", size); LOG(0, 0, 0, "Got C_BYTES with %d bytes of trailing junk!\n", size);
return size; return size;
} }
@ -1038,13 +1038,13 @@ static int cluster_handle_bytes(char * data, int size)
static int cluster_recv_session(int more , u8 * p) static int cluster_recv_session(int more , u8 * p)
{ {
if (more >= MAXSESSION) { if (more >= MAXSESSION) {
LOG(0,0,0,0, "DANGER: Received a heartbeat session id > MAXSESSION!\n"); LOG(0, 0, 0, "DANGER: Received a heartbeat session id > MAXSESSION!\n");
return -1; return -1;
} }
if (session[more].tunnel == T_UNDEF) { if (session[more].tunnel == T_UNDEF) {
if (config->cluster_iam_uptodate) { // Sanity. if (config->cluster_iam_uptodate) { // Sanity.
LOG(0,0,0,0, "I thought I was uptodate but I just found an undefined session!\n"); LOG(0, 0, 0, "I thought I was uptodate but I just found an undefined session!\n");
} else { } else {
--config->cluster_undefined_sessions; --config->cluster_undefined_sessions;
} }
@ -1052,7 +1052,7 @@ static int cluster_recv_session(int more , u8 * p)
load_session(more, (sessiont*) p); // Copy session into session table.. load_session(more, (sessiont*) p); // Copy session into session table..
LOG(5,0,more,0, "Received session update (%d undef)\n", config->cluster_undefined_sessions); LOG(5, more, 0, "Received session update (%d undef)\n", config->cluster_undefined_sessions);
if (!config->cluster_iam_uptodate) if (!config->cluster_iam_uptodate)
cluster_uptodate(); // Check to see if we're up to date. cluster_uptodate(); // Check to see if we're up to date.
@ -1063,13 +1063,13 @@ static int cluster_recv_session(int more , u8 * p)
static int cluster_recv_tunnel(int more, u8 *p) static int cluster_recv_tunnel(int more, u8 *p)
{ {
if (more >= MAXTUNNEL) { if (more >= MAXTUNNEL) {
LOG(0,0,0,0, "DANGER: Received a tunnel session id > MAXTUNNEL!\n"); LOG(0, 0, 0, "DANGER: Received a tunnel session id > MAXTUNNEL!\n");
return -1; return -1;
} }
if (tunnel[more].state == TUNNELUNDEF) { if (tunnel[more].state == TUNNELUNDEF) {
if (config->cluster_iam_uptodate) { // Sanity. if (config->cluster_iam_uptodate) { // Sanity.
LOG(0,0,0,0, "I thought I was uptodate but I just found an undefined tunnel!\n"); LOG(0, 0, 0, "I thought I was uptodate but I just found an undefined tunnel!\n");
} else { } else {
--config->cluster_undefined_tunnels; --config->cluster_undefined_tunnels;
} }
@ -1084,7 +1084,7 @@ static int cluster_recv_tunnel(int more, u8 *p)
tunnel[more].controls = tunnel[more].controle = NULL; tunnel[more].controls = tunnel[more].controle = NULL;
tunnel[more].controlc = 0; tunnel[more].controlc = 0;
LOG(5,0,0,more, "Received tunnel update\n"); LOG(5, 0, more, "Received tunnel update\n");
if (!config->cluster_iam_uptodate) if (!config->cluster_iam_uptodate)
cluster_uptodate(); // Check to see if we're up to date. cluster_uptodate(); // Check to see if we're up to date.
@ -1108,7 +1108,7 @@ static int cluster_process_heartbeat(u8 * data, int size, int more, u8 * p, u32
// we handle version 2+ // we handle version 2+
if (more < 2 || more > HB_VERSION) { if (more < 2 || more > HB_VERSION) {
LOG(0,0,0,0, "Received a heartbeat version that I don't support (%d)!\n", more); LOG(0, 0, 0, "Received a heartbeat version that I don't support (%d)!\n", more);
return -1; // Ignore it?? return -1; // Ignore it??
} }
@ -1126,18 +1126,18 @@ static int cluster_process_heartbeat(u8 * data, int size, int more, u8 * p, u32
if (config->cluster_iam_master) { // Sanity... if (config->cluster_iam_master) { // Sanity...
// Note that this MUST match the election process above! // Note that this MUST match the election process above!
LOG(0,0,0,0, "I just got a packet claiming to be from a master but _I_ am the master!\n"); LOG(0, 0, 0, "I just got a packet claiming to be from a master but _I_ am the master!\n");
if (!h->basetime) { if (!h->basetime) {
LOG(0,0,0,0, "Heartbeat from addr %s with zero basetime!\n", inet_toa(addr) ); LOG(0, 0, 0, "Heartbeat from addr %s with zero basetime!\n", fmtaddr(addr, 0));
return -1; // Skip it. return -1; // Skip it.
} }
if (basetime > h->basetime) { if (basetime > h->basetime) {
LOG(0,0,0,0, "They're (%s) an older master than me so I'm gone!\n", inet_toa(addr)); LOG(0, 0, 0, "They're (%s) an older master than me so I'm gone!\n", fmtaddr(addr, 0));
kill(0, SIGTERM); kill(0, SIGTERM);
exit(1); exit(1);
} }
if (basetime == h->basetime && my_address < addr) { // Tie breaker. if (basetime == h->basetime && my_address < addr) { // Tie breaker.
LOG(0,0,0,0, "They're a higher IP address than me, so I'm gone!\n"); LOG(0, 0, 0, "They're a higher IP address than me, so I'm gone!\n");
kill(0, SIGTERM); kill(0, SIGTERM);
exit(1); exit(1);
} }
@ -1150,7 +1150,7 @@ static int cluster_process_heartbeat(u8 * data, int size, int more, u8 * p, u32
config->cluster_last_hb = TIME; // Reset to ensure that we don't become master!! config->cluster_last_hb = TIME; // Reset to ensure that we don't become master!!
if (config->cluster_seq_number != h->seq) { // Out of sequence heartbeat! if (config->cluster_seq_number != h->seq) { // Out of sequence heartbeat!
LOG(1,0,0,0, "HB: Got seq# %d but was expecting %d. asking for resend.\n", h->seq, config->cluster_seq_number); LOG(1, 0, 0, "HB: Got seq# %d but was expecting %d. asking for resend.\n", h->seq, config->cluster_seq_number);
peer_send_message(addr, C_LASTSEEN, config->cluster_seq_number, NULL, 0); peer_send_message(addr, C_LASTSEEN, config->cluster_seq_number, NULL, 0);
@ -1177,7 +1177,7 @@ static int cluster_process_heartbeat(u8 * data, int size, int more, u8 * p, u32
{ {
if (h->interval != config->cluster_hb_interval) if (h->interval != config->cluster_hb_interval)
{ {
LOG(2, 0, 0, 0, "Master set ping/heartbeat interval to %u (was %u)\n", LOG(2, 0, 0, "Master set ping/heartbeat interval to %u (was %u)\n",
h->interval, config->cluster_hb_interval); h->interval, config->cluster_hb_interval);
config->cluster_hb_interval = h->interval; config->cluster_hb_interval = h->interval;
@ -1185,7 +1185,7 @@ static int cluster_process_heartbeat(u8 * data, int size, int more, u8 * p, u32
if (h->timeout != config->cluster_hb_timeout) if (h->timeout != config->cluster_hb_timeout)
{ {
LOG(2, 0, 0, 0, "Master set heartbeat timeout to %u (was %u)\n", LOG(2, 0, 0, "Master set heartbeat timeout to %u (was %u)\n",
h->timeout, config->cluster_hb_timeout); h->timeout, config->cluster_hb_timeout);
config->cluster_hb_timeout = h->timeout; config->cluster_hb_timeout = h->timeout;
@ -1213,7 +1213,7 @@ static int cluster_process_heartbeat(u8 * data, int size, int more, u8 * p, u32
s -= (p - orig_p); s -= (p - orig_p);
if (size != sizeof(sessiont) ) { // Ouch! Very very bad! if (size != sizeof(sessiont) ) { // Ouch! Very very bad!
LOG(0,0,0,0, "DANGER: Received a CSESSION that didn't decompress correctly!\n"); LOG(0, 0, 0, "DANGER: Received a CSESSION that didn't decompress correctly!\n");
// Now what? Should exit! No-longer up to date! // Now what? Should exit! No-longer up to date!
break; break;
} }
@ -1240,7 +1240,7 @@ static int cluster_process_heartbeat(u8 * data, int size, int more, u8 * p, u32
s -= (p - orig_p); s -= (p - orig_p);
if (size != sizeof(tunnelt) ) { // Ouch! Very very bad! if (size != sizeof(tunnelt) ) { // Ouch! Very very bad!
LOG(0,0,0,0, "DANGER: Received a CSESSION that didn't decompress correctly!\n"); LOG(0, 0, 0, "DANGER: Received a CSESSION that didn't decompress correctly!\n");
// Now what? Should exit! No-longer up to date! // Now what? Should exit! No-longer up to date!
break; break;
} }
@ -1259,24 +1259,24 @@ static int cluster_process_heartbeat(u8 * data, int size, int more, u8 * p, u32
s -= sizeof(tunnel[more]); s -= sizeof(tunnel[more]);
break; break;
default: default:
LOG(0,0,0,0, "DANGER: I received a heartbeat element where I didn't understand the type! (%d)\n", type); LOG(0, 0, 0, "DANGER: I received a heartbeat element where I didn't understand the type! (%d)\n", type);
return -1; // can't process any more of the packet!! return -1; // can't process any more of the packet!!
} }
} }
if (config->cluster_master_address != addr) if (config->cluster_master_address != addr)
{ {
char *str; LOG(0, 0, 0, "My master just changed from %s to %s!\n",
str = strdup(inet_toa(config->cluster_master_address)); fmtaddr(config->cluster_master_address, 0), fmtaddr(addr, 1));
LOG(0,0,0,0, "My master just changed from %s to %s!\n", str, inet_toa(addr));
if (str) free(str); config->cluster_master_address = addr;
} }
config->cluster_master_address = addr;
config->cluster_last_hb = TIME; // Successfully received a heartbeat! config->cluster_last_hb = TIME; // Successfully received a heartbeat!
return 0; return 0;
shortpacket: shortpacket:
LOG(0,0,0,0, "I got an incomplete heartbeat packet! This means I'm probably out of sync!!\n"); LOG(0, 0, 0, "I got an incomplete heartbeat packet! This means I'm probably out of sync!!\n");
return -1; return -1;
} }
@ -1293,7 +1293,7 @@ int processcluster(char * data, int size, u32 addr)
if (addr == my_address) if (addr == my_address)
return -1; // Ignore it. Something looped back the multicast! return -1; // Ignore it. Something looped back the multicast!
LOG(5,0,0,0, "Process cluster: %d bytes from %s\n", size, inet_toa(addr)); LOG(5, 0, 0, "Process cluster: %d bytes from %s\n", size, fmtaddr(addr, 0));
if (s <= 0) // Any data there?? if (s <= 0) // Any data there??
return -1; return -1;
@ -1325,18 +1325,18 @@ int processcluster(char * data, int size, u32 addr)
p += sizeof(int); p += sizeof(int);
if (!config->cluster_iam_master) { // huh? if (!config->cluster_iam_master) { // huh?
LOG(0,0,0,0, "I'm not the master, but I got a C_FORWARD from %s?\n", inet_toa(addr)); LOG(0, 0, 0, "I'm not the master, but I got a C_FORWARD from %s?\n", fmtaddr(addr, 0));
return -1; return -1;
} }
LOG(4,0,0,0, "Got a forwarded packet... (%s:%d)\n", inet_toa(more), a.sin_port); LOG(4, 0, 0, "Got a forwarded packet... (%s:%d)\n", fmtaddr(more, 0), a.sin_port);
STAT(recv_forward); STAT(recv_forward);
processudp(p, s, &a); processudp(p, s, &a);
return 0; return 0;
} }
case C_THROTTLE: { // Receive a forwarded packet from a slave. case C_THROTTLE: { // Receive a forwarded packet from a slave.
if (!config->cluster_iam_master) { if (!config->cluster_iam_master) {
LOG(0,0,0,0, "I'm not the master, but I got a C_THROTTLE from %s?\n", inet_toa(addr)); LOG(0, 0, 0, "I'm not the master, but I got a C_THROTTLE from %s?\n", fmtaddr(addr, 0));
return -1; return -1;
} }
@ -1346,7 +1346,7 @@ int processcluster(char * data, int size, u32 addr)
case C_GARDEN: case C_GARDEN:
// Receive a walled garden packet from a slave. // Receive a walled garden packet from a slave.
if (!config->cluster_iam_master) { if (!config->cluster_iam_master) {
LOG(0,0,0,0, "I'm not the master, but I got a C_GARDEN from %s?\n", inet_toa(addr)); LOG(0, 0, 0, "I'm not the master, but I got a C_GARDEN from %s?\n", fmtaddr(addr, 0));
return -1; return -1;
} }
@ -1358,37 +1358,37 @@ int processcluster(char * data, int size, u32 addr)
case C_KILL: // The master asked us to die!? (usually because we're too out of date). case C_KILL: // The master asked us to die!? (usually because we're too out of date).
if (config->cluster_iam_master) { if (config->cluster_iam_master) {
LOG(0,0,0,0, "_I_ am master, but I received a C_KILL from %s! (Seq# %d)\n", inet_toa(addr), more); LOG(0, 0, 0, "_I_ am master, but I received a C_KILL from %s! (Seq# %d)\n", fmtaddr(addr, 0), more);
return -1; return -1;
} }
if (more != config->cluster_seq_number) { if (more != config->cluster_seq_number) {
LOG(0,0,0,0, "The master asked us to die but the seq number didn't match!?\n"); LOG(0, 0, 0, "The master asked us to die but the seq number didn't match!?\n");
return -1; return -1;
} }
if (addr != config->cluster_master_address) { if (addr != config->cluster_master_address) {
LOG(0,0,0,0, "Received a C_KILL from %s which doesn't match config->cluster_master_address (%x)\n", LOG(0, 0, 0, "Received a C_KILL from %s which doesn't match config->cluster_master_address (%s)\n",
inet_toa(addr), config->cluster_master_address); fmtaddr(addr, 0), fmtaddr(config->cluster_master_address, 1));
// We can only warn about it. The master might really have switched! // We can only warn about it. The master might really have switched!
} }
LOG(0,0,0,0, "Received a valid C_KILL: I'm going to die now.\n"); LOG(0, 0, 0, "Received a valid C_KILL: I'm going to die now.\n");
kill(0, SIGTERM); kill(0, SIGTERM);
exit(0); // Lets be paranoid; exit(0); // Lets be paranoid;
return -1; // Just signalling the compiler. return -1; // Just signalling the compiler.
case C_HEARTBEAT: case C_HEARTBEAT:
LOG(4,0,0,0, "Got a heartbeat from %s\n", inet_toa(addr)); LOG(4, 0, 0, "Got a heartbeat from %s\n", fmtaddr(addr, 0));
return cluster_process_heartbeat(data, size, more, p, addr); return cluster_process_heartbeat(data, size, more, p, addr);
default: default:
LOG(0,0,0,0, "Strange type packet received on cluster socket (%d)\n", type); LOG(0, 0, 0, "Strange type packet received on cluster socket (%d)\n", type);
return -1; return -1;
} }
return 0; return 0;
shortpacket: shortpacket:
LOG(0,0,0,0, "I got a _short_ cluster heartbeat packet! This means I'm probably out of sync!!\n"); LOG(0, 0, 0, "I got a _short_ cluster heartbeat packet! This means I'm probably out of sync!!\n");
return -1; return -1;
} }
@ -1402,14 +1402,16 @@ int cmd_show_cluster(struct cli_def *cli, char *command, char **argv, int argc)
return CLI_HELP_NO_ARGS; return CLI_HELP_NO_ARGS;
cli_print(cli, "Cluster status : %s", config->cluster_iam_master ? "Master" : "Slave" ); cli_print(cli, "Cluster status : %s", config->cluster_iam_master ? "Master" : "Slave" );
cli_print(cli, "My address : %s", inet_toa(my_address)); cli_print(cli, "My address : %s", fmtaddr(my_address, 0));
cli_print(cli, "VIP address : %s", inet_toa(config->bind_address)); cli_print(cli, "VIP address : %s", fmtaddr(config->bind_address, 0));
cli_print(cli, "Multicast address: %s", inet_toa(config->cluster_address)); cli_print(cli, "Multicast address: %s", fmtaddr(config->cluster_address, 0));
cli_print(cli, "Multicast i'face : %s", config->cluster_interface); cli_print(cli, "Multicast i'face : %s", config->cluster_interface);
if (!config->cluster_iam_master) { if (!config->cluster_iam_master) {
cli_print(cli, "My master : %s (last heartbeat %.1f seconds old)", cli_print(cli, "My master : %s (last heartbeat %.1f seconds old)",
config->cluster_master_address ? inet_toa(config->cluster_master_address) : "Not defined", config->cluster_master_address
? fmtaddr(config->cluster_master_address, 0)
: "Not defined",
0.1 * (TIME - config->cluster_last_hb)); 0.1 * (TIME - config->cluster_last_hb));
cli_print(cli, "Uptodate : %s", config->cluster_iam_uptodate ? "Yes" : "No"); cli_print(cli, "Uptodate : %s", config->cluster_iam_uptodate ? "Yes" : "No");
cli_print(cli, "Next sequence number expected: %d", config->cluster_seq_number); cli_print(cli, "Next sequence number expected: %d", config->cluster_seq_number);
@ -1426,7 +1428,7 @@ int cmd_show_cluster(struct cli_def *cli, char *command, char **argv, int argc)
if (num_peers) if (num_peers)
cli_print(cli, "%20s %10s %8s", "Address", "Basetime", "Age"); cli_print(cli, "%20s %10s %8s", "Address", "Basetime", "Age");
for (i = 0; i < num_peers; ++i) { for (i = 0; i < num_peers; ++i) {
cli_print(cli, "%20s %10d %8d", inet_toa(peers[i].peer), cli_print(cli, "%20s %10d %8d", fmtaddr(peers[i].peer, 0),
peers[i].basetime, TIME - peers[i].timestamp); peers[i].basetime, TIME - peers[i].timestamp);
} }
return CLI_OK; return CLI_OK;

View file

@ -9,7 +9,7 @@
/* walled garden */ /* walled garden */
char const *cvs_id = "$Id: garden.c,v 1.16 2004-11-18 06:41:03 bodea Exp $"; char const *cvs_id = "$Id: garden.c,v 1.17 2004-11-29 02:17:17 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION; int plugin_api_version = PLUGIN_API_VERSION;
static struct pluginfuncs *p = 0; static struct pluginfuncs *p = 0;
@ -47,7 +47,7 @@ int plugin_post_auth(struct param_post_auth *data)
// Ignore if user authentication was successful // Ignore if user authentication was successful
if (data->auth_allowed) return PLUGIN_RET_OK; if (data->auth_allowed) return PLUGIN_RET_OK;
p->log(3, 0, 0, 0, "Walled Garden allowing login\n"); p->log(3, p->get_id_by_session(data->s), data->s->tunnel, "Walled Garden allowing login\n");
data->auth_allowed = 1; data->auth_allowed = 1;
data->s->walled_garden = 1; data->s->walled_garden = 1;
return PLUGIN_RET_OK; return PLUGIN_RET_OK;
@ -147,7 +147,7 @@ int plugin_become_master(void)
for (i = 0; up_commands[i] && *up_commands[i]; i++) for (i = 0; up_commands[i] && *up_commands[i]; i++)
{ {
p->log(3, 0, 0, 0, "Running %s\n", up_commands[i]); p->log(3, 0, 0, "Running %s\n", up_commands[i]);
system(up_commands[i]); system(up_commands[i]);
} }
@ -169,15 +169,17 @@ int plugin_new_session_master(sessiont *s)
int garden_session(sessiont *s, int flag) int garden_session(sessiont *s, int flag)
{ {
char cmd[2048]; char cmd[2048];
sessionidt sess;
if (!s) return 0; if (!s) return 0;
if (!s->opened) return 0; if (!s->opened) return 0;
sess = p->get_id_by_session(s);
if (flag == 1) if (flag == 1)
{ {
p->log(2, 0, 0, s->tunnel, "Garden user %s (%s)\n", s->user, p->inet_toa(htonl(s->ip))); 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->inet_toa(htonl(s->ip))); snprintf(cmd, sizeof(cmd), "iptables -t nat -A garden_users -s %s -j garden", p->fmtaddr(htonl(s->ip), 0));
p->log(3, 0, 0, s->tunnel, "%s\n", cmd); p->log(3, sess, s->tunnel, "%s\n", cmd);
system(cmd); system(cmd);
s->walled_garden = 1; s->walled_garden = 1;
} }
@ -187,7 +189,7 @@ int garden_session(sessiont *s, int flag)
int count = 40; int count = 40;
// Normal User // Normal User
p->log(2, 0, 0, s->tunnel, "Un-Garden user %s (%s)\n", s->user, p->inet_toa(htonl(s->ip))); p->log(2, sess, s->tunnel, "Un-Garden user %s (%s)\n", s->user, p->fmtaddr(htonl(s->ip), 0));
// Kick off any duplicate usernames // Kick off any duplicate usernames
// but make sure not to kick off ourself // 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)) { if (s->ip && !s->die && (other = p->get_session_by_username(s->user)) && s != p->get_session_by_id(other)) {
@ -197,8 +199,8 @@ int garden_session(sessiont *s, int flag)
s->cin = s->cout = 0; s->cin = s->cout = 0;
s->pin = s->pout = 0; s->pin = s->pout = 0;
snprintf(cmd, sizeof(cmd), "iptables -t nat -D garden_users -s %s -j garden", p->inet_toa(htonl(s->ip))); snprintf(cmd, sizeof(cmd), "iptables -t nat -D garden_users -s %s -j garden", p->fmtaddr(htonl(s->ip), 0));
p->log(3, 0, 0, s->tunnel, "%s\n", cmd); p->log(3, sess, s->tunnel, "%s\n", cmd);
while (--count) while (--count)
{ {
int status = system(cmd); int status = system(cmd);
@ -242,7 +244,7 @@ int plugin_init(struct pluginfuncs *funcs)
int i; int i;
for (i = 0; down_commands[i] && *down_commands[i]; i++) for (i = 0; down_commands[i] && *down_commands[i]; i++)
{ {
p->log(3, 0, 0, 0, "Running %s\n", down_commands[i]); p->log(3, 0, 0, "Running %s\n", down_commands[i]);
system(down_commands[i]); system(down_commands[i]);
} }
} }
@ -259,7 +261,7 @@ void plugin_done()
for (i = 0; down_commands[i] && *down_commands[i]; i++) for (i = 0; down_commands[i] && *down_commands[i]; i++)
{ {
p->log(3, 0, 0, 0, "Running %s\n", down_commands[i]); p->log(3, 0, 0, "Running %s\n", down_commands[i]);
system(down_commands[i]); system(down_commands[i]);
} }
} }

527
l2tpns.c

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
// L2TPNS Global Stuff // L2TPNS Global Stuff
// $Id: l2tpns.h,v 1.40 2004-11-28 20:10:04 bodea Exp $ // $Id: l2tpns.h,v 1.41 2004-11-29 02:17:17 bodea Exp $
#ifndef __L2TPNS_H__ #ifndef __L2TPNS_H__
#define __L2TPNS_H__ #define __L2TPNS_H__
@ -277,7 +277,6 @@ struct Tringbuffer
char level; char level;
sessionidt session; sessionidt session;
tunnelidt tunnel; tunnelidt tunnel;
ipt address;
char message[MAX_LOG_LENGTH]; char message[MAX_LOG_LENGTH];
} buffer[RINGBUFFER_SIZE]; } buffer[RINGBUFFER_SIZE];
int head; int head;
@ -513,11 +512,14 @@ typedef struct
ipt dst_ip; // dest ip ipt dst_ip; // dest ip
ipt dst_wild; ipt dst_wild;
ip_filter_portt dst_ports; ip_filter_portt dst_ports;
u8 tcp_flag_op; // match type: any, all u8 frag; // apply to non-initial fragments
u8 tcp_flag_op; // match type: any, all, established
#define FILTER_FLAG_OP_ANY 1 #define FILTER_FLAG_OP_ANY 1
#define FILTER_FLAG_OP_ALL 2 #define FILTER_FLAG_OP_ALL 2
#define FILTER_FLAG_OP_EST 3
u8 tcp_sflags; // flags set u8 tcp_sflags; // flags set
u8 tcp_cflags; // flags clear u8 tcp_cflags; // flags clear
u32 counter; // match count
} ip_filter_rulet; } ip_filter_rulet;
#define TCP_FLAG_FIN 0x01 #define TCP_FLAG_FIN 0x01
@ -580,10 +582,10 @@ int cmd_show_hist_open(struct cli_def *cli, char *command, char **argv, int argc
#undef LOG #undef LOG
#undef LOG_HEX #undef LOG_HEX
#define LOG(D, a, s, t, f, ...) ({ if (D <= config->debug) _log(D, a, s, t, f, ## __VA_ARGS__); }) #define LOG(D, s, t, f, ...) ({ if (D <= config->debug) _log(D, s, t, f, ## __VA_ARGS__); })
#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, ipt address, sessionidt s, tunnelidt t, const char *format, ...) __attribute__((format (printf, 5, 6))); 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 char *data, int maxsize);
int sessionsetup(tunnelidt t, sessionidt s); int sessionsetup(tunnelidt t, sessionidt s);
@ -616,12 +618,12 @@ if (count++ < max) { \
void *array[20]; \ void *array[20]; \
char **strings; \ char **strings; \
int size, i; \ int size, i; \
LOG(0, 0, 0, t, "Backtrace follows"); \ LOG(0, 0, t, "Backtrace follows"); \
size = backtrace(array, 10); \ size = backtrace(array, 10); \
strings = backtrace_symbols(array, size); \ strings = backtrace_symbols(array, size); \
if (strings) for (i = 0; i < size; i++) \ if (strings) for (i = 0; i < size; i++) \
{ \ { \
LOG(0, 0, 0, t, "%s\n", strings[i]); \ LOG(0, 0, t, "%s\n", strings[i]); \
} \ } \
free(strings); \ free(strings); \
} }

View file

@ -1,7 +1,7 @@
#ifndef __PLUGIN_H__ #ifndef __PLUGIN_H__
#define __PLUGIN_H__ #define __PLUGIN_H__
#define PLUGIN_API_VERSION 3 #define PLUGIN_API_VERSION 4
#define MAX_PLUGIN_TYPES 30 #define MAX_PLUGIN_TYPES 30
enum enum
@ -26,9 +26,9 @@ enum
struct pluginfuncs struct pluginfuncs
{ {
void (*log)(int level, ipt address, 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 char *data, int maxsize);
char *(*inet_toa)(unsigned long addr); char *(*fmtaddr)(ipt 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);
sessionidt (*get_id_by_session)(sessiont *s); sessionidt (*get_id_by_session)(sessiont *s);

154
ppp.c
View file

@ -1,6 +1,6 @@
// L2TPNS PPP Stuff // L2TPNS PPP Stuff
char const *cvs_id_ppp = "$Id: ppp.c,v 1.32 2004-11-28 20:10:04 bodea Exp $"; char const *cvs_id_ppp = "$Id: ppp.c,v 1.33 2004-11-29 02:17:18 bodea Exp $";
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -37,14 +37,14 @@ void processpap(tunnelidt t, sessionidt s, u8 *p, u16 l)
LOG_HEX(5, "PAP", p, l); LOG_HEX(5, "PAP", p, l);
if (l < 4) if (l < 4)
{ {
LOG(1, 0, s, t, "Short PAP %u bytes\n", l); LOG(1, s, t, "Short PAP %u bytes\n", l);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
if ((hl = ntohs(*(u16 *) (p + 2))) > l) if ((hl = ntohs(*(u16 *) (p + 2))) > l)
{ {
LOG(1, 0, s, t, "Length mismatch PAP %u/%u\n", hl, l); LOG(1, s, t, "Length mismatch PAP %u/%u\n", hl, l);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
@ -52,7 +52,7 @@ void processpap(tunnelidt t, sessionidt s, u8 *p, u16 l)
if (*p != 1) if (*p != 1)
{ {
LOG(1, 0, s, t, "Unexpected PAP code %d\n", *p); LOG(1, s, t, "Unexpected PAP code %d\n", *p);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
@ -67,7 +67,7 @@ void processpap(tunnelidt t, sessionidt s, u8 *p, u16 l)
if (*b && *b < sizeof(pass)) if (*b && *b < sizeof(pass))
memcpy(pass, b + 1, *b); memcpy(pass, b + 1, *b);
pass[*b] = 0; pass[*b] = 0;
LOG(3, 0, s, t, "PAP login %s/%s\n", user, pass); LOG(3, s, t, "PAP login %s/%s\n", user, pass);
} }
if (session[s].ip || !session[s].radius) if (session[s].ip || !session[s].radius)
{ {
@ -86,14 +86,16 @@ void processpap(tunnelidt t, sessionidt s, u8 *p, u16 l)
p[4] = 0; // no message p[4] = 0; // no message
if (session[s].ip) if (session[s].ip)
{ {
LOG(3, session[s].ip, s, t, "Already an IP allocated: %s (%d)\n", inet_toa(htonl(session[s].ip)), session[s].ip_pool_index); LOG(3, s, t, "Already an IP allocated: %s (%d)\n",
fmtaddr(htonl(session[s].ip), 0), session[s].ip_pool_index);
session[s].flags &= ~SF_IPCP_ACKED; session[s].flags &= ~SF_IPCP_ACKED;
} }
else else
{ {
LOG(1, 0, s, t, "No radius session available to authenticate session...\n"); LOG(1, s, t, "No radius session available to authenticate session...\n");
} }
LOG(3, 0, s, t, "Fallback response to PAP (%s)\n", (session[s].ip) ? "ACK" : "NAK"); LOG(3, s, t, "Fallback response to PAP (%s)\n", (session[s].ip) ? "ACK" : "NAK");
tunnelsend(b, 5 + (p - b), t); // send it tunnelsend(b, 5 + (p - b), t); // send it
} }
else else
@ -106,7 +108,7 @@ void processpap(tunnelidt t, sessionidt s, u8 *p, u16 l)
run_plugins(PLUGIN_PRE_AUTH, &packet); run_plugins(PLUGIN_PRE_AUTH, &packet);
if (!packet.continue_auth) if (!packet.continue_auth)
{ {
LOG(3, 0, s, t, "A plugin rejected PRE_AUTH\n"); LOG(3, s, t, "A plugin rejected PRE_AUTH\n");
if (packet.username) free(packet.username); if (packet.username) free(packet.username);
if (packet.password) free(packet.password); if (packet.password) free(packet.password);
return; return;
@ -119,7 +121,7 @@ void processpap(tunnelidt t, sessionidt s, u8 *p, u16 l)
free(packet.password); free(packet.password);
radius[r].id = p[1]; radius[r].id = p[1];
LOG(3, 0, s, t, "Sending login for %s/%s to radius\n", user, pass); LOG(3, s, t, "Sending login for %s/%s to radius\n", user, pass);
radiussend(r, RADIUSAUTH); radiussend(r, RADIUSAUTH);
} }
} }
@ -136,7 +138,7 @@ void processchap(tunnelidt t, sessionidt s, u8 *p, u16 l)
r = session[s].radius; r = session[s].radius;
if (!r) if (!r)
{ {
LOG(1, 0, s, t, "Unexpected CHAP message\n"); LOG(1, s, t, "Unexpected CHAP message\n");
// FIXME: Need to drop the session here. // FIXME: Need to drop the session here.
@ -146,14 +148,14 @@ void processchap(tunnelidt t, sessionidt s, u8 *p, u16 l)
if (l < 4) if (l < 4)
{ {
LOG(1, 0, s, t, "Short CHAP %u bytes\n", l); LOG(1, s, t, "Short CHAP %u bytes\n", l);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
if ((hl = ntohs(*(u16 *) (p + 2))) > l) if ((hl = ntohs(*(u16 *) (p + 2))) > l)
{ {
LOG(1, 0, s, t, "Length mismatch CHAP %u/%u\n", hl, l); LOG(1, s, t, "Length mismatch CHAP %u/%u\n", hl, l);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
@ -161,20 +163,20 @@ void processchap(tunnelidt t, sessionidt s, u8 *p, u16 l)
if (*p != 2) if (*p != 2)
{ {
LOG(1, 0, s, t, "Unexpected CHAP response code %d\n", *p); LOG(1, s, t, "Unexpected CHAP response code %d\n", *p);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return; return;
} }
if (p[1] != radius[r].id) if (p[1] != radius[r].id)
{ {
LOG(1, 0, s, t, "Wrong CHAP response ID %d (should be %d) (%d)\n", p[1], radius[r].id, r); LOG(1, s, t, "Wrong CHAP response ID %d (should be %d) (%d)\n", p[1], radius[r].id, r);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
if (l < 5 || p[4] != 16) if (l < 5 || p[4] != 16)
{ {
LOG(1, 0, s, t, "Bad CHAP response length %d\n", l < 5 ? -1 : p[4]); LOG(1, s, t, "Bad CHAP response length %d\n", l < 5 ? -1 : p[4]);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
@ -183,7 +185,7 @@ void processchap(tunnelidt t, sessionidt s, u8 *p, u16 l)
p += 5; p += 5;
if (l < 16 || l - 16 >= sizeof(session[s].user)) if (l < 16 || l - 16 >= sizeof(session[s].user))
{ {
LOG(1, 0, s, t, "CHAP user too long %d\n", l - 16); LOG(1, s, t, "CHAP user too long %d\n", l - 16);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
@ -204,7 +206,7 @@ void processchap(tunnelidt t, sessionidt s, u8 *p, u16 l)
run_plugins(PLUGIN_PRE_AUTH, &packet); run_plugins(PLUGIN_PRE_AUTH, &packet);
if (!packet.continue_auth) if (!packet.continue_auth)
{ {
LOG(3, 0, s, t, "A plugin rejected PRE_AUTH\n"); LOG(3, s, t, "A plugin rejected PRE_AUTH\n");
if (packet.username) free(packet.username); if (packet.username) free(packet.username);
if (packet.password) free(packet.password); if (packet.password) free(packet.password);
return; return;
@ -218,7 +220,7 @@ void processchap(tunnelidt t, sessionidt s, u8 *p, u16 l)
} }
radius[r].chap = 1; radius[r].chap = 1;
LOG(3, 0, s, t, "CHAP login %s\n", session[s].user); LOG(3, s, t, "CHAP login %s\n", session[s].user);
radiussend(r, RADIUSAUTH); radiussend(r, RADIUSAUTH);
} }
@ -244,8 +246,8 @@ static void dumplcp(u8 *p, int l)
u8 *o = (p + 4); u8 *o = (p + 4);
LOG_HEX(5, "PPP LCP Packet", p, l); LOG_HEX(5, "PPP LCP Packet", p, l);
LOG(4, 0, 0, 0, "PPP LCP Packet type %d (%s len %d)\n", *p, ppp_lcp_types[(int)*p], ntohs( ((u16 *) p)[1]) ); LOG(4, 0, 0, "PPP LCP Packet type %d (%s len %d)\n", *p, ppp_lcp_types[(int)*p], ntohs( ((u16 *) p)[1]) );
LOG(4, 0, 0, 0, "Length: %d\n", l); LOG(4, 0, 0, "Length: %d\n", l);
if (*p != ConfigReq && *p != ConfigRej && *p != ConfigAck) if (*p != ConfigReq && *p != ConfigRej && *p != ConfigAck)
return; return;
@ -255,12 +257,12 @@ static void dumplcp(u8 *p, int l)
int length = o[1]; int length = o[1];
if (length < 2) if (length < 2)
{ {
LOG(4, 0, 0, 0, " Option length is %d...\n", length); LOG(4, 0, 0, " Option length is %d...\n", length);
break; break;
} }
if (type == 0) if (type == 0)
{ {
LOG(4, 0, 0, 0, " Option type is 0...\n"); LOG(4, 0, 0, " Option type is 0...\n");
x -= length; x -= length;
o += length; o += length;
continue; continue;
@ -269,51 +271,51 @@ static void dumplcp(u8 *p, int l)
{ {
case 1: // Maximum-Receive-Unit case 1: // Maximum-Receive-Unit
if (length == 4) if (length == 4)
LOG(4, 0, 0, 0, " %s %d\n", lcp_types[type], ntohs(*(u16 *)(o + 2))); LOG(4, 0, 0, " %s %d\n", lcp_types[type], ntohs(*(u16 *)(o + 2)));
else else
LOG(4, 0, 0, 0, " %s odd length %d\n", lcp_types[type], length); LOG(4, 0, 0, " %s odd length %d\n", lcp_types[type], length);
break; break;
case 2: // Async-Control-Character-Map case 2: // Async-Control-Character-Map
if (length == 6) if (length == 6)
{ {
u32 asyncmap = ntohl(*(u32 *)(o + 2)); u32 asyncmap = ntohl(*(u32 *)(o + 2));
LOG(4, 0, 0, 0, " %s %x\n", lcp_types[type], asyncmap); LOG(4, 0, 0, " %s %x\n", lcp_types[type], asyncmap);
} }
else else
LOG(4, 0, 0, 0, " %s odd length %d\n", lcp_types[type], length); LOG(4, 0, 0, " %s odd length %d\n", lcp_types[type], length);
break; break;
case 3: // Authentication-Protocol case 3: // Authentication-Protocol
if (length == 4) if (length == 4)
{ {
int proto = ntohs(*(u16 *)(o + 2)); int proto = ntohs(*(u16 *)(o + 2));
LOG(4, 0, 0, 0, " %s 0x%x (%s)\n", lcp_types[type], proto, LOG(4, 0, 0, " %s 0x%x (%s)\n", lcp_types[type], proto,
proto == PPPCHAP ? "CHAP" : proto == PPPCHAP ? "CHAP" :
proto == PPPPAP ? "PAP" : "UNKNOWN"); proto == PPPPAP ? "PAP" : "UNKNOWN");
} }
else else
LOG(4, 0, 0, 0, " %s odd length %d\n", lcp_types[type], length); LOG(4, 0, 0, " %s odd length %d\n", lcp_types[type], length);
break; break;
case 4: // Quality-Protocol case 4: // Quality-Protocol
{ {
u32 qp = ntohl(*(u32 *)(o + 2)); u32 qp = ntohl(*(u32 *)(o + 2));
LOG(4, 0, 0, 0, " %s %x\n", lcp_types[type], qp); LOG(4, 0, 0, " %s %x\n", lcp_types[type], qp);
} }
break; break;
case 5: // Magic-Number case 5: // Magic-Number
if (length == 6) if (length == 6)
{ {
u32 magicno = ntohl(*(u32 *)(o + 2)); u32 magicno = ntohl(*(u32 *)(o + 2));
LOG(4, 0, 0, 0, " %s %x\n", lcp_types[type], magicno); LOG(4, 0, 0, " %s %x\n", lcp_types[type], magicno);
} }
else else
LOG(4, 0, 0, 0, " %s odd length %d\n", lcp_types[type], length); LOG(4, 0, 0, " %s odd length %d\n", lcp_types[type], length);
break; break;
case 7: // Protocol-Field-Compression case 7: // Protocol-Field-Compression
case 8: // Address-And-Control-Field-Compression case 8: // Address-And-Control-Field-Compression
LOG(4, 0, 0, 0, " %s\n", lcp_types[type]); LOG(4, 0, 0, " %s\n", lcp_types[type]);
break; break;
default: default:
LOG(2, 0, 0, 0, " Unknown PPP LCP Option type %d\n", type); LOG(2, 0, 0, " Unknown PPP LCP Option type %d\n", type);
break; break;
} }
x -= length; x -= length;
@ -334,14 +336,14 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
LOG_HEX(5, "LCP", p, l); LOG_HEX(5, "LCP", p, l);
if (l < 4) if (l < 4)
{ {
LOG(1, session[s].ip, s, t, "Short LCP %d bytes\n", l); LOG(1, s, t, "Short LCP %d bytes\n", l);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
if ((hl = ntohs(*(u16 *) (p + 2))) > l) if ((hl = ntohs(*(u16 *) (p + 2))) > l)
{ {
LOG(1, 0, s, t, "Length mismatch LCP %u/%u\n", hl, l); LOG(1, s, t, "Length mismatch LCP %u/%u\n", hl, l);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
@ -349,7 +351,7 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
if (*p == ConfigAck) if (*p == ConfigAck)
{ {
LOG(3, session[s].ip, s, t, "LCP: Discarding ConfigAck\n"); LOG(3, s, t, "LCP: Discarding ConfigAck\n");
session[s].flags |= SF_LCP_ACKED; session[s].flags |= SF_LCP_ACKED;
} }
else if (*p == ConfigReq) else if (*p == ConfigReq)
@ -358,7 +360,7 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
u8 *o = (p + 4); u8 *o = (p + 4);
u8 response = 0; u8 response = 0;
LOG(3, session[s].ip, s, t, "LCP: ConfigReq (%d bytes)...\n", l); LOG(3, s, t, "LCP: ConfigReq (%d bytes)...\n", l);
if (config->debug > 3) dumplcp(p, l); if (config->debug > 3) dumplcp(p, l);
while (x > 2) while (x > 2)
@ -379,7 +381,7 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
if (response && response != ConfigNak) // rej already queued if (response && response != ConfigNak) // rej already queued
break; break;
LOG(2, session[s].ip, s, t, " Remote requesting asyncmap. Rejecting.\n"); LOG(2, s, t, " Remote requesting asyncmap. Rejecting.\n");
if (!response) if (!response)
{ {
q = makeppp(b, sizeof(b), NULL, 0, t, s, PPPLCP); q = makeppp(b, sizeof(b), NULL, 0, t, s, PPPLCP);
@ -389,7 +391,7 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
if ((q - b + 11) > sizeof(b)) if ((q - b + 11) > sizeof(b))
{ {
LOG(2, session[s].ip, s, t, "LCP overflow for asyncmap ConfigNak.\n"); LOG(2, s, t, "LCP overflow for asyncmap ConfigNak.\n");
break; break;
} }
@ -414,7 +416,7 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
else else
sprintf(proto_name, "%#4.4x", proto); sprintf(proto_name, "%#4.4x", proto);
LOG(2, session[s].ip, s, t, " Remote requesting %s authentication. Rejecting.\n", proto_name); LOG(2, s, t, " Remote requesting %s authentication. Rejecting.\n", proto_name);
if (!response) if (!response)
{ {
@ -425,7 +427,7 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
if ((q - b + length) > sizeof(b)) if ((q - b + length) > sizeof(b))
{ {
LOG(2, session[s].ip, s, t, "LCP overflow for %s ConfigNak.\n", proto_name); LOG(2, s, t, "LCP overflow for %s ConfigNak.\n", proto_name);
break; break;
} }
@ -445,7 +447,7 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
break; break;
default: // Reject any unknown options default: // Reject any unknown options
LOG(2, session[s].ip, s, t, " Rejecting PPP LCP Option type %d\n", type); LOG(2, s, t, " Rejecting PPP LCP Option type %d\n", type);
if (!response || response != ConfigRej) // drop nak in favour of rej if (!response || response != ConfigRej) // drop nak in favour of rej
{ {
q = makeppp(b, sizeof(b), NULL, 0, t, s, PPPLCP); q = makeppp(b, sizeof(b), NULL, 0, t, s, PPPLCP);
@ -455,7 +457,7 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
if ((q - b + length) > sizeof(b)) if ((q - b + length) > sizeof(b))
{ {
LOG(2, session[s].ip, s, t, "LCP overflow for ConfigRej (type=%d).\n", type); LOG(2, s, t, "LCP overflow for ConfigRej (type=%d).\n", type);
break; break;
} }
@ -474,7 +476,7 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
response = *q = ConfigAck; response = *q = ConfigAck;
} }
LOG(3, session[s].ip, s, t, "Sending %s\n", ppp_lcp_types[response]); LOG(3, s, t, "Sending %s\n", ppp_lcp_types[response]);
tunnelsend(b, l + (q - b), t); tunnelsend(b, l + (q - b), t);
if (!(session[s].flags & SF_LCP_ACKED)) if (!(session[s].flags & SF_LCP_ACKED))
@ -482,13 +484,13 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
} }
else if (*p == ConfigNak) else if (*p == ConfigNak)
{ {
LOG(1, session[s].ip, s, t, "Remote end sent a ConfigNak. Ignoring\n"); LOG(1, s, t, "Remote end sent a ConfigNak. Ignoring\n");
if (config->debug > 3) dumplcp(p, l); if (config->debug > 3) dumplcp(p, l);
return ; return ;
} }
else if (*p == TerminateReq) else if (*p == TerminateReq)
{ {
LOG(3, session[s].ip, s, t, "LCP: Received TerminateReq. Sending TerminateAck\n"); LOG(3, s, t, "LCP: Received TerminateReq. Sending TerminateAck\n");
*p = TerminateAck; // close *p = TerminateAck; // close
q = makeppp(b, sizeof(b), p, l, t, s, PPPLCP); q = makeppp(b, sizeof(b), p, l, t, s, PPPLCP);
if (!q) return; if (!q) return;
@ -501,7 +503,7 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
} }
else if (*p == EchoReq) else if (*p == EchoReq)
{ {
LOG(5, session[s].ip, s, t, "LCP: Received EchoReq. Sending EchoReply\n"); LOG(5, s, t, "LCP: Received EchoReq. Sending EchoReply\n");
*p = EchoReply; // reply *p = EchoReply; // reply
*(u32 *) (p + 4) = htonl(session[s].magic); // our magic number *(u32 *) (p + 4) = htonl(session[s].magic); // our magic number
q = makeppp(b, sizeof(b), p, l, t, s, PPPLCP); q = makeppp(b, sizeof(b), p, l, t, s, PPPLCP);
@ -517,7 +519,7 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
*p = CodeRej; *p = CodeRej;
if (l > MAXCONTROL) if (l > MAXCONTROL)
{ {
LOG(1, 0, s, t, "Truncated Ident Packet (length=%d) to 1400 bytes\n", l); LOG(1, s, t, "Truncated Ident Packet (length=%d) to 1400 bytes\n", l);
l = 1400; l = 1400;
} }
q = makeppp(b, sizeof(b), p, l, t, s, PPPLCP); q = makeppp(b, sizeof(b), p, l, t, s, PPPLCP);
@ -527,7 +529,7 @@ void processlcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
} }
else else
{ {
LOG(1, session[s].ip, s, t, "Unexpected LCP code %d\n", *p); LOG(1, s, t, "Unexpected LCP code %d\n", *p);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
@ -563,14 +565,14 @@ void processipcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
LOG_HEX(5, "IPCP", p, l); LOG_HEX(5, "IPCP", p, l);
if (l < 5) if (l < 5)
{ {
LOG(1, 0, s, t, "Short IPCP %d bytes\n", l); LOG(1, s, t, "Short IPCP %d bytes\n", l);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
if ((hl = ntohs(*(u16 *) (p + 2))) > l) if ((hl = ntohs(*(u16 *) (p + 2))) > l)
{ {
LOG(1, 0, s, t, "Length mismatch IPCP %u/%u\n", hl, l); LOG(1, s, t, "Length mismatch IPCP %u/%u\n", hl, l);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
@ -589,7 +591,7 @@ void processipcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
} }
session[s].flags |= SF_IPCP_ACKED; session[s].flags |= SF_IPCP_ACKED;
LOG(3, session[s].ip, s, t, "IPCP Acked, session is now active\n"); LOG(3, s, t, "IPCP Acked, session is now active\n");
// clear LCP_ACKED/CCP_ACKED flag for possible fast renegotiaion for routers // clear LCP_ACKED/CCP_ACKED flag for possible fast renegotiaion for routers
session[s].flags &= ~(SF_LCP_ACKED|SF_CCP_ACKED); session[s].flags &= ~(SF_LCP_ACKED|SF_CCP_ACKED);
@ -598,15 +600,15 @@ void processipcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
} }
if (*p != ConfigReq) if (*p != ConfigReq)
{ {
LOG(1, 0, s, t, "Unexpected IPCP code %d\n", *p); LOG(1, s, t, "Unexpected IPCP code %d\n", *p);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
LOG(4, session[s].ip, s, t, "IPCP ConfigReq received\n"); LOG(4, s, t, "IPCP ConfigReq received\n");
if (!session[s].ip) if (!session[s].ip)
{ {
LOG(3, 0, s, t, "Waiting on radius reply\n"); LOG(3, s, t, "Waiting on radius reply\n");
return; // have to wait on RADIUS reply return; // have to wait on RADIUS reply
} }
// form a config reply quoting the IP in the session // form a config reply quoting the IP in the session
@ -637,19 +639,19 @@ void processipcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
{ {
if (*p != 0x81 && *p != 0x83 && *p != 3) if (*p != 0x81 && *p != 0x83 && *p != 3)
{ {
LOG(2, 0, s, t, "IPCP reject %d\n", *p); LOG(2, s, t, "IPCP reject %d\n", *p);
memcpy(q + n, p, p[1]); memcpy(q + n, p, p[1]);
n += p[1]; n += p[1];
} }
p += p[1]; p += p[1];
} }
*(u16 *) (q + 2) = htons(n); *(u16 *) (q + 2) = htons(n);
LOG(4, session[s].ip, s, t, "Sending ConfigRej\n"); LOG(4, s, t, "Sending ConfigRej\n");
tunnelsend(b, n + (q - b), t); // send it tunnelsend(b, n + (q - b), t); // send it
} }
else else
{ {
LOG(4, session[s].ip, s, t, "Sending ConfigAck\n"); LOG(4, s, t, "Sending ConfigAck\n");
*p = ConfigAck; *p = ConfigAck;
if ((i = findppp(p, 0x81))) // Primary DNS address if ((i = findppp(p, 0x81))) // Primary DNS address
{ {
@ -657,7 +659,7 @@ void processipcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
{ {
*(u32 *) (i + 2) = htonl(session[s].dns1); *(u32 *) (i + 2) = htonl(session[s].dns1);
*p = ConfigNak; *p = ConfigNak;
LOG(5, session[s].ip, s, t, " DNS1 = %s\n", inet_toa(session[s].dns1)); LOG(5, s, t, " DNS1 = %s\n", fmtaddr(session[s].dns1, 0));
} }
} }
if ((i = findppp(p, 0x83))) // Secondary DNS address (TBA, is it) if ((i = findppp(p, 0x83))) // Secondary DNS address (TBA, is it)
@ -666,13 +668,13 @@ void processipcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
{ {
*(u32 *) (i + 2) = htonl(session[s].dns2); *(u32 *) (i + 2) = htonl(session[s].dns2);
*p = ConfigNak; *p = ConfigNak;
LOG(5, session[s].ip, s, t, " DNS2 = %s\n", inet_toa(session[s].dns2)); LOG(5, s, t, " DNS2 = %s\n", fmtaddr(session[s].dns2, 0));
} }
} }
i = findppp(p, 3); // IP address i = findppp(p, 3); // IP address
if (!i || i[1] != 6) if (!i || i[1] != 6)
{ {
LOG(1, 0, s, t, "No IP in IPCP request\n"); LOG(1, s, t, "No IP in IPCP request\n");
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
@ -680,8 +682,8 @@ void processipcp(tunnelidt t, sessionidt s, u8 *p, u16 l)
{ {
*(u32 *) (i + 2) = htonl(session[s].ip); *(u32 *) (i + 2) = htonl(session[s].ip);
*p = ConfigNak; *p = ConfigNak;
LOG(4, session[s].ip, s, t, " No, a ConfigNak, client is requesting IP - sending %s\n", LOG(4, s, t, " No, a ConfigNak, client is requesting IP - sending %s\n",
inet_toa(htonl(session[s].ip))); fmtaddr(htonl(session[s].ip), 0));
} }
if (!(q = makeppp(b, sizeof(b), p, l, t, s, PPPIPCP))) if (!(q = makeppp(b, sizeof(b), p, l, t, s, PPPIPCP)))
return; return;
@ -707,7 +709,7 @@ void processipin(tunnelidt t, sessionidt s, u8 *p, u16 l)
if (l > MAXETHER) if (l > MAXETHER)
{ {
LOG(1, ip, s, t, "IP packet too long %d\n", l); LOG(1, s, t, "IP packet too long %d\n", l);
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return ; return ;
} }
@ -715,7 +717,7 @@ void processipin(tunnelidt t, sessionidt s, u8 *p, u16 l)
// no spoof (do sessionbyip to handled statically routed subnets) // no spoof (do sessionbyip to handled statically routed subnets)
if (ip != session[s].ip && sessionbyip(htonl(ip)) != s) if (ip != session[s].ip && sessionbyip(htonl(ip)) != s)
{ {
LOG(5, ip, s, t, "Dropping packet with spoofed IP %s\n", inet_toa(htonl(ip))); LOG(5, s, t, "Dropping packet with spoofed IP %s\n", fmtaddr(htonl(ip), 0));
return; return;
} }
@ -742,7 +744,7 @@ void processipin(tunnelidt t, sessionidt s, u8 *p, u16 l)
if (tun_write(p, l) < 0) if (tun_write(p, l) < 0)
{ {
STAT(tun_tx_errors); STAT(tun_tx_errors);
LOG(0, 0, s, t, "Error writing %d bytes to TUN device: %s (tunfd=%d, p=%p)\n", LOG(0, s, t, "Error writing %d bytes to TUN device: %s (tunfd=%d, p=%p)\n",
l, strerror(errno), tunfd, p); l, strerror(errno), tunfd, p);
return; return;
@ -776,7 +778,7 @@ void send_ipin(sessionidt s, u8 *buf, int len)
if (write(tunfd, buf, len) < 0) if (write(tunfd, buf, len) < 0)
{ {
STAT(tun_tx_errors); STAT(tun_tx_errors);
LOG(0, 0, 0, 0, "Error writing %d bytes to TUN device: %s (tunfd=%d, p=%p)\n", LOG(0, 0, 0, "Error writing %d bytes to TUN device: %s (tunfd=%d, p=%p)\n",
len, strerror(errno), tunfd, buf); len, strerror(errno), tunfd, buf);
return; return;
@ -838,9 +840,9 @@ void processccp(tunnelidt t, sessionidt s, u8 *p, u16 l)
default: default:
if (l > 1) if (l > 1)
LOG(1, 0, s, t, "Unexpected CCP request code %d\n", *p); LOG(1, s, t, "Unexpected CCP request code %d\n", *p);
else else
LOG(1, 0, s, t, "Short CCP packet\n"); LOG(1, s, t, "Short CCP packet\n");
STAT(tunnel_rx_errors); STAT(tunnel_rx_errors);
return; return;
@ -863,11 +865,11 @@ void sendchap(tunnelidt t, sessionidt s)
if (!r) if (!r)
{ {
LOG(1, 0, s, t, "No RADIUS to send challenge\n"); LOG(1, s, t, "No RADIUS to send challenge\n");
STAT(tunnel_tx_errors); STAT(tunnel_tx_errors);
return ; return ;
} }
LOG(1, 0, s, t, "Send CHAP challenge\n"); LOG(1, s, t, "Send CHAP challenge\n");
{ {
// new challenge // new challenge
int n; int n;
@ -906,7 +908,7 @@ u8 *makeppp(u8 *b, int size, u8 *p, int l, tunnelidt t, sessionidt s, u16 mtype)
if (size < 12) // Need more space than this!! if (size < 12) // Need more space than this!!
{ {
static int backtrace_count = 0; static int backtrace_count = 0;
LOG(0, session[s].ip, s, t, "makeppp buffer too small for L2TP header (size=%d)\n", size); LOG(0, s, t, "makeppp buffer too small for L2TP header (size=%d)\n", size);
log_backtrace(backtrace_count, 5) log_backtrace(backtrace_count, 5)
return NULL; return NULL;
} }
@ -931,7 +933,7 @@ u8 *makeppp(u8 *b, int size, u8 *p, int l, tunnelidt t, sessionidt s, u16 mtype)
if (l + 12 > size) if (l + 12 > size)
{ {
static int backtrace_count = 0; static int backtrace_count = 0;
LOG(2, session[s].ip, s, t, "makeppp would overflow buffer (size=%d, header+payload=%d)\n", size, l + 12); LOG(2, s, t, "makeppp would overflow buffer (size=%d, header+payload=%d)\n", size, l + 12);
log_backtrace(backtrace_count, 5) log_backtrace(backtrace_count, 5)
return NULL; return NULL;
} }
@ -950,7 +952,7 @@ void initlcp(tunnelidt t, sessionidt s)
if (!(q = makeppp(b, sizeof(b), NULL, 0, t, s, PPPLCP))) if (!(q = makeppp(b, sizeof(b), NULL, 0, t, s, PPPLCP)))
return; return;
LOG(4, 0, s, t, "Sending LCP ConfigReq for PAP\n"); LOG(4, s, t, "Sending LCP ConfigReq for PAP\n");
*q = ConfigReq; *q = ConfigReq;
*(u8 *)(q + 1) = (time_now % 255) + 1; // ID *(u8 *)(q + 1) = (time_now % 255) + 1; // ID
*(u16 *)(q + 2) = htons(14); // Length *(u16 *)(q + 2) = htons(14); // Length
@ -973,7 +975,7 @@ static void initccp(tunnelidt t, sessionidt s)
if (!(q = makeppp(b, sizeof(b), NULL, 0, t, s, PPPCCP))) if (!(q = makeppp(b, sizeof(b), NULL, 0, t, s, PPPCCP)))
return; return;
LOG(4, 0, s, t, "Sending CCP ConfigReq for no compression\n"); LOG(4, s, t, "Sending CCP ConfigReq for no compression\n");
*q = ConfigReq; *q = ConfigReq;
*(u8 *)(q + 1) = (time_now % 255) + 1; // ID *(u8 *)(q + 1) = (time_now % 255) + 1; // ID
*(u16 *)(q + 2) = htons(4); // Length *(u16 *)(q + 2) = htons(4); // Length

View file

@ -1,6 +1,6 @@
// L2TPNS Radius Stuff // L2TPNS Radius Stuff
char const *cvs_id_radius = "$Id: radius.c,v 1.17 2004-11-28 02:53:11 bodea Exp $"; char const *cvs_id_radius = "$Id: radius.c,v 1.18 2004-11-29 02:17:18 bodea Exp $";
#include <time.h> #include <time.h>
#include <stdio.h> #include <stdio.h>
@ -42,7 +42,7 @@ static const char *radius_state(int state)
void initrad(void) void initrad(void)
{ {
int i; int i;
LOG(3, 0, 0, 0, "Creating %d sockets for RADIUS queries\n", config->num_radfds); LOG(3, 0, 0, "Creating %d sockets for RADIUS queries\n", config->num_radfds);
radfds = calloc(sizeof(int), config->num_radfds); radfds = calloc(sizeof(int), config->num_radfds);
for (i = 0; i < config->num_radfds; i++) for (i = 0; i < config->num_radfds; i++)
{ {
@ -77,7 +77,7 @@ static u16 get_free_radius()
} }
} }
LOG(0, 0, 0, 0, "Can't find a free radius session! This is very bad!\n"); LOG(0, 0, 0, "Can't find a free radius session! This is very bad!\n");
return 0; return 0;
} }
@ -88,13 +88,13 @@ u16 radiusnew(sessionidt s)
/* re-use */ /* re-use */
if (r) if (r)
{ {
LOG(3, 0, s, session[s].tunnel, "Re-used radius %d\n", r); LOG(3, s, session[s].tunnel, "Re-used radius %d\n", r);
return r; return r;
} }
if (!(r = get_free_radius())) if (!(r = get_free_radius()))
{ {
LOG(1, 0, s, session[s].tunnel, "No free RADIUS sessions\n"); LOG(1, s, session[s].tunnel, "No free RADIUS sessions\n");
STAT(radius_overflow); STAT(radius_overflow);
return 0; return 0;
}; };
@ -105,7 +105,7 @@ u16 radiusnew(sessionidt s)
radius[r].state = RADIUSWAIT; radius[r].state = RADIUSWAIT;
radius[r].retry = TIME + 1200; // Wait at least 120 seconds to re-claim this. radius[r].retry = TIME + 1200; // Wait at least 120 seconds to re-claim this.
LOG(3,0,s, session[s].tunnel, "Allocated radius %d\n", r); LOG(3, s, session[s].tunnel, "Allocated radius %d\n", r);
return r; return r;
} }
@ -124,12 +124,12 @@ void radiussend(u16 r, u8 state)
s = radius[r].session; s = radius[r].session;
if (!config->numradiusservers) if (!config->numradiusservers)
{ {
LOG(0, 0, s, session[s].tunnel, "No RADIUS servers\n"); LOG(0, s, session[s].tunnel, "No RADIUS servers\n");
return; return;
} }
if (!*config->radiussecret) if (!*config->radiussecret)
{ {
LOG(0, 0, s, session[s].tunnel, "No RADIUS secret\n"); LOG(0, s, session[s].tunnel, "No RADIUS secret\n");
return; return;
} }
@ -144,9 +144,10 @@ void radiussend(u16 r, u8 state)
radius[r].try = 0; radius[r].try = 0;
radius[r].state = state; radius[r].state = state;
radius[r].retry = backoff(radius[r].try++); radius[r].retry = backoff(radius[r].try++);
LOG(4, 0, s, session[s].tunnel, "Send RADIUS id %d sock %d state %s try %d\n", LOG(4, s, session[s].tunnel, "Send RADIUS id %d sock %d state %s try %d\n",
r >> RADIUS_SHIFT, r & RADIUS_MASK, r >> RADIUS_SHIFT, r & RADIUS_MASK,
radius_state(radius[r].state), radius[r].try); radius_state(radius[r].state), radius[r].try);
if (radius[r].try > config->numradiusservers * 2) if (radius[r].try > config->numradiusservers * 2)
{ {
if (s) if (s)
@ -155,7 +156,7 @@ void radiussend(u16 r, u8 state)
sessionshutdown(s, "RADIUS timeout"); sessionshutdown(s, "RADIUS timeout");
else else
{ {
LOG(1, 0, s, session[s].tunnel, "RADIUS timeout, but in state %s so don't timeout session\n", LOG(1, s, session[s].tunnel, "RADIUS timeout, but in state %s so don't timeout session\n",
radius_states[state]); radius_states[state]);
radiusclear(r, s); radiusclear(r, s);
} }
@ -180,7 +181,7 @@ void radiussend(u16 r, u8 state)
b[0] = 4; // accounting request b[0] = 4; // accounting request
break; break;
default: default:
LOG(0, 0, 0, 0, "Unknown radius state %d\n", state); LOG(0, 0, 0, "Unknown radius state %d\n", state);
} }
b[1] = r >> RADIUS_SHIFT; // identifier b[1] = r >> RADIUS_SHIFT; // identifier
memcpy(b + 4, radius[r].auth, 16); memcpy(b + 4, radius[r].auth, 16);
@ -381,22 +382,22 @@ void processrad(u8 *buf, int len, char socket_index)
LOG_HEX(5, "RADIUS Response", buf, len); LOG_HEX(5, "RADIUS Response", buf, len);
if (len < 20 || len < ntohs(*(u16 *) (buf + 2))) if (len < 20 || len < ntohs(*(u16 *) (buf + 2)))
{ {
LOG(1, 0, 0, 0, "Duff RADIUS response length %d\n", len); LOG(1, 0, 0, "Duff RADIUS response length %d\n", len);
return ; return ;
} }
len = ntohs(*(u16 *) (buf + 2)); len = ntohs(*(u16 *) (buf + 2));
r = socket_index | (r_id << RADIUS_SHIFT); r = socket_index | (r_id << RADIUS_SHIFT);
s = radius[r].session; s = radius[r].session;
LOG(3, 0, s, session[s].tunnel, "Received %s, radius %d response for session %u (code %d, id %d)\n", LOG(3, s, session[s].tunnel, "Received %s, radius %d response for session %u (code %d, id %d)\n",
radius_states[radius[r].state], r, s, r_code, r_id); radius_states[radius[r].state], r, s, r_code, r_id);
if (!s && radius[r].state != RADIUSSTOP) if (!s && radius[r].state != RADIUSSTOP)
{ {
LOG(1, 0, s, session[s].tunnel, " Unexpected RADIUS response\n"); LOG(1, s, session[s].tunnel, " Unexpected RADIUS response\n");
return; return;
} }
if (radius[r].state != RADIUSAUTH && radius[r].state != RADIUSSTART && radius[r].state != RADIUSSTOP) if (radius[r].state != RADIUSAUTH && radius[r].state != RADIUSSTART && radius[r].state != RADIUSSTOP)
{ {
LOG(1, 0, s, session[s].tunnel, " Unexpected RADIUS response\n"); LOG(1, s, session[s].tunnel, " Unexpected RADIUS response\n");
return; return;
} }
t = session[s].tunnel; t = session[s].tunnel;
@ -409,19 +410,19 @@ void processrad(u8 *buf, int len, char socket_index)
do { do {
if (memcmp(hash, buf + 4, 16)) if (memcmp(hash, buf + 4, 16))
{ {
LOG(0, 0, s, session[s].tunnel, " Incorrect auth on RADIUS response!! (wrong secret in radius config?)\n"); LOG(0, s, session[s].tunnel, " Incorrect auth on RADIUS response!! (wrong secret in radius config?)\n");
return; // Do nothing. On timeout, it will try the next radius server. return; // Do nothing. On timeout, it will try the next radius server.
} }
if ((radius[r].state == RADIUSAUTH && *buf != 2 && *buf != 3) || if ((radius[r].state == RADIUSAUTH && *buf != 2 && *buf != 3) ||
((radius[r].state == RADIUSSTART || radius[r].state == RADIUSSTOP) && *buf != 5)) ((radius[r].state == RADIUSSTART || radius[r].state == RADIUSSTOP) && *buf != 5))
{ {
LOG(1, 0, s, session[s].tunnel, " Unexpected RADIUS response %d\n", *buf); LOG(1, s, session[s].tunnel, " Unexpected RADIUS response %d\n", *buf);
return; // We got something we didn't expect. Let the timeouts take return; // We got something we didn't expect. Let the timeouts take
// care off finishing the radius session if that's really correct. // care off finishing the radius session if that's really correct.
} }
if (radius[r].state == RADIUSAUTH) if (radius[r].state == RADIUSAUTH)
{ {
LOG(4, 0, s, session[s].tunnel, " Original response is \"%s\"\n", (*buf == 2) ? "accept" : "reject"); LOG(4, s, session[s].tunnel, " Original response is \"%s\"\n", (*buf == 2) ? "accept" : "reject");
// process auth response // process auth response
if (radius[r].chap) if (radius[r].chap)
{ {
@ -435,7 +436,7 @@ void processrad(u8 *buf, int len, char socket_index)
*buf = packet.auth_allowed ? 2 : 3; *buf = packet.auth_allowed ? 2 : 3;
} }
LOG(3, 0, s, session[s].tunnel, " CHAP User %s authentication %s.\n", session[s].user, LOG(3, s, session[s].tunnel, " CHAP User %s authentication %s.\n", session[s].user,
(*buf == 2) ? "allowed" : "denied"); (*buf == 2) ? "allowed" : "denied");
*p = (*buf == 2) ? 3 : 4; // ack/nak *p = (*buf == 2) ? 3 : 4; // ack/nak
p[1] = radius[r].id; p[1] = radius[r].id;
@ -454,7 +455,7 @@ void processrad(u8 *buf, int len, char socket_index)
*buf = packet.auth_allowed ? 2 : 3; *buf = packet.auth_allowed ? 2 : 3;
} }
LOG(3, 0, s, session[s].tunnel, " PAP User %s authentication %s.\n", session[s].user, LOG(3, s, session[s].tunnel, " PAP User %s authentication %s.\n", session[s].user,
(*buf == 2) ? "allowed" : "denied"); (*buf == 2) ? "allowed" : "denied");
// ack/nak // ack/nak
*p = *buf; *p = *buf;
@ -475,21 +476,24 @@ void processrad(u8 *buf, int len, char socket_index)
if (*p == 8) if (*p == 8)
{ {
// Framed-IP-Address // Framed-IP-Address
LOG(3, 0, s, session[s].tunnel, " Radius reply contains IP address %s\n", inet_toa(*(u32 *) (p + 2)));
session[s].ip = ntohl(*(u32 *) (p + 2)); session[s].ip = ntohl(*(u32 *) (p + 2));
session[s].ip_pool_index = -1; session[s].ip_pool_index = -1;
LOG(3, s, session[s].tunnel, " Radius reply contains IP address %s\n",
fmtaddr(htonl(session[s].ip), 0));
} }
else if (*p == 135) else if (*p == 135)
{ {
// DNS address // DNS address
LOG(3, 0, s, session[s].tunnel, " Radius reply contains primary DNS address %s\n", inet_toa(*(u32 *) (p + 2)));
session[s].dns1 = ntohl(*(u32 *) (p + 2)); session[s].dns1 = ntohl(*(u32 *) (p + 2));
LOG(3, s, session[s].tunnel, " Radius reply contains primary DNS address %s\n",
fmtaddr(htonl(session[s].dns1), 0));
} }
else if (*p == 136) else if (*p == 136)
{ {
// DNS address // DNS address
LOG(3, 0, s, session[s].tunnel, " Radius reply contains secondary DNS address %s\n", inet_toa(*(u32 *) (p + 2)));
session[s].dns2 = ntohl(*(u32 *) (p + 2)); session[s].dns2 = ntohl(*(u32 *) (p + 2));
LOG(3, s, session[s].tunnel, " Radius reply contains secondary DNS address %s\n",
fmtaddr(htonl(session[s].dns2), 0));
} }
else if (*p == 22) else if (*p == 22)
{ {
@ -524,18 +528,16 @@ void processrad(u8 *buf, int len, char socket_index)
mask = 0xFFFF0000; mask = 0xFFFF0000;
else else
mask = 0xFFFFFF00; mask = 0xFFFFFF00;
if (routes == MAXROUTE) if (routes == MAXROUTE)
{ {
LOG(1, 0, s, session[s].tunnel, " Too many routes\n"); LOG(1, s, session[s].tunnel, " Too many routes\n");
} }
else if (ip) else if (ip)
{ {
char *ips, *masks; LOG(3, s, session[s].tunnel, " Radius reply contains route for %s/%s\n",
ips = strdup(inet_toa(htonl(ip))); fmtaddr(htonl(ip), 0), fmtaddr(htonl(mask), 1));
masks = strdup(inet_toa(htonl(mask)));
LOG(3, 0, s, session[s].tunnel, " Radius reply contains route for %s/%s\n", ips, masks);
free(ips);
free(masks);
session[s].route[routes].ip = ip; session[s].route[routes].ip = ip;
session[s].route[routes].mask = mask; session[s].route[routes].mask = mask;
routes++; routes++;
@ -550,7 +552,7 @@ void processrad(u8 *buf, int len, char socket_index)
u8 *f = 0; u8 *f = 0;
int i; int i;
LOG(3, 0, s, session[s].tunnel, " Radius reply contains Filter-Id \"%.*s\"\n", l, filter); LOG(3, s, session[s].tunnel, " Radius reply contains Filter-Id \"%.*s\"\n", l, filter);
if ((suffix = memchr(filter, '.', l))) if ((suffix = memchr(filter, '.', l)))
{ {
int b = suffix - filter; int b = suffix - filter;
@ -564,7 +566,7 @@ void processrad(u8 *buf, int len, char socket_index)
if (!f) if (!f)
{ {
LOG(3, 0, s, session[s].tunnel, " Invalid filter\n"); LOG(3, s, session[s].tunnel, " Invalid filter\n");
continue; continue;
} }
@ -576,7 +578,7 @@ void processrad(u8 *buf, int len, char socket_index)
if (*f) if (*f)
ip_filters[*f - 1].used++; ip_filters[*f - 1].used++;
else else
LOG(3, 0, s, session[s].tunnel, " Unknown filter\n"); LOG(3, s, session[s].tunnel, " Unknown filter\n");
} }
else if (*p == 26) else if (*p == 26)
@ -585,16 +587,16 @@ void processrad(u8 *buf, int len, char socket_index)
int vendor = ntohl(*(int *)(p + 2)); int vendor = ntohl(*(int *)(p + 2));
char attrib = *(p + 6); char attrib = *(p + 6);
char attrib_length = *(p + 7) - 2; char attrib_length = *(p + 7) - 2;
LOG(3, 0, s, session[s].tunnel, " Radius reply contains Vendor-Specific. Vendor=%d Attrib=%d Length=%d\n", vendor, attrib, attrib_length); LOG(3, s, session[s].tunnel, " Radius reply contains Vendor-Specific. Vendor=%d Attrib=%d Length=%d\n", vendor, attrib, attrib_length);
if (attrib_length == 0) continue; if (attrib_length == 0) continue;
if (attrib != 1) if (attrib != 1)
LOG(3, 0, s, session[s].tunnel, " Unknown vendor-specific\n"); LOG(3, s, session[s].tunnel, " Unknown vendor-specific\n");
else else
{ {
char *avpair, *value, *key, *newp; char *avpair, *value, *key, *newp;
avpair = key = calloc(attrib_length + 1, 1); avpair = key = calloc(attrib_length + 1, 1);
memcpy(avpair, p + 8, attrib_length); memcpy(avpair, p + 8, attrib_length);
LOG(3, 0, s, session[s].tunnel, " Cisco-Avpair value: %s\n", avpair); LOG(3, s, session[s].tunnel, " Cisco-Avpair value: %s\n", avpair);
do { do {
value = strchr(key, '='); value = strchr(key, '=');
if (!value) break; if (!value) break;
@ -626,7 +628,7 @@ void processrad(u8 *buf, int len, char socket_index)
} }
else if (*buf == 3) else if (*buf == 3)
{ {
LOG(2, 0, s, session[s].tunnel, " Authentication denied for %s\n", session[s].user); LOG(2, s, session[s].tunnel, " Authentication denied for %s\n", session[s].user);
//FIXME: We should tear down the session here! //FIXME: We should tear down the session here!
break; break;
} }
@ -634,12 +636,12 @@ void processrad(u8 *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 = htonl(config->default_dns1);
LOG(3, 0, s, t, " Sending dns1 = %s\n", inet_toa(config->default_dns1)); 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 = htonl(config->default_dns2);
LOG(3, 0, s, t, " Sending dns2 = %s\n", inet_toa(config->default_dns2)); LOG(3, s, t, " Sending dns2 = %s\n", fmtaddr(config->default_dns2, 0));
} }
// Valid Session, set it up // Valid Session, set it up
@ -649,7 +651,7 @@ void processrad(u8 *buf, int len, char socket_index)
else else
{ {
// An ack for a stop or start record. // An ack for a stop or start record.
LOG(3, 0, s, t, " RADIUS accounting ack recv in state %s\n", radius_states[radius[r].state]); LOG(3, s, t, " RADIUS accounting ack recv in state %s\n", radius_states[radius[r].state]);
break; break;
} }
} while (0); } while (0);
@ -691,7 +693,7 @@ void radiusretry(u16 r)
case RADIUSWAIT: // waiting timeout before available, in case delayed reply from RADIUS server case RADIUSWAIT: // waiting timeout before available, in case delayed reply from RADIUS server
// free up RADIUS task // free up RADIUS task
radiusclear(r, s); radiusclear(r, s);
LOG(3, 0, s, session[s].tunnel, "Freeing up radius session %d\n", r); LOG(3, s, session[s].tunnel, "Freeing up radius session %d\n", r);
break; break;
} }
} }

View file

@ -4,7 +4,7 @@
/* strip domain part of username before sending RADIUS requests */ /* strip domain part of username before sending RADIUS requests */
char const *cvs_id = "$Id: stripdomain.c,v 1.6 2004-11-17 08:23:35 bodea Exp $"; char const *cvs_id = "$Id: stripdomain.c,v 1.7 2004-11-29 02:17:18 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION; int plugin_api_version = PLUGIN_API_VERSION;
static struct pluginfuncs *p = 0; static struct pluginfuncs *p = 0;
@ -18,7 +18,7 @@ int plugin_pre_auth(struct param_pre_auth *data)
// Strip off @domain // Strip off @domain
if ((x = strchr(data->username, '@'))) if ((x = strchr(data->username, '@')))
{ {
p->log(3, 0, 0, 0, "Stripping off trailing domain name \"%s\"\n", x); p->log(3, 0, 0, "Stripping off trailing domain name \"%s\"\n", x);
*x = 0; *x = 0;
} }

14
tbf.c
View file

@ -1,6 +1,6 @@
// L2TPNS: token bucket filters // L2TPNS: token bucket filters
char const *cvs_id_tbf = "$Id: tbf.c,v 1.9 2004-11-05 04:55:27 bodea Exp $"; char const *cvs_id_tbf = "$Id: tbf.c,v 1.10 2004-11-29 02:17:18 bodea Exp $";
#include <string.h> #include <string.h>
#include "l2tpns.h" #include "l2tpns.h"
@ -54,7 +54,7 @@ static void del_from_timer(int id)
if (filter_list[id].next == id) { // Last element in chain? if (filter_list[id].next == id) { // Last element in chain?
if (timer_chain != id) { // WTF? if (timer_chain != id) { // WTF?
LOG(0,0,0,0, "Removed a singleton element from TBF, but tc didn't point to it!\n"); LOG(0, 0, 0, "Removed a singleton element from TBF, but tc didn't point to it!\n");
} else } else
timer_chain = -1; timer_chain = -1;
filter_list[id].next = filter_list[id].prev = 0; filter_list[id].next = filter_list[id].prev = 0;
@ -96,7 +96,7 @@ int new_tbf(int sid, int max_credit, int rate, void (*f)(sessionidt, u8 *, int))
int i; int i;
static int p = 0; static int p = 0;
LOG(4,0,0,0, "Allocating new TBF (sess %d, rate %d, helper %p)\n", sid, rate, f); LOG(4, 0, 0, "Allocating new TBF (sess %d, rate %d, helper %p)\n", sid, rate, f);
if (!filter_list) if (!filter_list)
return 0; // Couldn't alloc memory! return 0; // Couldn't alloc memory!
@ -116,7 +116,7 @@ int new_tbf(int sid, int max_credit, int rate, void (*f)(sessionidt, u8 *, int))
return p; return p;
} }
LOG(0,0,0,0, "Ran out of token bucket filters! Sess %d will be un-throttled\n", sid); LOG(0, 0, 0, "Ran out of token bucket filters! Sess %d will be un-throttled\n", sid);
return 0; return 0;
} }
@ -300,7 +300,7 @@ int tbf_run_timer(void)
if (filter_list[i].lasttime == TIME) // Did we just run it? if (filter_list[i].lasttime == TIME) // Did we just run it?
continue; continue;
LOG(1,0,0,0, "Missed tbf %d! Not on the timer chain?(n %d, p %d, tc %d)\n", i, LOG(1, 0, 0, "Missed tbf %d! Not on the timer chain?(n %d, p %d, tc %d)\n", i,
filter_list[i].next, filter_list[i].prev, timer_chain); filter_list[i].next, filter_list[i].prev, timer_chain);
tbf_run_queue(i); tbf_run_queue(i);
} }
@ -318,7 +318,9 @@ int cmd_show_tbf(struct cli_def *cli, char *command, char **argv, int argc)
return CLI_HELP_NO_ARGS; return CLI_HELP_NO_ARGS;
if (!config->cluster_iam_master) { if (!config->cluster_iam_master) {
cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address)); cli_print(cli, "Can't do this on a slave. Do it on %s",
fmtaddr(config->cluster_master_address, 0));
return CLI_OK; return CLI_OK;
} }

17
util.c
View file

@ -1,6 +1,6 @@
/* Misc util functions */ /* Misc util functions */
char const *cvs_id_util = "$Id: util.c,v 1.6 2004-11-16 07:54:32 bodea Exp $"; char const *cvs_id_util = "$Id: util.c,v 1.7 2004-11-29 02:17:18 bodea Exp $";
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
@ -16,11 +16,16 @@ char const *cvs_id_util = "$Id: util.c,v 1.6 2004-11-16 07:54:32 bodea Exp $";
#include "bgp.h" #include "bgp.h"
#endif #endif
char *inet_toa(unsigned long addr) // format ipv4 addr as a dotted-quad; n chooses one of 4 static buffers
// to use
char *fmtaddr(ipt addr, int n)
{ {
static char addrs[4][16];
struct in_addr in; struct in_addr in;
memcpy(&in, &addr, sizeof(unsigned long));
return inet_ntoa(in); if (n < 0 || n >= 4) return "";
in.s_addr = addr;
return strcpy(addrs[n], inet_ntoa(in));
} }
void *shared_malloc(unsigned int size) void *shared_malloc(unsigned int size)
@ -51,8 +56,8 @@ pid_t fork_and_close()
params.sched_priority = 0; params.sched_priority = 0;
if (sched_setscheduler(0, SCHED_OTHER, &params)) if (sched_setscheduler(0, SCHED_OTHER, &params))
{ {
LOG(0, 0, 0, 0, "Error setting scheduler to OTHER after fork: %s\n", strerror(errno)); LOG(0, 0, 0, "Error setting scheduler to OTHER after fork: %s\n", strerror(errno));
LOG(0, 0, 0, 0, "This is probably really really bad.\n"); LOG(0, 0, 0, "This is probably really really bad.\n");
} }
} }

2
util.h
View file

@ -1,7 +1,7 @@
#ifndef __UTIL_H__ #ifndef __UTIL_H__
#define __UTIL_H__ #define __UTIL_H__
char *inet_toa(unsigned long addr); char *fmtaddr(ipt addr, int n);
void *shared_malloc(unsigned int size); void *shared_malloc(unsigned int size);
pid_t fork_and_close(void); pid_t fork_and_close(void);