X-Git-Url: http://git.sameswireless.fr/l2tpns.git/blobdiff_plain/6b1075b65c4239e97629f3a891f49f5ae9ef3d4b..bcc4b6a3bbb8642f6adfc1a4017b878dad1aa06d:/l2tpns.h diff --git a/l2tpns.h b/l2tpns.h index db96836..03619a4 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -1,5 +1,5 @@ // L2TPNS Global Stuff -// $Id: l2tpns.h,v 1.47 2004/12/16 08:49:53 bodea Exp $ +// $Id: l2tpns.h,v 1.80 2005/06/28 14:48:27 bodea Exp $ #ifndef __L2TPNS_H__ #define __L2TPNS_H__ @@ -15,16 +15,17 @@ #include #include -#define VERSION "2.0.13" +#define VERSION "2.1.2" // Limits #define MAXTUNNEL 500 // could be up to 65535 -#define MAXSESSION 50000 // could be up to 65535 +#define MAXSESSION 60000 // could be up to 65535 #define MAXTBFS 6000 // Maximum token bucket filters. Might need up to 2 * session. -#define RADIUS_SHIFT 5 -#define RADIUS_MASK ((unsigned short)(((unsigned short)~0) >> (16 - RADIUS_SHIFT))) -#define MAXRADIUS ((unsigned long)(1L << RADIUS_SHIFT) * 255) +#define RADIUS_SHIFT 6 +#define RADIUS_FDS (1 << RADIUS_SHIFT) +#define RADIUS_MASK ((1 << RADIUS_SHIFT) - 1) +#define MAXRADIUS (1 << (8 + RADIUS_SHIFT)) #define T_UNDEF (0xffff) // A tunnel ID that won't ever be used. Mark session as undefined. #define T_FREE (0) // A tunnel ID that won't ever be used. Mark session as free. @@ -32,6 +33,8 @@ #define MAXCONTROL 1000 // max length control message we ever send... #define MAXETHER (1500+18) // max packet we try sending to tun #define MAXTEL 96 // telephone number +#define MAXUSER 128 // username +#define MAXPASS 128 // password #define MAXPLUGINS 20 // maximum number of plugins to load #define MAXRADSERVER 10 // max radius servers #define MAXROUTE 10 // max static routes per session @@ -41,6 +44,7 @@ #define ECHO_TIMEOUT 60 // Time between last packet sent and LCP ECHO generation #define IDLE_TIMEOUT 240 // Time between last packet sent and LCP ECHO generation #define BUSY_WAIT_TIME 3000 // 5 minutes in 1/10th seconds to wait for radius to cleanup on shutdown +#define DEFAULT_MRU 1452 // maximum packet size to avoid fragmentation when LNS ethernet MTU is 1500 // Constants #ifndef ETCDIR @@ -51,10 +55,6 @@ #define LIBDIR "/usr/lib/l2tpns" #endif -#ifndef STATEDIR -#define STATEDIR "/var/lib/l2tpns" -#endif - #ifndef PLUGINDIR #define PLUGINDIR LIBDIR // Plugins #endif @@ -67,12 +67,8 @@ #define FLASHDIR ETCDIR #endif -#ifndef DATADIR -#define DATADIR STATEDIR -#endif - #define TUNDEVICE "/dev/net/tun" -#define STATEFILE DATADIR "/state.dump" // State dump file +#define RANDOMDEVICE "/dev/urandom" // default, not as secure as /dev/random but non-blocking #define CONFIGFILE FLASHDIR "/startup-config" // Configuration file #define CLIUSERS FLASHDIR "/users" // CLI Users file #define IPPOOLFILE FLASHDIR "/ip_pool" // Address pool configuration @@ -80,19 +76,22 @@ #define ACCT_SHUT_TIME 600 // 1 minute for counters of shutdown sessions #define L2TPPORT 1701 // L2TP port #define RADPORT 1645 // old radius port... +#define DAEPORT 3799 // DAE port #define PKTARP 0x0806 // ARP packet type -#define PKTIP 0x0800 // IP packet type -#define PSEUDOMAC 0x0200 // pseudo MAC prefix (local significant MAC) +#define PKTIP 0x0800 // IPv4 packet type +#define PKTIPV6 0x86DD // IPv6 packet type #define PPPPAP 0xC023 #define PPPCHAP 0xC223 #define PPPLCP 0xC021 #define PPPIPCP 0x8021 +#define PPPIPV6CP 0x8057 #define PPPCCP 0x80FD #define PPPIP 0x0021 +#define PPPIPV6 0x0057 #define PPPMP 0x003D #define MIN_IP_SIZE 0x19 -enum -{ + +enum { ConfigReq = 1, ConfigAck, ConfigNak, @@ -107,6 +106,21 @@ enum IdentRequest }; +enum { + AccessRequest = 1, + AccessAccept, + AccessReject, + AccountingRequest, + AccountingResponse, + AccessChallenge = 11, + DisconnectRequest = 40, + DisconnectACK, + DisconnectNAK, + CoARequest, + CoAACK, + CoANAK +}; + // Types typedef uint16_t sessionidt; typedef uint16_t tunnelidt; @@ -138,9 +152,6 @@ struct cli_tunnel_actions { #define CLI_TUN_KILL 0x01 -// dump header: update number if internal format changes -#define DUMP_MAGIC "L2TPNS#" VERSION "#" - // structures typedef struct // route { @@ -162,58 +173,77 @@ typedef struct sessionidt next; // next session in linked list sessionidt far; // far end session ID tunnelidt tunnel; // near end tunnel ID + uint8_t l2tp_flags; // various bit flags from the ICCN on the l2tp tunnel. + uint8_t flags; // Various session flags. in_addr_t ip; // IP of session set by RADIUS response (host byte order). int ip_pool_index; // index to IP pool - unsigned long unique_id; // unique session id + uint32_t unique_id; // unique session id uint16_t nr; // next receive uint16_t ns; // next send uint32_t magic; // ppp magic number - uint32_t cin, cout; // byte counts uint32_t pin, pout; // packet counts - uint32_t total_cin; // This counter is never reset while a session is open - uint32_t total_cout; // This counter is never reset while a session is open - uint32_t id; // session id + uint32_t cin, cout; // byte counts + uint32_t cin_wrap, cout_wrap; // byte counter wrap count (RADIUS accounting giagawords) + uint32_t cin_delta, cout_delta; // byte count changes (for dump_session()) uint16_t throttle_in; // upstream throttle rate (kbps) uint16_t throttle_out; // downstream throttle rate + uint8_t filter_in; // input filter index (to ip_filters[N-1]; 0 if none) + uint8_t filter_out; // output filter index + uint16_t mru; // maximum receive unit clockt opened; // when started clockt die; // being closed, when to finally free time_t last_packet; // Last packet from the user (used for idle timeouts) in_addr_t dns1, dns2; // DNS servers routet route[MAXROUTE]; // static routes - uint16_t radius; // which radius session is being used (0 for not waiting on authentication) - uint16_t mru; // maximum receive unit uint16_t tbf_in; // filter bucket for throttling in from the user. uint16_t tbf_out; // filter bucket for throttling out to the user. - uint8_t l2tp_flags; // various bit flags from the ICCN on the l2tp tunnel. - uint8_t reserved_old_snoop; // No longer used - remove at some time - uint8_t walled_garden; // is this session gardened? - uint8_t flags1; // additional flags (currently unused); - char random_vector[MAXTEL]; int random_vector_length; - char user[129]; // user (needed in seesion for radius stop messages) (can we reduce this? --mo) + char random_vector[MAXTEL]; + char user[MAXUSER]; // user (needed in seesion for radius stop messages) char called[MAXTEL]; // called number char calling[MAXTEL]; // calling number uint32_t tx_connect_speed; uint32_t rx_connect_speed; - uint32_t flags; // Various session flags. in_addr_t snoop_ip; // Interception destination IP uint16_t snoop_port; // Interception destination port - uint16_t sid; // near end session id. - uint8_t filter_in; // input filter index (to ip_filters[N-1]; 0 if none) - uint8_t filter_out; // output filter index - char reserved[18]; // Space to expand structure without changing HB_VERSION + uint8_t walled_garden; // is this session gardened? + uint8_t ipv6prefixlen; // IPv6 route prefix length + struct in6_addr ipv6route; // Static IPv6 route + char reserved[16]; // Space to expand structure without changing HB_VERSION } sessiont; #define SF_IPCP_ACKED 1 // Has this session seen an IPCP Ack? #define SF_LCP_ACKED 2 // LCP negotiated #define SF_CCP_ACKED 4 // CCP negotiated +#define SF_IPV6CP_ACKED 8 // IPv6 negotiated +#define SF_IPV6_NACKED 16 // IPv6 rejected +#define SF_IPV6_ROUTED 32 // advertised v6 route + +#define AUTHPAP 1 // allow PAP +#define AUTHCHAP 2 // allow CHAP typedef struct { + // packet counters + uint32_t pin; + uint32_t pout; + + // byte counters uint32_t cin; uint32_t cout; -} sessioncountt; + + // DoS prevention + clockt last_packet_out; + uint32_t packets_out; + uint32_t packets_dropped; + + // RADIUS session in use + uint16_t radius; + + // interim RADIUS + time_t last_interim; +} sessionlocalt; #define SESSIONPFC 1 // PFC negotiated flags #define SESSIONACFC 2 // ACFC negotiated flags @@ -301,84 +331,95 @@ enum RADIUSIPCP, // sending IPCP to end user RADIUSSTART, // sending start accounting to RADIUS server RADIUSSTOP, // sending stop accounting to RADIUS server + RADIUSINTERIM, // sending interim accounting to RADIUS server RADIUSWAIT, // waiting timeout before available, in case delayed replies - RADIUSDEAD, // errored while talking to radius server. }; struct Tstats { - time_t start_time; - time_t last_reset; - - unsigned long tun_rx_packets; - unsigned long tun_tx_packets; - unsigned long tun_rx_bytes; - unsigned long tun_tx_bytes; - unsigned long tun_rx_errors; - unsigned long tun_tx_errors; - - unsigned long tunnel_rx_packets; - unsigned long tunnel_tx_packets; - unsigned long tunnel_rx_bytes; - unsigned long tunnel_tx_bytes; - unsigned long tunnel_rx_errors; - unsigned long tunnel_tx_errors; - - unsigned long tunnel_retries; - unsigned long radius_retries; - - unsigned long arp_sent; - - unsigned long packets_snooped; - - unsigned long tunnel_created; - unsigned long session_created; - unsigned long tunnel_timeout; - unsigned long session_timeout; - unsigned long radius_timeout; - unsigned long radius_overflow; - unsigned long tunnel_overflow; - unsigned long session_overflow; - - unsigned long ip_allocated; - unsigned long ip_freed; - - unsigned long c_forwarded; - unsigned long recv_forward; + time_t start_time; + time_t last_reset; + + uint32_t tun_rx_packets; + uint32_t tun_tx_packets; + uint32_t tun_rx_bytes; + uint32_t tun_tx_bytes; + uint32_t tun_rx_errors; + uint32_t tun_tx_errors; + uint32_t tun_rx_dropped; + + uint32_t tunnel_rx_packets; + uint32_t tunnel_tx_packets; + uint32_t tunnel_rx_bytes; + uint32_t tunnel_tx_bytes; + uint32_t tunnel_rx_errors; + uint32_t tunnel_tx_errors; + + uint32_t tunnel_retries; + uint32_t radius_retries; + + uint32_t arp_sent; + + uint32_t packets_snooped; + + uint32_t tunnel_created; + uint32_t session_created; + uint32_t tunnel_timeout; + uint32_t session_timeout; + uint32_t radius_timeout; + uint32_t radius_overflow; + uint32_t tunnel_overflow; + uint32_t session_overflow; + + uint32_t ip_allocated; + uint32_t ip_freed; + + uint32_t c_forwarded; + uint32_t recv_forward; + + uint32_t select_called; + uint32_t multi_read_used; + uint32_t multi_read_exceeded; + #ifdef STATISTICS - unsigned long call_processtun; - unsigned long call_processipout; - unsigned long call_processudp; - unsigned long call_sessionbyip; - unsigned long call_sessionbyuser; - unsigned long call_sendarp; - unsigned long call_sendipcp; - unsigned long call_tunnelsend; - unsigned long call_sessionkill; - unsigned long call_sessionshutdown; - unsigned long call_tunnelkill; - unsigned long call_tunnelshutdown; - unsigned long call_assign_ip_address; - unsigned long call_free_ip_address; - unsigned long call_dump_acct_info; - unsigned long call_sessionsetup; - unsigned long call_processpap; - unsigned long call_processchap; - unsigned long call_processlcp; - unsigned long call_processipcp; - unsigned long call_processipin; - unsigned long call_processccp; - unsigned long call_sendchap; - unsigned long call_processrad; - unsigned long call_radiussend; - unsigned long call_radiusretry; + uint32_t call_processtun; + uint32_t call_processipout; + uint32_t call_processipv6out; + uint32_t call_processudp; + uint32_t call_sessionbyip; + uint32_t call_sessionbyipv6; + uint32_t call_sessionbyuser; + uint32_t call_sendarp; + uint32_t call_sendipcp; + uint32_t call_processipv6cp; + uint32_t call_tunnelsend; + uint32_t call_sessionkill; + uint32_t call_sessionshutdown; + uint32_t call_tunnelkill; + uint32_t call_tunnelshutdown; + uint32_t call_assign_ip_address; + uint32_t call_free_ip_address; + uint32_t call_dump_acct_info; + uint32_t call_sessionsetup; + uint32_t call_processpap; + uint32_t call_processchap; + uint32_t call_processlcp; + uint32_t call_processipcp; + uint32_t call_processipin; + uint32_t call_processipv6in; + uint32_t call_processccp; + uint32_t call_sendchap; + uint32_t call_processrad; + uint32_t call_radiussend; + uint32_t call_radiusretry; + uint32_t call_random_data; #endif }; #ifdef STATISTICS #ifdef STAT_CALLS -#define CSTAT(x) STAT(x) +#define CSTAT(x) STAT(call_ ## x) #else #define CSTAT(x) #endif @@ -408,26 +449,34 @@ typedef struct char config_file[128]; int reload_config; // flag to re-read config (set by cli) - int cleanup_interval; // interval between regular cleanups (in seconds) int multi_read_count; // amount of packets to read per fd in processing loop char tundevice[10]; // tun device name char log_filename[128]; char l2tpsecret[64]; + char random_device[256]; // random device path, defaults to RANDOMDEVICE + char radiussecret[64]; int radius_accounting; + int radius_interim; in_addr_t radiusserver[MAXRADSERVER]; // radius servers uint16_t radiusport[MAXRADSERVER]; // radius base ports uint8_t numradiusservers; // radius server count - short num_radfds; // Number of radius filehandles allocated + + uint16_t radius_dae_port; // local port for radius dae + + char radius_authtypes_s[32]; // list of valid authentication types (chap, pap) in order of preference + int radius_authtypes; + int radius_authprefer; + + int allow_duplicate_users; // allow multiple logins with the same username in_addr_t default_dns1, default_dns2; unsigned long rl_rate; // default throttle rate int num_tbfs; // number of throttle buckets - int save_state; char accounting_dir[128]; in_addr_t bind_address; in_addr_t peer_address; @@ -439,9 +488,11 @@ typedef struct char old_plugins[64][MAXPLUGINS]; int next_tbf; // Next HTB id available to use - int scheduler_fifo; // If the system has multiple CPUs, use FIFO scheduling policy for this process. + int scheduler_fifo; // If the system has multiple CPUs, use FIFO scheduling + // policy for this process. int lock_pages; // Lock pages into memory. - int icmp_rate; // Max number of ICMP unreachable per second to send> + int icmp_rate; // Max number of ICMP unreachable per second to send + int max_packets; // DoS prevention: per session limit of packets/0.1s in_addr_t cluster_address; // Multicast address of cluster. // Send to this address to have everyone hear. @@ -457,12 +508,19 @@ typedef struct int cluster_highest_sessionid; int cluster_highest_tunnelid; clockt cluster_last_hb; // Last time we saw a heartbeat from the master. + int cluster_last_hb_ver; // Heartbeat version last seen from master int cluster_num_changes; // Number of changes queued. int cluster_hb_interval; // How often to send a heartbeat. int cluster_hb_timeout; // How many missed heartbeats trigger an election. uint64_t cluster_table_version; // # state changes processed by cluster + struct in6_addr ipv6_prefix; // Our IPv6 network pool. + + + int cluster_master_min_adv; // Master advertises routes while the number of up to date + // slaves is less than this value. + #ifdef BGP #define BGP_NUM_PEERS 2 uint16_t as_number; @@ -475,7 +533,7 @@ typedef struct #endif } configt; -enum config_typet { INT, STRING, UNSIGNED_LONG, SHORT, BOOL, IP, MAC }; +enum config_typet { INT, STRING, UNSIGNED_LONG, SHORT, BOOL, IPv4, IPv6, MAC }; typedef struct { char *key; @@ -545,11 +603,13 @@ void processpap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l); void processchap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l); void processlcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l); void processipcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l); +void processipv6cp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l); void processipin(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l); +void processipv6in(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l); void processccp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l); void sendchap(tunnelidt t, sessionidt s); uint8_t *makeppp(uint8_t *b, int size, uint8_t *p, int l, tunnelidt t, sessionidt s, uint16_t mtype); -void initlcp(tunnelidt t, sessionidt s); +void sendlcp(tunnelidt t, sessionidt s, int authtype); void send_ipin(sessionidt s, uint8_t *buf, int len); @@ -560,18 +620,27 @@ void processrad(uint8_t *buf, int len, char socket_index); void radiusretry(uint16_t r); uint16_t radiusnew(sessionidt s); void radiusclear(uint16_t r, sessionidt s); +void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen); // l2tpns.c clockt backoff(uint8_t try); +void send_ipv6_ra(tunnelidt t, sessionidt s, struct in6_addr *ip); +void route6set(sessionidt s, struct in6_addr ip, int prefixlen, int add); sessionidt sessionbyip(in_addr_t ip); +sessionidt sessionbyipv6(struct in6_addr ip); sessionidt sessionbyuser(char *username); -void sessionshutdown(sessionidt s, char *reason); +void increment_counter(uint32_t *counter, uint32_t *wrap, uint32_t delta); +void random_data(uint8_t *buf, int len); +void sessionkill(sessionidt s, char *reason); +void sessionshutdown(sessionidt s, char *reason, int result, int error); +void filter_session(sessionidt s, int filter_in, int filter_out); void send_garp(in_addr_t ip); void tunnelsend(uint8_t *buf, uint16_t l, tunnelidt t); void sendipcp(tunnelidt t, sessionidt s); void processudp(uint8_t *buf, int len, struct sockaddr_in *addr); void snoop_send_packet(char *packet, uint16_t size, in_addr_t destination, uint16_t port); +int find_filter(char const *name, size_t len); int ip_filter(uint8_t *buf, int len, uint8_t filter); int cmd_show_ipcache(struct cli_def *cli, char *command, char **argv, int argc); int cmd_show_hist_idle(struct cli_def *cli, char *command, char **argv, int argc); @@ -606,7 +675,7 @@ void host_unreachable(in_addr_t destination, uint16_t id, in_addr_t source, char extern tunnelt *tunnel; extern sessiont *session; -extern sessioncountt *sess_count; +extern sessionlocalt *sess_local; extern ippoolt *ip_address_pool; #define sessionfree (session[0].next) @@ -615,12 +684,12 @@ if (count++ < max) { \ void *array[20]; \ char **strings; \ int size, i; \ - LOG(0, 0, t, "Backtrace follows"); \ + LOG(0, 0, t, "Backtrace follows:\n"); \ size = backtrace(array, 10); \ strings = backtrace_symbols(array, size); \ if (strings) for (i = 0; i < size; i++) \ { \ - LOG(0, 0, t, "%s\n", strings[i]); \ + LOG(0, 0, t, " %s\n", strings[i]); \ } \ free(strings); \ } @@ -629,12 +698,27 @@ if (count++ < max) { \ extern configt *config; extern time_t basetime; // Time when this process started. extern time_t time_now; // Seconds since EPOCH. +extern char main_quit; extern uint32_t last_id; extern struct Tstats *_statistics; extern in_addr_t my_address; extern int tun_write(uint8_t *data, int size); extern int clifd; - +extern int epollfd; + +struct event_data { + enum { + FD_TYPE_CLI, + FD_TYPE_CLUSTER, + FD_TYPE_TUN, + FD_TYPE_UDP, + FD_TYPE_CONTROL, + FD_TYPE_DAE, + FD_TYPE_RADIUS, + FD_TYPE_BGP, + } type; + int index; // for RADIUS, BGP +}; #define TIME (config->current_time)