// L2TPNS Clustering Stuff
-char const *cvs_id_cluster = "$Id: cluster.c,v 1.17 2004/11/09 03:09:12 bodea Exp $";
+char const *cvs_id_cluster = "$Id: cluster.c,v 1.18 2004/11/16 07:54:32 bodea Exp $";
#include <stdio.h>
#include <sys/file.h>
} peers[CLUSTER_MAX_SIZE]; // List of all the peers we've heard from.
static int num_peers; // Number of peers in list.
-int rle_decompress(u8 ** src_p, int ssize, u8 *dst, int dsize);
-int rle_compress(u8 ** src_p, int ssize, u8 *dst, int dsize);
+static int rle_decompress(u8 ** src_p, int ssize, u8 *dst, int dsize);
+static int rle_compress(u8 ** src_p, int ssize, u8 *dst, int dsize);
//
// Create a listening socket
// address ).
//
-int cluster_send_data(void *data, int datalen)
+static int cluster_send_data(void *data, int datalen)
{
struct sockaddr_in addr = {0};
send_garp(config->bind_address); // Start taking traffic.
}
-void cluster_uptodate(void)
+static void cluster_uptodate(void)
{
if (config->cluster_iam_uptodate)
return;
// Send a unicast UDP packet to a peer with 'data' as the
// contents.
//
-int peer_send_data(u32 peer, char * data, int size)
+static int peer_send_data(u32 peer, char * data, int size)
{
struct sockaddr_in addr = {0};
//
// Send a structured message to a peer with a single element of type 'type'.
//
-int peer_send_message(u32 peer, int type, int more, char * data, int size)
+static int peer_send_message(u32 peer, int type, int more, char * data, int size)
{
char buf[65536]; // Vast overkill.
char * p = buf;
cluster_uptodate();
}
-int hb_add_type(char **p, int type, int id)
+static int hb_add_type(char **p, int type, int id)
{
switch (type) {
case C_CSESSION: { // Compressed C_SESSION.
//
// A structure of type 'type' has changed; Add it to the queue to send.
//
-int type_changed(int type, int id)
+static int type_changed(int type, int id)
{
int i;
// missed a packet. We'll resend it every packet since
// the last one it's seen.
//
-int cluster_catchup_slave(int seq, u32 slave)
+static int cluster_catchup_slave(int seq, u32 slave)
{
int s;
int diff;
// We've heard from another peer! Add it to the list
// that we select from at election time.
//
-int cluster_add_peer(u32 peer, time_t basetime, pingt *pp, int size)
+static int cluster_add_peer(u32 peer, time_t basetime, pingt *pp, int size)
{
int i;
u32 clusterid;
// Note that we don't mark the session as dirty; We rely on
// the slow table walk to propogate this back out to the slaves.
//
-int cluster_handle_bytes(char * data, int size)
+static int cluster_handle_bytes(char * data, int size)
{
bytest * b;
//
// Worst case is a 50% expansion in space required (trying to
// compress { 0x00, 0x01 } * N )
-int rle_compress(u8 ** src_p, int ssize, u8 *dst, int dsize)
+static int rle_compress(u8 ** src_p, int ssize, u8 *dst, int dsize)
{
int count;
int orig_dsize = dsize;
// Return the number of dst bytes used.
// Updates the 'src_p' pointer to point to the
// first un-used byte.
-int rle_decompress(u8 ** src_p, int ssize, u8 *dst, int dsize)
+static int rle_decompress(u8 ** src_p, int ssize, u8 *dst, int dsize)
{
int count;
int orig_dsize = dsize;
// Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
// vim: sw=8 ts=8
-char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.48 2004/11/11 03:07:42 bodea Exp $";
+char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.49 2004/11/16 07:54:32 bodea Exp $";
#include <arpa/inet.h>
#include <assert.h>
int tunfd = -1; // tun interface file handle. (network device)
int udpfd = -1; // UDP file handle
int controlfd = -1; // Control signal handle
+int clifd = -1; // Socket listening for CLI connections.
int snoopfd = -1; // UDP file handle for sending out intercept data
int *radfds = NULL; // RADIUS requests file handles
int ifrfd = -1; // File descriptor for routing, etc
time_t basetime = 0; // base clock
char hostname[1000] = ""; // us.
-int tunidx; // ifr_ifindex of tun device
-u32 sessionid = 0; // session id for radius accounting
-int syslog_log = 0; // are we logging to syslog
-FILE *log_stream = NULL; // file handle for direct logging (i.e. direct into file, not via syslog).
+static u32 sessionid = 0; // session id for radius accounting
+static int syslog_log = 0; // are we logging to syslog
+static FILE *log_stream = NULL; // file handle for direct logging (i.e. direct into file, not via syslog).
extern int cluster_sockfd; // Intra-cluster communications socket.
u32 last_id = 0; // Last used PPP SID. Can I kill this?? -- mo
-int clifd = 0; // Socket listening for CLI connections.
struct cli_session_actions *cli_session_actions = NULL; // Pending session changes requested by CLI
struct cli_tunnel_actions *cli_tunnel_actions = NULL; // Pending tunnel changes required by CLI
static void *ip_hash[256]; // Mapping from IP address to session structures.
-u32 udp_tx = 0, udp_rx = 0, udp_rx_pkt = 0; // Global traffic counters.
-u32 eth_tx = 0, eth_rx = 0, eth_rx_pkt = 0;
-u32 ip_pool_size = 1; // Size of the pool of addresses used for dynamic address allocation.
-time_t time_now = 0; // Current time in seconds since epoch.
-char time_now_string[64] = {0}; // Current time as a string.
-char main_quit = 0; // True if we're in the process of exiting.
-char *_program_name = NULL;
+// Traffic counters.
+static u32 udp_rx = 0, udp_rx_pkt = 0, udp_tx = 0;
+static u32 eth_rx = 0, eth_rx_pkt = 0;
+u32 eth_tx = 0;
+
+static u32 ip_pool_size = 1; // Size of the pool of addresses used for dynamic address allocation.
+time_t time_now = 0; // Current time in seconds since epoch.
+static char time_now_string[64] = {0}; // Current time as a string.
+static char main_quit = 0; // True if we're in the process of exiting.
linked_list *loaded_plugins;
linked_list *plugins[MAX_PLUGIN_TYPES];
{ NULL, 0, 0, 0 },
};
-char *plugin_functions[] = {
+static char *plugin_functions[] = {
NULL,
"plugin_pre_auth",
"plugin_post_auth",
sessioncountt *sess_count = NULL; // Array of partial per-session traffic counters.
radiust *radius = NULL; // Array of radius structures.
ippoolt *ip_address_pool = NULL; // Array of dynamic IP addresses.
-controlt *controlfree = 0;
+static controlt *controlfree = 0;
struct Tstats *_statistics = NULL;
#ifdef RINGBUFFER
struct Tringbuffer *ringbuffer = NULL;
#endif
-void sigalrm_handler(int);
-void sighup_handler(int);
-void sigterm_handler(int);
-void sigquit_handler(int);
-void sigchild_handler(int);
-void read_config_file();
-void read_state();
-void dump_state();
-void tunnel_clean();
-tunnelidt new_tunnel();
-void update_config();
-int unhide_avp(u8 *avp, tunnelidt t, sessionidt s, u16 length);
-
static void cache_ipmap(ipt ip, int s);
static void uncache_ipmap(ipt ip);
+static void free_ip_address(sessionidt s);
+static void dump_acct_info(void);
+static void sighup_handler(int sig);
+static void sigalrm_handler(int sig);
+static void sigterm_handler(int sig);
+static void sigquit_handler(int sig);
+static void sigchild_handler(int sig);
+static void read_state(void);
+static void dump_state(void);
+static void build_chap_response(char *challenge, u8 id, u16 challenge_length, char **challenge_response);
+static void update_config(void);
+static void read_config_file(void);
+static void initplugins(void);
+static void add_plugin(char *plugin_name);
+static void remove_plugin(char *plugin_name);
+static void plugins_done(void);
+static void processcontrol(u8 * buf, int len, struct sockaddr_in *addr);
+static tunnelidt new_tunnel(void);
+static int unhide_avp(u8 *avp, tunnelidt t, sessionidt s, u16 length);
// return internal time (10ths since process startup)
-clockt now(void)
+static clockt now(void)
{
struct timeval t;
gettimeofday(&t, 0);
// Add a route
//
// This adds it to the routing table, advertises it
-// via iBGP if enabled, and stuffs it into the
+// via BGP if enabled, and stuffs it into the
// 'sessionbyip' cache.
//
// 'ip' and 'mask' must be in _host_ order.
//
-void routeset(sessionidt s, ipt ip, ipt mask, ipt gw, u8 add)
+static void routeset(sessionidt s, ipt ip, ipt mask, ipt gw, u8 add)
{
struct rtentry r;
int i;
#endif /* BGP */
// Add/Remove the IPs to the 'sessionbyip' cache.
- // Note that we add the zero address in the case of
+ // Note that we add the zero address in the case of
// a network route. Roll on CIDR.
// Note that 's == 0' implies this is the address pool.
//
// Set up TUN interface
-void inittun(void)
+static void inittun(void)
{
struct ifreq ifr;
struct sockaddr_in sin = {0};
LOG(0, 0, 0, 0, "Error setting tun flags: %s\n", strerror(errno));
exit(1);
}
- if (ioctl(ifrfd, SIOCGIFINDEX, (void *) &ifr) < 0)
- {
- LOG(0, 0, 0, 0, "Error setting tun ifindex: %s\n", strerror(errno));
- exit(1);
- }
- tunidx = ifr.ifr_ifindex;
}
// set up UDP port
-void initudp(void)
+static void initudp(void)
{
int on = 1;
struct sockaddr_in addr;
// IP address.
//
-int lookup_ipmap(ipt ip)
+static int lookup_ipmap(ipt ip)
{
u8 *a = (u8 *)&ip;
char **d = (char **) ip_hash;
}
// Find session by username, 0 for not found
-sessiont *sessiontbysessionidt(sessionidt s)
+static sessiont *sessiontbysessionidt(sessionidt s)
{
if (!s || s > MAXSESSION) return NULL;
return &session[s];
}
-sessionidt sessionidtbysessiont(sessiont *s)
+static sessionidt sessionidtbysessiont(sessiont *s)
{
sessionidt val = s-session;
if (s < session || val > MAXSESSION) return 0;
// process outgoing (to tunnel) IP
//
-void processipout(u8 * buf, int len)
+static void processipout(u8 * buf, int len)
{
sessionidt s;
sessiont *sp;
// Helper routine for the TBF filters.
// Used to send queued data in to the user!
//
-void send_ipout(sessionidt s, u8 *buf, int len)
+static void send_ipout(sessionidt s, u8 *buf, int len)
{
sessiont *sp;
tunnelidt t;
}
// add an AVP (16 bit)
-void control16(controlt * c, u16 avp, u16 val, u8 m)
+static void control16(controlt * c, u16 avp, u16 val, u8 m)
{
u16 l = (m ? 0x8008 : 0x0008);
*(u16 *) (c->buf + c->length + 0) = htons(l);
}
// add an AVP (32 bit)
-void control32(controlt * c, u16 avp, u32 val, u8 m)
+static void control32(controlt * c, u16 avp, u32 val, u8 m)
{
u16 l = (m ? 0x800A : 0x000A);
*(u16 *) (c->buf + c->length + 0) = htons(l);
}
// add an AVP (32 bit)
-void controls(controlt * c, u16 avp, char *val, u8 m)
+static void controls(controlt * c, u16 avp, char *val, u8 m)
{
u16 l = ((m ? 0x8000 : 0) + strlen(val) + 6);
*(u16 *) (c->buf + c->length + 0) = htons(l);
}
// add a binary AVP
-void controlb(controlt * c, u16 avp, char *val, unsigned int len, u8 m)
+static void controlb(controlt * c, u16 avp, char *val, unsigned int len, u8 m)
{
u16 l = ((m ? 0x8000 : 0) + len + 6);
*(u16 *) (c->buf + c->length + 0) = htons(l);
}
// new control connection
-controlt *controlnew(u16 mtype)
+static controlt *controlnew(u16 mtype)
{
controlt *c;
if (!controlfree)
// send zero block if nothing is waiting
// (ZLB send).
-void controlnull(tunnelidt t)
+static void controlnull(tunnelidt t)
{
u8 buf[12];
if (tunnel[t].controlc) // Messages queued; They will carry the ack.
}
// add a control message to a tunnel, and send if within window
-void controladd(controlt * c, tunnelidt t, sessionidt s)
+static void controladd(controlt * c, tunnelidt t, sessionidt s)
{
*(u16 *) (c->buf + 2) = htons(c->length); // length
*(u16 *) (c->buf + 4) = htons(tunnel[t].far); // tunnel
// start tidy shutdown of session
void sessionshutdown(sessionidt s, char *reason)
{
- int dead = session[s].die;
int walled_garden = session[s].walled_garden;
return; // not a live session
}
- if (!dead)
- LOG(2, 0, s, session[s].tunnel, "Shutting down session %d: %s\n", s, reason);
-
- session[s].die = now() + 150; // Clean up in 15 seconds
-
+ if (!session[s].die)
{
struct param_kill_session data = { &tunnel[session[s].tunnel], &session[s] };
+ LOG(2, 0, s, session[s].tunnel, "Shutting down session %d: %s\n", s, reason);
run_plugins(PLUGIN_KILL_SESSION, &data);
}
// RADIUS Stop message
- if (session[s].opened && !walled_garden && !dead)
+ if (session[s].opened && !walled_garden && !session[s].die)
{
u16 r = session[s].radius;
if (!r)
int r;
for (r = 0; r < MAXROUTE && session[s].route[r].ip; r++)
{
- routeset(s, session[s].route[r].ip, session[s].route[r].mask, session[s].ip, 0);
+ routeset(s, session[s].route[r].ip, session[s].route[r].mask, 0, 0);
session[s].route[r].ip = 0;
}
controladd(c, session[s].tunnel, s); // send the message
}
+ if (!session[s].die)
+ session[s].die = now() + 150; // Clean up in 15 seconds
+
cluster_send_session(s);
}
}
// kill a session now
-void sessionkill(sessionidt s, char *reason)
+static void sessionkill(sessionidt s, char *reason)
{
CSTAT(call_sessionkill);
cluster_send_session(s);
}
+static void tunnelclear(tunnelidt t)
+{
+ if (!t) return;
+ memset(&tunnel[t], 0, sizeof(tunnel[t]));
+ tunnel[t].state = TUNNELFREE;
+}
+
// kill a tunnel now
-void tunnelkill(tunnelidt t, char *reason)
+static void tunnelkill(tunnelidt t, char *reason)
{
sessionidt s;
controlt *c;
}
// shut down a tunnel cleanly
-void tunnelshutdown(tunnelidt t, char *reason)
+static void tunnelshutdown(tunnelidt t, char *reason)
{
sessionidt s;
// close session
for (s = 1; s < MAXSESSION; s++)
if (session[s].tunnel == t)
- sessionkill(s, reason);
+ sessionshutdown(s, reason);
tunnel[t].state = TUNNELDIE;
tunnel[t].die = now() + 700; // Clean up in 70 seconds
}
// read and process packet on tun
-void processtun(u8 * buf, int len)
+static void processtun(u8 * buf, int len)
{
LOG_HEX(5, "Receive TUN Data", buf, len);
STAT(tun_rx_packets);
// at once.
#define MAX_ACTIONS 500
-int regular_cleanups(void)
+static int regular_cleanups(void)
{
static sessionidt s = 0; // Next session to check for actions on.
tunnelidt t;
// Are we in the middle of a tunnel update, or radius
// requests??
//
-int still_busy(void)
+static int still_busy(void)
{
int i;
static clockt last_talked = 0;
static int readset_n = 0;
// main loop - gets packets on tun or udp and processes them
-void mainloop(void)
+static void mainloop(void)
{
int i;
u8 buf[65536];
}
// Init data structures
-void initdata(int optdebug, char *optconfig)
+static void initdata(int optdebug, char *optconfig)
{
int i;
#endif /* BGP */
}
-int assign_ip_address(sessionidt s)
+static int assign_ip_address(sessionidt s)
{
u32 i;
int best = -1;
return 1;
}
-void free_ip_address(sessionidt s)
+static void free_ip_address(sessionidt s)
{
int i = session[s].ip_pool_index;
+
+ CSTAT(call_free_ip_address);
+
if (!session[s].ip)
return; // what the?
ip_address_pool[i].assigned = 0;
ip_address_pool[i].session = 0;
ip_address_pool[i].last = time_now;
-
-
- CSTAT(call_free_ip_address);
-
}
//
//
// Fix the address pool to match a changed session.
// (usually when the master sends us an update).
-void fix_address_pool(int sid)
+static void fix_address_pool(int sid)
{
int ipid;
//
// Add a block of addresses to the IP pool to hand out.
//
-void add_to_ip_pool(u32 addr, u32 mask)
+static void add_to_ip_pool(u32 addr, u32 mask)
{
int i;
if (mask == 0)
}
// Initialize the IP address pool
-void initippool()
+static void initippool()
{
FILE *f;
char *p;
STAT(packets_snooped);
}
-void dump_acct_info()
+static void dump_acct_info()
{
char filename[1024];
char timestr[64];
int optdebug = 0;
char *optconfig = CONFIGFILE;
- _program_name = strdup(argv[0]);
-
time(&basetime); // start clock
// scan args
}
/* Set up the cluster communications port. */
- if (cluster_init(config->bind_address) < 0)
+ if (cluster_init() < 0)
exit(1);
#ifdef BGP
return 0;
}
-void sighup_handler(int junk)
+static void sighup_handler(int sig)
{
if (log_stream && log_stream != stderr)
{
read_config_file();
}
-void sigalrm_handler(int junk)
+static void sigalrm_handler(int sig)
{
// Log current traffic stats
}
-void sigterm_handler(int junk)
+static void sigterm_handler(int sig)
{
LOG(1, 0, 0, 0, "Shutting down cleanly\n");
if (config->save_state)
main_quit++;
}
-void sigquit_handler(int junk)
+static void sigquit_handler(int sig)
{
int i;
main_quit++;
}
-void sigchild_handler(int signal)
+static void sigchild_handler(int sig)
{
while (waitpid(-1, NULL, WNOHANG) > 0)
;
}
-void read_state()
+static void read_state()
{
struct stat sb;
int i;
LOG(0, 0, 0, 0, "Loaded saved state information\n");
}
-void dump_state()
+static void dump_state()
{
FILE *f;
u32 buf[2];
unlink(STATEFILE);
}
-void build_chap_response(char *challenge, u8 id, u16 challenge_length, char **challenge_response)
+static void build_chap_response(char *challenge, u8 id, u16 challenge_length, char **challenge_response)
{
MD5_CTX ctx;
*challenge_response = NULL;
return 0;
}
-void update_config()
+static void update_config()
{
int i;
static int timeout = 0;
config->reload_config = 0;
}
-void read_config_file()
+static void read_config_file()
{
FILE *f;
cache_ipmap(session[s].ip, s);
for (r = 0; r < MAXROUTE && session[s].route[r].ip; r++)
- routeset(s, session[s].route[r].ip, session[s].route[r].mask, session[s].ip, 1);
+ routeset(s, session[s].route[r].ip, session[s].route[r].mask, 0, 1);
if (!session[s].unique_id)
{
// Remove any routes if the IP has changed
for (i = 0; i < MAXROUTE && session[s].route[i].ip; i++)
{
- routeset(s, session[s].route[i].ip, session[s].route[i].mask, session[s].ip, 0);
+ routeset(s, session[s].route[i].ip, session[s].route[i].mask, 0, 0);
session[s].route[i].ip = 0;
}
continue;
if (session[s].route[i].ip) // Remove the old one if it exists.
- routeset(s, session[s].route[i].ip, session[s].route[i].mask, session[s].ip, 0);
+ routeset(s, session[s].route[i].ip, session[s].route[i].mask, 0, 0);
if (new->route[i].ip) // Add the new one if it exists.
- routeset(s, new->route[i].ip, new->route[i].mask, new->ip, 1);
+ routeset(s, new->route[i].ip, new->route[i].mask, 0, 1);
}
if (new->tunnel && s > config->cluster_highest_sessionid) // Maintain this in the slave. It's used
return 1;
}
-#ifdef RINGBUFFER
-void ringbuffer_dump(FILE *stream)
-{
- int i = ringbuffer->head;
-
- while (i != ringbuffer->tail)
- {
- if (*ringbuffer->buffer[i].message)
- fprintf(stream, "%d-%s", ringbuffer->buffer[i].level, ringbuffer->buffer[i].message);
- if (++i == ringbuffer->tail) break;
- if (i == RINGBUFFER_SIZE) i = 0;
- }
-}
-#endif
-
-void initplugins()
+static void initplugins()
{
int i;
return 0;
}
-void add_plugin(char *plugin_name)
+static void add_plugin(char *plugin_name)
{
static struct pluginfuncs funcs = {
_log,
donefunc();
}
-void remove_plugin(char *plugin_name)
+static void remove_plugin(char *plugin_name)
{
void *p = open_plugin(plugin_name, 0);
int i;
return 1;
}
-void plugins_done()
+static void plugins_done()
{
void *p;
run_plugin_done(p);
}
-void processcontrol(u8 * buf, int len, struct sockaddr_in *addr)
+static void processcontrol(u8 * buf, int len, struct sockaddr_in *addr)
{
char *resp;
int l;
free(resp);
}
-void tunnelclear(tunnelidt t)
-{
- if (!t) return;
- memset(&tunnel[t], 0, sizeof(tunnel[t]));
- tunnel[t].state = TUNNELFREE;
-}
-
-tunnelidt new_tunnel()
+static tunnelidt new_tunnel()
{
tunnelidt i;
for (i = 1; i < MAXTUNNEL; i++)
// add radius fds
for (i = 0; i < config->num_radfds; i++)
{
- if (!radfds[i]) continue;
FD_SET(radfds[i], &readset);
if (radfds[i] > readset_n)
readset_n = radfds[i];
*
* Based on code from rp-l2tpd by Roaring Penguin Software Inc.
*/
-int unhide_avp(u8 *avp, tunnelidt t, sessionidt s, u16 length)
+static int unhide_avp(u8 *avp, tunnelidt t, sessionidt s, u16 length)
{
MD5_CTX ctx;
u8 *cursor;
// L2TPNS Global Stuff
-// $Id: l2tpns.h,v 1.34 2004/11/15 07:01:54 bodea Exp $
+// $Id: l2tpns.h,v 1.35 2004/11/16 07:54:32 bodea Exp $
#ifndef __L2TPNS_H__
#define __L2TPNS_H__
#include <sys/types.h>
#include <libcli.h>
-#define VERSION "2.0.7"
+#define VERSION "2.0.8"
// Limits
#define MAXTUNNEL 500 // could be up to 65535
void processccp(tunnelidt t, sessionidt s, u8 * p, u16 l);
void sendchap(tunnelidt t, sessionidt s);
u8 *makeppp(u8 * b, int size, u8 * p, int l, tunnelidt t, sessionidt s, u16 mtype);
-u8 *findppp(u8 * b, u8 mtype);
void initlcp(tunnelidt t, sessionidt s);
-void dumplcp(u8 *p, int l);
+void send_ipin(sessionidt s, u8 * buf, int len);
// radius.c
// l2tpns.c
-clockt now(void);
clockt backoff(u8 try);
-void routeset(sessionidt, ipt ip, ipt mask, ipt gw, u8 add);
-void inittun(void);
-void initudp(void);
-void initdata(int optdebug, char *optconfig);
-void initippool();
sessionidt sessionbyip(ipt ip);
sessionidt sessionbyuser(char *username);
void sessionshutdown(sessionidt s, char *reason);
-void sessionsendarp(sessionidt s);
void send_garp(ipt ip);
-void sessionkill(sessionidt s, char *reason);
-void control16(controlt * c, u16 avp, u16 val, u8 m);
-void control32(controlt * c, u16 avp, u32 val, u8 m);
-void controls(controlt * c, u16 avp, char *val, u8 m);
-void controlb(controlt * c, u16 avp, char *val, unsigned int len, u8 m);
-controlt *controlnew(u16 mtype);
-void controlnull(tunnelidt t);
-void controladd(controlt * c, tunnelidt t, sessionidt s);
void tunnelsend(u8 * buf, u16 l, tunnelidt t);
-void tunnelkill(tunnelidt t, char *reason);
-void tunnelshutdown(tunnelidt t, char *reason);
void sendipcp(tunnelidt t, sessionidt s);
-void processipout(u8 * buf, int len);
-void processarp(u8 * buf, int len);
void processudp(u8 * buf, int len, struct sockaddr_in *addr);
-void processtun(u8 * buf, int len);
-void processcontrol(u8 * buf, int len, struct sockaddr_in *addr);
-int assign_ip_address(sessionidt s);
-void free_ip_address(sessionidt s);
void snoop_send_packet(char *packet, u16 size, ipt destination, u16 port);
-void dump_acct_info();
-void mainloop(void);
int cmd_show_ipcache(struct cli_def *cli, char *command, char **argv, int argc);
int cmd_show_hist_idle(struct cli_def *cli, char *command, char **argv, int argc);
int cmd_show_hist_open(struct cli_def *cli, char *command, char **argv, int argc);
void _log(int level, ipt address, sessionidt s, tunnelidt t, const char *format, ...) __attribute__((format (printf, 5, 6)));
void _log_hex(int level, const char *title, const char *data, int maxsize);
-void build_chap_response(char *challenge, u8 id, u16 challenge_length, char **challenge_response);
int sessionsetup(tunnelidt t, sessionidt s);
-int cluster_send_session(int s);
-int cluster_send_tunnel(int t);
-int cluster_send_goodbye();
-void init_cli(char *hostname);
-void cli_do_file(FILE *fh);
-void cli_do(int sockfd);
-int cli_arg_help(struct cli_def *cli, int cr_ok, char *entry, ...);
-#ifdef RINGBUFFER
-void ringbuffer_dump(FILE *stream);
-#endif
-void initplugins(void);
int run_plugins(int plugin_type, void *data);
-void add_plugin(char *plugin_name);
-void remove_plugin(char *plugin_name);
-void plugins_done(void);
-void tunnelclear(tunnelidt t);
-void host_unreachable(ipt destination, u16 id, ipt source, char *packet, int packet_len);
-void fix_address_pool(int sid);
void rebuild_address_pool(void);
-void send_ipin(sessionidt s, u8 * buf, int len);
void throttle_session(sessionidt s, int rate_in, int rate_out);
int load_session(sessionidt, sessiont *);
void become_master(void); // We're the master; kick off any required master initializations.
+
+
+// cli.c
+void init_cli(char *hostname);
+void cli_do_file(FILE *fh);
+void cli_do(int sockfd);
+int cli_arg_help(struct cli_def *cli, int cr_ok, char *entry, ...);
+
+
+// icmp.c
+void host_unreachable(ipt destination, u16 id, ipt source, char *packet, int packet_len);
+
+
extern tunnelt *tunnel;
extern sessiont *session;
extern sessioncountt *sess_count;