summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--README64
-rw-r--r--accel-pppd/CMakeLists.txt8
-rw-r--r--accel-pppd/accel-ppp.conf23
-rw-r--r--accel-pppd/accel-ppp.conf.555
-rw-r--r--accel-pppd/auth/auth_chap_md5.c44
-rw-r--r--accel-pppd/auth/auth_mschap_v1.c100
-rw-r--r--accel-pppd/auth/auth_mschap_v2.c143
-rw-r--r--accel-pppd/auth/auth_pap.c24
-rw-r--r--accel-pppd/cli/cli.c4
-rw-r--r--accel-pppd/cli/show_sessions.c37
-rw-r--r--accel-pppd/cli/std_cmd.c10
-rw-r--r--accel-pppd/cli/tcp.c3
-rw-r--r--accel-pppd/cli/telnet.c3
-rw-r--r--accel-pppd/ctrl/l2tp/dict.c3
-rw-r--r--accel-pppd/ctrl/l2tp/l2tp.c17
-rw-r--r--accel-pppd/ctrl/l2tp/netlink.c3
-rw-r--r--accel-pppd/ctrl/l2tp/packet.c3
-rw-r--r--accel-pppd/ctrl/pppoe/cli.c3
-rw-r--r--accel-pppd/ctrl/pppoe/mac_filter.c3
-rw-r--r--accel-pppd/ctrl/pppoe/pppoe.c93
-rw-r--r--accel-pppd/ctrl/pptp/pptp.c14
-rw-r--r--accel-pppd/extra/CMakeLists.txt4
-rw-r--r--accel-pppd/extra/chap-secrets.c9
-rw-r--r--accel-pppd/extra/ippool.c4
-rw-r--r--accel-pppd/extra/net-snmp/ACCEL-PPP-MIB.txt326
-rw-r--r--accel-pppd/extra/net-snmp/CMakeLists.txt23
-rw-r--r--accel-pppd/extra/net-snmp/agent.c150
-rw-r--r--accel-pppd/extra/net-snmp/sessionTable.c201
-rw-r--r--accel-pppd/extra/net-snmp/sessionTable.h195
-rw-r--r--accel-pppd/extra/net-snmp/sessionTable_data_access.c304
-rw-r--r--accel-pppd/extra/net-snmp/sessionTable_data_access.h76
-rw-r--r--accel-pppd/extra/net-snmp/sessionTable_data_get.c696
-rw-r--r--accel-pppd/extra/net-snmp/sessionTable_data_get.h66
-rw-r--r--accel-pppd/extra/net-snmp/sessionTable_data_set.c24
-rw-r--r--accel-pppd/extra/net-snmp/sessionTable_data_set.h27
-rw-r--r--accel-pppd/extra/net-snmp/sessionTable_enums.h85
-rw-r--r--accel-pppd/extra/net-snmp/sessionTable_interface.c946
-rw-r--r--accel-pppd/extra/net-snmp/sessionTable_interface.h84
-rw-r--r--accel-pppd/extra/net-snmp/sessionTable_oids.h46
-rw-r--r--accel-pppd/extra/net-snmp/shutdown.c88
-rw-r--r--accel-pppd/extra/net-snmp/shutdown.h12
-rw-r--r--accel-pppd/extra/net-snmp/statCore.c147
-rw-r--r--accel-pppd/extra/net-snmp/statCore.h14
-rw-r--r--accel-pppd/extra/net-snmp/statL2TP.c94
-rw-r--r--accel-pppd/extra/net-snmp/statL2TP.h11
-rw-r--r--accel-pppd/extra/net-snmp/statPPP.c93
-rw-r--r--accel-pppd/extra/net-snmp/statPPP.h11
-rw-r--r--accel-pppd/extra/net-snmp/statPPPOE.c93
-rw-r--r--accel-pppd/extra/net-snmp/statPPPOE.h11
-rw-r--r--accel-pppd/extra/net-snmp/statPPTP.c92
-rw-r--r--accel-pppd/extra/net-snmp/statPPTP.h11
-rw-r--r--accel-pppd/extra/net-snmp/terminate.c379
-rw-r--r--accel-pppd/extra/net-snmp/terminate.h15
-rw-r--r--accel-pppd/extra/pppd_compat.c4
-rw-r--r--accel-pppd/extra/shaper_tbf.c57
-rw-r--r--accel-pppd/extra/sigchld.c4
-rw-r--r--accel-pppd/include/events.h1
-rw-r--r--accel-pppd/iprange.c3
-rw-r--r--accel-pppd/log.c12
-rw-r--r--accel-pppd/log.h8
-rw-r--r--accel-pppd/logs/log_file.c277
-rw-r--r--accel-pppd/logs/log_pgsql.c4
-rw-r--r--accel-pppd/logs/log_tcp.c3
-rw-r--r--accel-pppd/main.c113
-rw-r--r--accel-pppd/ppp/ccp_mppe.c94
-rw-r--r--accel-pppd/ppp/ipcp_opt_dns.c4
-rw-r--r--accel-pppd/ppp/ipcp_opt_ipaddr.c53
-rw-r--r--accel-pppd/ppp/lcp_opt_accomp.c3
-rw-r--r--accel-pppd/ppp/lcp_opt_magic.c4
-rw-r--r--accel-pppd/ppp/lcp_opt_mru.c3
-rw-r--r--accel-pppd/ppp/lcp_opt_pcomp.c3
-rw-r--r--accel-pppd/ppp/ppp.c19
-rw-r--r--accel-pppd/ppp/ppp.h5
-rw-r--r--accel-pppd/ppp/ppp_auth.c59
-rw-r--r--accel-pppd/ppp/ppp_auth.h4
-rw-r--r--accel-pppd/ppp/ppp_ccp.c172
-rw-r--r--accel-pppd/ppp/ppp_ccp.h7
-rw-r--r--accel-pppd/ppp/ppp_fsm.c18
-rw-r--r--accel-pppd/ppp/ppp_fsm.h1
-rw-r--r--accel-pppd/ppp/ppp_ipcp.c82
-rw-r--r--accel-pppd/ppp/ppp_ipcp.h2
-rw-r--r--accel-pppd/ppp/ppp_lcp.c58
-rw-r--r--accel-pppd/radius/CMakeLists.txt1
-rw-r--r--accel-pppd/radius/acct.c235
-rw-r--r--accel-pppd/radius/auth.c117
-rw-r--r--accel-pppd/radius/dm_coa.c4
-rw-r--r--accel-pppd/radius/packet.c4
-rw-r--r--accel-pppd/radius/radius.c56
-rw-r--r--accel-pppd/radius/radius_p.h40
-rw-r--r--accel-pppd/radius/req.c27
-rw-r--r--accel-pppd/radius/serv.c331
-rw-r--r--accel-pppd/radius/stat_accm.c14
-rw-r--r--accel-pppd/triton/triton.c67
-rw-r--r--accel-pppd/triton/triton.h4
-rw-r--r--accel-pppd/triton/triton_p.h8
-rw-r--r--cmake/cpack.cmake12
-rw-r--r--cmake/debian/debian.cmake3
-rwxr-xr-xcmake/debian/postinst4
-rw-r--r--contrib/gentoo/net-dialup/accel-ppp/accel-ppp-1.3.5.ebuild (renamed from contrib/gentoo/net-dialup/accel-ppp/accel-ppp-1.3.3.ebuild)0
100 files changed, 6262 insertions, 738 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f61780a..40f2f1a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.6)
cmake_policy(SET CMP0005 NEW)
cmake_policy(SET CMP0003 OLD)
-PROJECT (accel-pppd C)
+PROJECT (accel-ppp C)
include(cmake/cpack.cmake)
diff --git a/README b/README
index 107e773..e8aace7 100644
--- a/README
+++ b/README
@@ -1,10 +1,8 @@
Overview
--------
-The ACCEL-PPTP v1.0 is completly new implementation of PPTP/PPPoE/L2TP which was written from null.
+The ACCEL-PPP v1.0 is completly new implementation of PPTP/PPPoE/L2TP which was written from scratch.
Userspace daemon has its own PPP implementation, so it does not uses pppd and one process (multi-threaded) manages all connections.
-ACCEL-PPTP uses kernel module to increase performance and decrease system usage.
-It is not fully tested yet so not recomended to use in production.
-Also v1.0 is oriented for servers and does not containes client part, if you need client please use v0.8.x
+ACCEL-PPP uses only kernel-mode implementations of pptp/l2tp/pppoe.
Features
@@ -12,7 +10,7 @@ Features
1. Modular architecture
2. High-performance multi-threaded I/O core
3. Supported PPTP
-4. Supported PPPoE
+4. Supported PPPoE (including TR-101 extension)
5. Supported L2TPv2 (without IPsec)
5. Radius authentication/accounting
6. Radius DM/CoA extention
@@ -25,6 +23,7 @@ Features
13. Supported pppd compatible ip-up/ip-down scripts
14. Builtin tbf shaper manager
15. Command line interface via telnet
+16. SNMP support (master or subagent via AgentX)
Requirment
@@ -33,16 +32,19 @@ Requirment
2. kernel-2.6.25 or later
4. cmake-2.6 or later
5. libnl-2.0 or probably later (required for builtin shaper)
+6. libcrypto-0.9.8 or probably later (openssl-0.9.8)
+7. libpcre
+8. net-snmp-5.x
Compilation and instalation
-----------
Make sure you have configured kernel headers in /usr/src/linux,
or specify other location via KDIR.
-1. cd /path/to/accel-pptp-1.3.1
+1. cd /path/to/accel-ppp-1.3.5
2. mkdir build
3. cd build
-4. cmake [-DBUILD_DRIVER=FALSE] [-DKDIR=/usr/src/linux] [-DCMAKE_INSTALL_PREFIX=/usr/local] [-DCMAKE_BUILD_TYPE=Release] [-DLOG_PGSQL=FALSE] [-DSHAPER=FALSE] [-DRADIUS=TRUE] ..
+4. cmake [-DBUILD_DRIVER=FALSE] [-DKDIR=/usr/src/linux] [-DCMAKE_INSTALL_PREFIX=/usr/local] [-DCMAKE_BUILD_TYPE=Release] [-DLOG_PGSQL=FALSE] [-DSHAPER=FALSE] [-DRADIUS=TRUE] [-DNETSNMP=FALSE] ..
Please note that the double dot record in the end of the command is essential. You'll probably get error or misconfigured sources if you miss it.
BUILD_DRIVER, KDIR, CMAKE_INSTALL_PREFIX, CMAKE_BUILD_TYPE, LOG_PGSQL, SHAPER, RADIUS are optional,
But while pptp is not present in mainline kernel you probably need BUILD_DRIVER.
@@ -59,13 +61,14 @@ or specify other location via KDIR.
Configuration
-------------
-read man accel-pptp.conf
+read man accel-ppp.conf
+
Built-in shaper
--------------
-accel-pptp supports tbf based shaper manager.
+accel-ppp supports tbf based shaper manager.
To enable it uncomment shaper_tbf in [modules] section.
-It accepts radius attrbutes in various formats: rate, down-rate/up-rate and cisco-like. Values have to be in kilobits except cisco-like.
+It accepts radius attributes in various formats: rate, down-rate/up-rate and cisco-like. Values have to be in kilobits except cisco-like.
For example:
Filter-Id=1000 (means 1000Kbit both up-stream and down-stream rate)
Filter-Id=2000/3000 (means 2000Kbit down-stream rate and 3000Kbit up-stream rate)
@@ -78,7 +81,7 @@ To specify different attributes for down-stream and up-stream rates use 'attr-do
attr-down=PPPD-Downstream-Speed
attr-up=PPPD-Upstream-Speed
-If you want to use cisco-like format configure accel-pptp as following:
+If you want to use cisco-like format configure accel-ppp as following:
[tbf]
vendor=Cisco
attr=Cisco-AVPair
@@ -86,10 +89,11 @@ and send two attributes:
Cisco-AVPair=lcp:interface-config#1=rate-limit input 2000000 8000 8000 conform-action transmit exceed-action drop (which means 2000Kbit up-stream rate and 8Kb burst)
Cisco-AVPair=lcp:interface-config#1=rate-limit output 2000000 8000 8000 conform-action transmit exceed-action drop (which means 2000Kbit down-stream rate and 8Kb burst)
+
Advanced shaper using
---------------------
1. Burst configuration.
-If you not using cisco-format then burst calculates from rate and specified burst factors.
+If you not using cisco-like format then burst calculates from rate and specified burst factors.
To specify burst factors use 'down-burst-factor' and 'up-burst-factor' options, for example:
[tbf]
down-burst-factor=1.0
@@ -114,15 +118,45 @@ You have to pass multiple Filter-Id attributes to utilize this functionality.
Or cisco-like:
Cisco-AVPair=lcp:interface-config#1=rate-limit output access-group 1 1000000 8000 8000 conform-action transmit exceed-action drop
Cisco-AVPair=lcp:interface-config#1=rate-limit input access-group 1 1000000 8000 8000 conform-action transmit exceed-action drop
-ans so on...
+and so on...
+
+3. chap-secrets.
+If you use chap-secrets instead of radius then there is way to utilize built-in shaper too.
+The optional fifth column in chap-secrets file is used to pass rate information to shaper.
+Its format is same as for radius attributes, except you cann't utilize time ranges functionality.
+
+
+SNMP
+----
+SNMP is implemented using net-snmp libraries. By default accel-ppp starts in subagent mode,
+so make sure that net-snmp configured with subagent control turned on (read net-snmp's README.agentx for more details).
+Also you can start accel-ppp as master agent using following configuration:
+[snmp]
+master=1
+
+Usage:
+Place accel-pppd/extra/net-snmp/ACCEL-PPP-MIB.txt to your mibs directory.
+Also you can find used numerical oids in this file.
+1. Requesting statistics:
+snmpwalk -m +ACCEL-PPP-MIB -v 2c -c local 127.0.0.1 ACCEL-PPP-MIB::accelPPPStat
+2. Requesting sessions:
+snmptable -m +ACCEL-PPP-MIB -v 2c -c local 127.0.0.1 ACCEL-PPP-MIB::sessionsTable
+3. Terminate session by session identifier (Acct-Session-ID):
+snmpset -m +ACCEL-PPP-MIB -v 2c -c local 127.0.0.1 ACCEL-PPP-MIB::termBySID.0 = 0000000000000001
+4. Terminate session by interface name:
+snmpset -m +ACCEL-PPP-MIB -v 2c -c local 127.0.0.1 ACCEL-PPP-MIB::termByIfName = ppp2
+5. Terminaten session by IP address (Framed-IP-Address):
+snmpset -m +ACCEL-PPP-MIB -v 2c -c local 127.0.0.1 ACCEL-PPP-MIB::termByIP = 192.168.10.10
+6. Terminate session by username:
+snmpset -m +ACCEL-PPP-MIB -v 2c -c local 127.0.0.1 ACCEL-PPP-MIB::termByUsername = user1
Warning !!!
-----------
1. The pptp driver conflicts with ip_gre driver (in kernel), so make sure that ip_gre is not built-in or loaded at run time
(don't matter if you have 2.6.37 or later kernel).
-2. Never mix connections of accel-pptp and original pptpd, before starting accel-pptp make sure that no connections
- of original pptpd exists.
+2. Don't mix connections of accel-ppp and poptop's pptpd, before starting accel-ppp make sure that no connections
+ of pptpd exists.
Thanks
diff --git a/accel-pppd/CMakeLists.txt b/accel-pppd/CMakeLists.txt
index aaafbd9..45a070f 100644
--- a/accel-pppd/CMakeLists.txt
+++ b/accel-pppd/CMakeLists.txt
@@ -14,7 +14,7 @@ ENDIF (NOT HAVE_SSL)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fvisibility=hidden -fno-strict-aliasing -D_GNU_SOURCE -DPTHREAD_SPINLOCK -fPIC")
-IF (EXISTS ${CMAKE_HOME_DIRECTORY}/.git)
+IF (EXISTS ${CMAKE_HOME_DIRECTORY}/.git AND NOT DEFINED IGNORE_GIT)
EXECUTE_PROCESS(
COMMAND git log
COMMAND head -n1
@@ -23,9 +23,9 @@ IF (EXISTS ${CMAKE_HOME_DIRECTORY}/.git)
OUTPUT_VARIABLE ACCEL_PPP_VERSION
)
STRING(STRIP ${ACCEL_PPP_VERSION} ACCEL_PPP_VERSION)
-ELSE (EXISTS ${CMAKE_HOME_DIRECTORY}/.git)
- SET (ACCEL_PPP_VERSION 1.3.4)
-ENDIF (EXISTS ${CMAKE_HOME_DIRECTORY}/.git)
+ELSE (EXISTS ${CMAKE_HOME_DIRECTORY}/.git AND NOT DEFINED IGNORE_GIT)
+ SET (ACCEL_PPP_VERSION 1.3.7)
+ENDIF (EXISTS ${CMAKE_HOME_DIRECTORY}/.git AND NOT DEFINED IGNORE_GIT)
ADD_DEFINITIONS(-DACCEL_PPP_VERSION="${ACCEL_PPP_VERSION}")
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf
index 31ad4e0..3193242 100644
--- a/accel-pppd/accel-ppp.conf
+++ b/accel-pppd/accel-ppp.conf
@@ -29,13 +29,15 @@ mru=1400
#ccp=0
#sid-case=upper
#check-ip=0
+#single-session=replace
+#mppe=require
[lcp]
echo-interval=30
echo-failure=3
[pptp]
-echo-interval=30
+#echo-interval=30
verbose=1
[pppoe]
@@ -45,6 +47,7 @@ interface=eth0
#pado-delay=0
#pado-delay=0,100:100,200:200,-1:500
#ifname-in-sid=called-sid
+#tr101=1
verbose=1
[l2tp]
@@ -65,14 +68,15 @@ verbose=1
nas-identifier=accel-ppp
nas-ip-address=127.0.0.1
gw-ip-address=192.168.100.1
-auth-server=127.0.0.1:1812,testing123
-acct-server=127.0.0.1:1813,testing123
+#auth-server=127.0.0.1:1812,testing123 (obsolete)
+#acct-server=127.0.0.1:1813,testing123 (obsolete)
+server=127.0.0.1,testing123
dae-server=127.0.0.1:3799,testing123
-#dm_coa_secret=testing123 (deprecated)
verbose=1
#timeout=3
#max-try=3
#acct-timeout=120
+#acct-delay-time=0
[client-ip-range]
10.0.0.0/8
@@ -88,6 +92,7 @@ gw-ip-address=192.168.0.1
[log]
log-file=/var/log/accel-ppp/accel-ppp.log
log-emerg=/var/log/accel-ppp/emerg.log
+log-fail-file=/var/log/accel-ppp/auth-fail.log
#log-debug=/dev/stdout
#log-tcp=127.0.0.1:3000
copy=1
@@ -110,6 +115,10 @@ ip-change=/etc/ppp/ip-change
radattr-prefix=/var/run/radattr
verbose=1
+[chap-secrets]
+gw-ip-address=192.168.100.1
+#chap-secrets=/etc/ppp/chap-secrets
+
[tbf]
#attr=Filter-Id
#down-burst-factor=0.1
@@ -119,4 +128,8 @@ verbose=1
[cli]
telnet=127.0.0.1:2000
tcp=127.0.0.1:2001
-#passwd=123
+#password=123
+
+[snmp]
+master=0
+agent-name=accel-ppp
diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5
index d9aaadb..aee1354 100644
--- a/accel-pppd/accel-ppp.conf.5
+++ b/accel-pppd/accel-ppp.conf.5
@@ -104,6 +104,32 @@ Specifies in which case generate session identifier (default lower).
.BI "check-ip=" 0|1
Specifies whether accel-ppp should check if IP already assigned to other ppp interface (default 0).
.TP
+.BI "single-session=" replace|deny
+Specifies whether accel-ppp should control sessions count.
+.br
+If this option is absent session count control is turned off.
+If this option is
+.B replace
+then accel-ppp will terminate first session when second is authorized.
+If this option is
+.B deny
+then accel-ppp will deny second session authorization.
+.TP
+.BI "mppe=" require|prefere|deny
+Specifies mppe negotioation preference.
+.br
+.B require
+- ask client for mppe, if it rejects drop connection
+.br
+.B prefere
+- ask client for mppe, if it rejects don't fail.
+.br
+.B deny
+- deny mppe.
+.br
+Default behavior - don't ask client for mppe, but allow it if client wants.
+Please note that RADIUS may override this option by MS-MPPE-Encryption-Policy attribute.
+.TP
.SH [lcp]
.br
PPP LCP module configuration
@@ -190,6 +216,10 @@ If this option is given and
.B n
is greater of zero then pppoe module will produce verbose logging.
.TP
+.TP
+.BI "tr101=" 0|1
+Specifies whether to handle TR101 tags.
+.TP
.SH [l2tp]
.br
Configuration of L2TP module.
@@ -232,10 +262,15 @@ Also DM/CoA server will bind to that address.
Specifies address to use as local address of ppp interfaces if Framed-IP-Address received from RADIUS server.
.TP
.BI "auth-server=" x.x.x.x:port,secret
-Specifies IP address, port and secret of authentication RADIUS server.
+Specifies IP address, port and secret of authentication RADIUS server. (obsolete)
.TP
.BI "acct-server=" x.x.x.x:port,secret
-Specifies IP address, port and secret of accounting RADIUS server.
+Specifies IP address, port and secret of accounting RADIUS server. (obsolete)
+.TP
+.BI "server=" address,secret[,auth-port[,acct-port]]
+Specifies IP address, ports and secret of RADIUS server.
+If you want to specify only authentication or accounting server then set auth-port/acct-port to zero.
+You may specify multiple radius servers.
.TP
.BI "dae-server=" x.x.x.x:port,secret
Specifies IP address, port to bind and secret for Dynamic Authorization Extension server (DM/CoA).
@@ -265,6 +300,9 @@ Specifies number of tries to send Access-Request/Accounting-Request queries.
.BI "acct-timeout=" n
Specifies timeout of accounting interim update.
.TP
+.BI "acct-delay-time=" 0|1
+Specifies whether radius client should include Acct-Delay-Time attribute to accounting requests (default 0).
+.TP
.SH [log]
.br
Configuration of log and log_file modules.
@@ -275,6 +313,9 @@ Path to file to write general log.
.BI "log-emerg=" file
Path to file to write emergency messages.
.TP
+.BI "log-fail-file=" file
+Path to file to write authentication failed session log.
+.TP
.BI "log-tcp=" x.x.x.x:port
Send logs to specified host.
.TP
@@ -357,6 +398,16 @@ Prefix of radattr files (for example /var/run/radattr, resulting files will be /
.BI "verbose=" n
If specified and greated then zero pppd_module will produce verbose logging.
.TP
+.SH [chap-secrets]
+.br
+Configuration of chap-secrets module.
+.TP
+.BI "gw-ip-address=" x.x.x.x
+Specifies address to use as local address of ppp interfaces if chap-secrets is used for IP address assignment.
+.TP
+.BI "chap-secrets=" file
+Specifies alternate chap-secrets file location (default is /etc/ppp/chap-secrets).
+.TP
.SH [ip-pool]
.br
Configuration of ippool module.
diff --git a/accel-pppd/auth/auth_chap_md5.c b/accel-pppd/auth/auth_chap_md5.c
index 2ea60ba..2307f14 100644
--- a/accel-pppd/auth/auth_chap_md5.c
+++ b/accel-pppd/auth/auth_chap_md5.c
@@ -289,9 +289,14 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
name = _strndup(msg->name,ntohs(msg->hdr.len) - sizeof(*msg) + 2);
if (conf_any_login) {
+ if (ppp_auth_successed(ad->ppp, name)) {
+ chap_send_failure(ad);
+ ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
+ _free(name);
+ return;
+ }
chap_send_success(ad);
ad->started = 1;
- ppp_auth_successed(ad->ppp, name);
return;
}
@@ -325,12 +330,17 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
ppp_auth_failed(ad->ppp, name);
_free(name);
} else {
- chap_send_success(ad);
if (!ad->started) {
- ad->started = 1;
- if (conf_interval)
- triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
- ppp_auth_successed(ad->ppp, name);
+ if (ppp_auth_successed(ad->ppp, name)) {
+ chap_send_failure(ad);
+ ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
+ _free(name);
+ } else {
+ chap_send_success(ad);
+ ad->started = 1;
+ if (conf_interval)
+ triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
+ }
} else
_free(name);
}
@@ -343,14 +353,21 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
ppp_auth_failed(ad->ppp, name);
_free(name);
} else {
- chap_send_success(ad);
if (!ad->started) {
- ad->started = 1;
- if (conf_interval)
- triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
- ppp_auth_successed(ad->ppp, name);
- } else
+ if (ppp_auth_successed(ad->ppp, name)) {
+ chap_send_failure(ad);
+ ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
+ _free(name);
+ } else {
+ chap_send_success(ad);
+ ad->started = 1;
+ if (conf_interval)
+ triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
+ }
+ } else {
+ chap_send_success(ad);
_free(name);
+ }
}
}
@@ -397,7 +414,7 @@ static void chap_recv(struct ppp_handler_t *h)
log_ppp_warn("chap-md5: unknown code received %x\n", hdr->code);
}
-static void __init auth_chap_md5_init()
+static void auth_chap_md5_init()
{
char *opt;
@@ -428,3 +445,4 @@ static void __init auth_chap_md5_init()
log_emerg("chap-md5: failed to register handler\n");
}
+DEFINE_INIT(6, auth_chap_md5_init);
diff --git a/accel-pppd/auth/auth_mschap_v1.c b/accel-pppd/auth/auth_mschap_v1.c
index 4308300..10d5fe8 100644
--- a/accel-pppd/auth/auth_mschap_v1.c
+++ b/accel-pppd/auth/auth_mschap_v1.c
@@ -31,15 +31,15 @@
#define VALUE_SIZE 8
#define RESPONSE_VALUE_SIZE (24+24+1)
-#define MSG_FAILURE "E=691 R=0"
-#define MSG_SUCCESS "Authentication successed"
-
#define HDR_LEN (sizeof(struct chap_hdr_t)-2)
static int conf_timeout = 5;
static int conf_interval = 0;
static int conf_max_failure = 3;
static int conf_any_login = 0;
+static char *conf_msg_failure = "E=691 R=0";
+static char *conf_msg_success = "Authentication successed";
+;
static int urandom_fd;
@@ -69,19 +69,6 @@ struct chap_response_t
char name[0];
} __attribute__((packed));
-struct chap_failure_t
-{
- struct chap_hdr_t hdr;
- char message[sizeof(MSG_FAILURE)];
-} __attribute__((packed));
-
-struct chap_success_t
-{
- struct chap_hdr_t hdr;
- char message[sizeof(MSG_SUCCESS)];
-} __attribute__((packed));
-
-
struct chap_auth_data_t
{
struct auth_data_t auth;
@@ -210,36 +197,38 @@ static int lcp_recv_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *
return LCP_OPT_NAK;
}
-static void chap_send_failure(struct chap_auth_data_t *ad)
+static void chap_send_failure(struct chap_auth_data_t *ad, char *mschap_error)
{
- struct chap_failure_t msg = {
- .hdr.proto = htons(PPP_CHAP),
- .hdr.code = CHAP_FAILURE,
- .hdr.id = ad->id,
- .hdr.len = htons(sizeof(msg)-1-2),
- .message = MSG_FAILURE,
- };
-
+ struct chap_hdr_t *hdr = _malloc(sizeof(*hdr) + strlen(mschap_error) + 1);
+ hdr->proto = htons(PPP_CHAP);
+ hdr->code = CHAP_FAILURE;
+ hdr->id = ad->id;
+ hdr->len = htons(HDR_LEN + strlen(mschap_error));
+ strcpy((char *)(hdr + 1), mschap_error);
+
if (conf_ppp_verbose)
- log_ppp_info2("send [MSCHAP-v1 Failure id=%x \"%s\"]\n", msg.hdr.id, MSG_FAILURE);
+ log_ppp_info2("send [MSCHAP-v1 Failure id=%x \"%s\"]\n", hdr->id, mschap_error);
- ppp_chan_send(ad->ppp,&msg,ntohs(msg.hdr.len)+2);
+ ppp_chan_send(ad->ppp, hdr, ntohs(hdr->len) + 2);
+
+ _free(hdr);
}
static void chap_send_success(struct chap_auth_data_t *ad)
{
- struct chap_success_t msg = {
- .hdr.proto = htons(PPP_CHAP),
- .hdr.code = CHAP_SUCCESS,
- .hdr.id = ad->id,
- .hdr.len = htons(sizeof(msg)-1-2),
- .message = MSG_SUCCESS,
- };
+ struct chap_hdr_t *hdr = _malloc(sizeof(*hdr) + strlen(conf_msg_success) + 1);
+ hdr->proto = htons(PPP_CHAP);
+ hdr->code = CHAP_SUCCESS;
+ hdr->id = ad->id;
+ hdr->len = htons(HDR_LEN + strlen(conf_msg_success));
+ strcpy((char *)(hdr + 1), conf_msg_success);
if (conf_ppp_verbose)
- log_ppp_info2("send [MSCHAP-v1 Success id=%x \"%s\"]\n", msg.hdr.id, MSG_SUCCESS);
+ log_ppp_info2("send [MSCHAP-v1 Success id=%x \"%s\"]\n", hdr->id, conf_msg_success);
- ppp_chan_send(ad->ppp, &msg, ntohs(msg.hdr.len) + 2);
+ ppp_chan_send(ad->ppp, hdr, ntohs(hdr->len) + 2);
+
+ _free(hdr);
}
static void chap_send_challenge(struct chap_auth_data_t *ad)
@@ -271,6 +260,7 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
{
struct chap_response_t *msg = (struct chap_response_t*)hdr;
char *name;
+ char *mschap_error = conf_msg_failure;
int r;
if (ad->timeout.tpd)
@@ -312,33 +302,45 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
}
if (conf_any_login) {
+ if (ppp_auth_successed(ad->ppp, name)) {
+ chap_send_failure(ad, mschap_error);
+ ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
+ _free(name);
+ return;
+ }
chap_send_success(ad);
ad->started = 1;
- ppp_auth_successed(ad->ppp, name);
return;
}
- r = pwdb_check(ad->ppp, name, PPP_CHAP, MSCHAP_V1, ad->id, ad->val, VALUE_SIZE, msg->lm_hash, msg->nt_hash, msg->flags);
+ r = pwdb_check(ad->ppp, name, PPP_CHAP, MSCHAP_V1, ad->id, ad->val, VALUE_SIZE, msg->lm_hash, msg->nt_hash, msg->flags, &mschap_error);
if (r == PWDB_NO_IMPL)
if (chap_check_response(ad, msg, name))
r = PWDB_DENIED;
if (r == PWDB_DENIED) {
- chap_send_failure(ad);
+ chap_send_failure(ad, mschap_error);
if (ad->started)
ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
else
ppp_auth_failed(ad->ppp, name);
_free(name);
} else {
- chap_send_success(ad);
if (!ad->started) {
- ad->started = 1;
- if (conf_interval)
- triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
- ppp_auth_successed(ad->ppp, name);
- } else
+ if (ppp_auth_successed(ad->ppp, name)) {
+ chap_send_failure(ad, mschap_error);
+ ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
+ _free(name);
+ } else {
+ chap_send_success(ad);
+ ad->started = 1;
+ if (conf_interval)
+ triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
+ }
+ } else {
+ chap_send_success(ad);
_free(name);
+ }
}
}
@@ -384,7 +386,7 @@ static int chap_check_response(struct chap_auth_data_t *ad, struct chap_response
if (!passwd) {
if (conf_ppp_verbose)
log_ppp_warn("mschap-v1: user not found\n");
- chap_send_failure(ad);
+ chap_send_failure(ad, conf_msg_failure);
return PWDB_DENIED;
}
@@ -424,8 +426,7 @@ static void set_mppe_keys(struct chap_auth_data_t *ad, uint8_t *z_hash)
struct ev_mppe_keys_t ev_mppe = {
.ppp = ad->ppp,
- .type = 1 << 2,
- .policy = 1,
+ .policy = -1,
.recv_key = digest,
.send_key = digest,
};
@@ -482,7 +483,7 @@ static void chap_recv(struct ppp_handler_t *h)
log_ppp_warn("mschap-v1: unknown code received %x\n", hdr->code);
}
-static void __init auth_mschap_v1_init()
+static void auth_mschap_v1_init()
{
char *opt;
@@ -511,3 +512,4 @@ static void __init auth_mschap_v1_init()
log_emerg("mschap-v1: failed to register handler\n");
}
+DEFINE_INIT(5, auth_mschap_v1_init);
diff --git a/accel-pppd/auth/auth_mschap_v2.c b/accel-pppd/auth/auth_mschap_v2.c
index 644f70b..ebcffb7 100644
--- a/accel-pppd/auth/auth_mschap_v2.c
+++ b/accel-pppd/auth/auth_mschap_v2.c
@@ -31,14 +31,14 @@
#define VALUE_SIZE 16
#define RESPONSE_VALUE_SIZE (16+8+24+1)
-#define MSG_FAILURE "E=691 R=0 C=cccccccccccccccccccccccccccccccc V=3 M=Authentication failure"
-#define MSG_SUCCESS "S=cccccccccccccccccccccccccccccccccccccccc M=Authentication successed"
-
#define HDR_LEN (sizeof(struct chap_hdr_t)-2)
static int conf_timeout = 5;
static int conf_interval = 0;
static int conf_max_failure = 3;
+static char *conf_msg_failure = "E=691 R=0 V=3";
+static char *conf_msg_failure2 = "Authentication failure";
+static char *conf_msg_success = "Authentication successed";
static int urandom_fd;
@@ -69,19 +69,6 @@ struct chap_response_t
char name[0];
} __attribute__((packed));
-struct chap_failure_t
-{
- struct chap_hdr_t hdr;
- char message[sizeof(MSG_FAILURE)];
-} __attribute__((packed));
-
-struct chap_success_t
-{
- struct chap_hdr_t hdr;
- char message[sizeof(MSG_SUCCESS)];
-} __attribute__((packed));
-
-
struct chap_auth_data_t
{
struct auth_data_t auth;
@@ -211,20 +198,40 @@ static int lcp_recv_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *
return LCP_OPT_NAK;
}
-static void chap_send_failure(struct chap_auth_data_t *ad)
+static void chap_send_failure(struct chap_auth_data_t *ad, char *mschap_error, char *reply_msg)
{
- struct chap_failure_t msg = {
- .hdr.proto = htons(PPP_CHAP),
- .hdr.code = CHAP_FAILURE,
- .hdr.id = ad->id,
- .hdr.len = htons(sizeof(msg) - 1 - 2),
- .message = MSG_FAILURE,
- };
+ struct chap_hdr_t *hdr = _malloc(sizeof(*hdr) + strlen(mschap_error) + strlen(reply_msg) + 4);
+ hdr->proto = htons(PPP_CHAP);
+ hdr->code = CHAP_FAILURE;
+ hdr->id = ad->id;
+ hdr->len = htons(HDR_LEN + strlen(mschap_error) + strlen(reply_msg) + 3);
+
+ sprintf((char *)(hdr + 1), "%s M=%s", mschap_error, reply_msg);
if (conf_ppp_verbose)
- log_ppp_info2("send [MSCHAP-v2 Failure id=%x \"%s\"]\n", msg.hdr.id, MSG_FAILURE);
+ log_ppp_info2("send [MSCHAP-v2 Failure id=%x \"%s\"]\n", hdr->id, hdr + 1);
- ppp_chan_send(ad->ppp, &msg, ntohs(msg.hdr.len) + 2);
+ ppp_chan_send(ad->ppp, hdr, ntohs(hdr->len) + 2);
+
+ _free(hdr);
+}
+
+static void chap_send_success(struct chap_auth_data_t *ad, struct chap_response_t *res_msg, const char *authenticator)
+{
+ struct chap_hdr_t *hdr = _malloc(sizeof(*hdr) + strlen(conf_msg_success) + 1 + 45);
+ hdr->proto = htons(PPP_CHAP),
+ hdr->code = CHAP_SUCCESS,
+ hdr->id = ad->id,
+ hdr->len = htons(HDR_LEN + strlen(conf_msg_success) + 45),
+
+ sprintf((char *)(hdr + 1), "S=%s M=%s", authenticator, conf_msg_success);
+
+ if (conf_ppp_verbose)
+ log_ppp_info2("send [MSCHAP-v2 Success id=%x \"%s\"]\n", hdr->id, hdr + 1);
+
+ ppp_chan_send(ad->ppp, hdr, ntohs(hdr->len) + 2);
+
+ _free(hdr);
}
static int generate_response(struct chap_auth_data_t *ad, struct chap_response_t *msg, const char *name, char *authenticator)
@@ -297,24 +304,6 @@ static int generate_response(struct chap_auth_data_t *ad, struct chap_response_t
return 0;
}
-static void chap_send_success(struct chap_auth_data_t *ad, struct chap_response_t *res_msg, const char *authenticator)
-{
- struct chap_success_t msg = {
- .hdr.proto = htons(PPP_CHAP),
- .hdr.code = CHAP_SUCCESS,
- .hdr.id = ad->id,
- .hdr.len = htons(sizeof(msg) - 1 - 2),
- .message = MSG_SUCCESS,
- };
-
- memcpy(msg.message + 2, authenticator, 40);
-
- if (conf_ppp_verbose)
- log_ppp_info2("send [MSCHAP-v2 Success id=%x \"%s\"]\n", msg.hdr.id, msg.message);
-
- ppp_chan_send(ad->ppp, &msg, ntohs(msg.hdr.len) + 2);
-}
-
static void chap_send_challenge(struct chap_auth_data_t *ad)
{
struct chap_challenge_t msg = {
@@ -346,6 +335,10 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
char *name;
char authenticator[41];
int r;
+ char *mschap_error = conf_msg_failure;
+ char *reply_msg = conf_msg_failure2;
+
+ authenticator[40] = 0;
if (ad->timeout.tpd)
triton_timer_del(&ad->timeout);
@@ -368,7 +361,7 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
if (msg->val_size != RESPONSE_VALUE_SIZE) {
log_ppp_error("mschap-v2: incorrect value-size (%i)\n", msg->val_size);
- chap_send_failure(ad);
+ chap_send_failure(ad, mschap_error, reply_msg);
if (ad->started)
ppp_terminate(ad->ppp, TERM_USER_ERROR, 0);
else
@@ -386,9 +379,9 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
return;
}
- r = pwdb_check(ad->ppp, name, PPP_CHAP, MSCHAP_V2, ad->id, ad->val, msg->peer_challenge, msg->reserved, msg->nt_hash, msg->flags, authenticator);
+ r = pwdb_check(ad->ppp, name, PPP_CHAP, MSCHAP_V2, ad->id, ad->val, msg->peer_challenge, msg->reserved, msg->nt_hash, msg->flags, authenticator, &mschap_error, &reply_msg);
- if (r == PWDB_NO_IMPL) {
+ if (r == PWDB_NO_IMPL) {
r = chap_check_response(ad, msg, name);
if (r)
r = PWDB_DENIED;
@@ -397,21 +390,28 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
}
if (r == PWDB_DENIED) {
- chap_send_failure(ad);
+ chap_send_failure(ad, mschap_error, reply_msg);
if (ad->started)
ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
else
ppp_auth_failed(ad->ppp, name);
_free(name);
} else {
- chap_send_success(ad, msg, authenticator);
if (!ad->started) {
- ad->started = 1;
- if (conf_interval)
- triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
- ppp_auth_successed(ad->ppp, name);
- } else
+ if (ppp_auth_successed(ad->ppp, name)) {
+ chap_send_failure(ad, mschap_error, reply_msg);
+ ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
+ _free(name);
+ } else {
+ chap_send_success(ad, msg, authenticator);
+ ad->started = 1;
+ if (conf_interval)
+ triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
+ }
+ } else {
+ chap_send_success(ad, msg, authenticator);
_free(name);
+ }
}
}
@@ -459,38 +459,37 @@ static int chap_check_response(struct chap_auth_data_t *ad, struct chap_response
if (!passwd) {
if (conf_ppp_verbose)
log_ppp_warn("mschap-v2: user not found\n");
- chap_send_failure(ad);
+ chap_send_failure(ad, conf_msg_failure, conf_msg_failure2);
return -1;
}
- u_passwd=_malloc(strlen(passwd)*2);
- for(i=0; i<strlen(passwd); i++)
- {
+ u_passwd = _malloc(strlen(passwd) * 2);
+ for (i = 0; i < strlen(passwd); i++) {
u_passwd[i*2]=passwd[i];
u_passwd[i*2+1]=0;
}
SHA1_Init(&sha_ctx);
- SHA1_Update(&sha_ctx,msg->peer_challenge,16);
- SHA1_Update(&sha_ctx,ad->val,16);
- SHA1_Update(&sha_ctx,name,strlen(name));
- SHA1_Final(c_hash,&sha_ctx);
+ SHA1_Update(&sha_ctx, msg->peer_challenge, 16);
+ SHA1_Update(&sha_ctx, ad->val, 16);
+ SHA1_Update(&sha_ctx, name, strlen(name));
+ SHA1_Final(c_hash, &sha_ctx);
- memset(z_hash,0,sizeof(z_hash));
+ memset(z_hash, 0, sizeof(z_hash));
MD4_Init(&md4_ctx);
- MD4_Update(&md4_ctx,u_passwd,strlen(passwd)*2);
- MD4_Final(z_hash,&md4_ctx);
+ MD4_Update(&md4_ctx, u_passwd, strlen(passwd) * 2);
+ MD4_Final(z_hash, &md4_ctx);
- des_encrypt(c_hash,z_hash,nt_hash);
- des_encrypt(c_hash,z_hash+7,nt_hash+8);
- des_encrypt(c_hash,z_hash+14,nt_hash+16);
+ des_encrypt(c_hash, z_hash, nt_hash);
+ des_encrypt(c_hash, z_hash + 7, nt_hash + 8);
+ des_encrypt(c_hash, z_hash + 14, nt_hash + 16);
set_mppe_keys(ad, z_hash, msg->nt_hash);
_free(passwd);
_free(u_passwd);
- return memcmp(nt_hash,msg->nt_hash,24);
+ return memcmp(nt_hash, msg->nt_hash, 24);
}
static void set_mppe_keys(struct chap_auth_data_t *ad, uint8_t *z_hash, uint8_t *nt_hash)
@@ -542,8 +541,7 @@ static void set_mppe_keys(struct chap_auth_data_t *ad, uint8_t *z_hash, uint8_t
struct ev_mppe_keys_t ev_mppe = {
.ppp = ad->ppp,
- .type = 1 << 2,
- .policy = 1,
+ .policy = -1,
.recv_key = recv_key,
.send_key = send_key,
};
@@ -622,7 +620,7 @@ static void chap_recv(struct ppp_handler_t *h)
log_ppp_warn("mschap-v2: unknown code received %x\n",hdr->code);
}
-static void __init auth_mschap_v2_init()
+static void auth_mschap_v2_init()
{
urandom_fd = open("/dev/urandom", O_RDONLY);
if (urandom_fd < 0) {
@@ -634,3 +632,4 @@ static void __init auth_mschap_v2_init()
log_emerg("mschap-v2: failed to register handler\n");
}
+DEFINE_INIT(4, auth_mschap_v2_init);
diff --git a/accel-pppd/auth/auth_pap.c b/accel-pppd/auth/auth_pap.c
index 70e8081..e051dd7 100644
--- a/accel-pppd/auth/auth_pap.c
+++ b/accel-pppd/auth/auth_pap.c
@@ -198,9 +198,14 @@ static int pap_recv_req(struct pap_auth_data_t *p, struct pap_hdr_t *hdr)
peer_id = _strndup((const char*)peer_id, peer_id_len);
if (conf_any_login) {
+ if (ppp_auth_successed(p->ppp, peer_id)) {
+ pap_send_nak(p, hdr->id);
+ ppp_terminate(p->ppp, TERM_AUTH_ERROR, 0);
+ _free(peer_id);
+ return -1;
+ }
pap_send_ack(p, hdr->id);
p->started = 1;
- ppp_auth_successed(p->ppp, peer_id);
return 0;
}
@@ -223,15 +228,19 @@ static int pap_recv_req(struct pap_auth_data_t *p, struct pap_hdr_t *hdr)
ppp_terminate(p->ppp, TERM_AUTH_ERROR, 0);
else
ppp_auth_failed(p->ppp, peer_id);
- ret=-1;
+ ret = -1;
_free(peer_id);
} else {
- pap_send_ack(p, hdr->id);
- if (!p->started) {
+ if (ppp_auth_successed(p->ppp, peer_id)) {
+ pap_send_nak(p, hdr->id);
+ ppp_terminate(p->ppp, TERM_AUTH_ERROR, 0);
+ _free(peer_id);
+ ret = -1;
+ } else {
+ pap_send_ack(p, hdr->id);
p->started = 1;
- ppp_auth_successed(p->ppp, peer_id);
+ ret = 0;
}
- ret = 0;
}
_free(passwd);
@@ -256,7 +265,7 @@ static void pap_recv(struct ppp_handler_t *h)
}
}
-static void __init auth_pap_init()
+static void auth_pap_init()
{
char *opt;
@@ -271,3 +280,4 @@ static void __init auth_pap_init()
ppp_auth_register_handler(&pap);
}
+DEFINE_INIT(7, auth_pap_init);
diff --git a/accel-pppd/cli/cli.c b/accel-pppd/cli/cli.c
index 5009a74..00d5ffb 100644
--- a/accel-pppd/cli/cli.c
+++ b/accel-pppd/cli/cli.c
@@ -219,9 +219,11 @@ static void load_config(void)
conf_cli_prompt = (char *)def_cli_prompt;
}
-static void __init init(void)
+static void init(void)
{
load_config();
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
}
+
+DEFINE_INIT(10, init);
diff --git a/accel-pppd/cli/show_sessions.c b/accel-pppd/cli/show_sessions.c
index 555fa88..d7a8a82 100644
--- a/accel-pppd/cli/show_sessions.c
+++ b/accel-pppd/cli/show_sessions.c
@@ -29,6 +29,7 @@ struct col_t
struct list_head entry;
struct column_t *column;
int width;
+ int hidden;
};
struct row_t
@@ -131,6 +132,7 @@ static int show_ses_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
int i, n, total_width, def_columns = 0;
struct ppp_t *ppp;
char *buf = NULL;
+ int match_key_f = 0, order_key_f = 0;
LIST_HEAD(c_list);
LIST_HEAD(r_list);
LIST_HEAD(t_list);
@@ -179,10 +181,15 @@ static int show_ses_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
if (ptr2)
*ptr2 = 0;
column = find_column(ptr1);
+ if (column == match_key)
+ match_key_f = 1;
+ if (column == order_key)
+ order_key_f = 1;
if (column) {
col = _malloc(sizeof(*col));
col->column = column;
col->width = strlen(column->name);
+ col->hidden = 0;
list_add_tail(&col->entry, &c_list);
} else {
if (!def_columns) {
@@ -197,6 +204,22 @@ static int show_ses_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
}
_free(columns);
+ if (match_key && !match_key_f) {
+ col = _malloc(sizeof(*col));
+ col->column = match_key;
+ col->width = 0;
+ col->hidden = 1;
+ list_add_tail(&col->entry, &c_list);
+ }
+
+ if (order_key && !order_key_f) {
+ col = _malloc(sizeof(*col));
+ col->column = order_key;
+ col->width = 0;
+ col->hidden = 1;
+ list_add_tail(&col->entry, &c_list);
+ }
+
pthread_rwlock_rdlock(&ppp_lock);
list_for_each_entry(ppp, &ppp_list, entry) {
row = _malloc(sizeof(*row));
@@ -244,8 +267,11 @@ static int show_ses_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
}
total_width = -1;
- list_for_each_entry(col, &c_list, entry)
+ list_for_each_entry(col, &c_list, entry) {
+ if (col->hidden)
+ continue;
total_width += col->width + 3;
+ }
buf = _malloc(total_width + 3);
if (!buf)
@@ -253,6 +279,8 @@ static int show_ses_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
ptr1 = buf;
list_for_each_entry(col, &c_list, entry) {
+ if (col->hidden)
+ continue;
n = strlen(col->column->name);
if (col->width > n + 1) {
ptr2 = ptr1;
@@ -278,6 +306,8 @@ static int show_ses_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
ptr1 = buf;
list_for_each_entry(col, &c_list, entry) {
+ if (col->hidden)
+ continue;
memset(ptr1, '-', col->width + 2);
ptr1 += col->width + 2;
*ptr1 = '+';
@@ -291,6 +321,8 @@ static int show_ses_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
row = list_entry(r_list.next, typeof(*row), entry);
ptr1 = buf;
list_for_each_entry(cell, &row->cell_list, entry) {
+ if (cell->col->hidden)
+ continue;
ptr2 = ptr1;
sprintf(ptr1, " %s ", cell->buf);
ptr1 = strchr(ptr1, 0);
@@ -417,7 +449,7 @@ static void print_sid(const struct ppp_t *ppp, char *buf)
snprintf(buf, CELL_SIZE, "%s", ppp->sessionid);
}
-void __init init(void)
+static void init(void)
{
cli_register_simple_cmd2(show_ses_exec, show_ses_help, 2, "show", "sessions");
@@ -432,3 +464,4 @@ void __init init(void)
cli_show_ses_register("sid", "session id", print_sid);
}
+DEFINE_INIT(12, init);
diff --git a/accel-pppd/cli/std_cmd.c b/accel-pppd/cli/std_cmd.c
index 43407f1..1c8e149 100644
--- a/accel-pppd/cli/std_cmd.c
+++ b/accel-pppd/cli/std_cmd.c
@@ -16,6 +16,7 @@
static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
+ struct timespec ts;
time_t dt;
int day,hour;
char statm_fname[128];
@@ -33,8 +34,8 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt,
fclose(f);
}
- time(&dt);
- dt -= triton_stat.start_time;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ dt = ts.tv_sec - triton_stat.start_time;
day = dt / (60 * 60 * 24);
dt %= 60 * 60 * 24;
hour = dt / (60 * 60);
@@ -161,7 +162,7 @@ static int terminate_exec2(int key, char * const *f, int f_cnt, void *cli)
list_for_each_entry(ppp, &ppp_list, entry) {
switch (key) {
case 0:
- if (strcmp(ppp->username, f[2]))
+ if (!ppp->username || strcmp(ppp->username, f[2]))
continue;
break;
case 1:
@@ -326,7 +327,7 @@ static void reload_help(char * const *fields, int fields_cnt, void *client)
cli_send(client, "reload - reload config file\r\n");
}
-static void __init init(void)
+static void init(void)
{
cli_register_simple_cmd2(show_stat_exec, show_stat_help, 2, "show", "stat");
cli_register_simple_cmd2(terminate_exec, terminate_help, 1, "terminate");
@@ -335,3 +336,4 @@ static void __init init(void)
cli_register_simple_cmd2(exit_exec, exit_help, 1, "exit");
}
+DEFINE_INIT(12, init);
diff --git a/accel-pppd/cli/tcp.c b/accel-pppd/cli/tcp.c
index 260225f..fea0e4e 100644
--- a/accel-pppd/cli/tcp.c
+++ b/accel-pppd/cli/tcp.c
@@ -339,7 +339,7 @@ static void start_server(const char *host, int port)
triton_context_wakeup(&serv_ctx);
}
-static void __init init(void)
+static void init(void)
{
const char *opt;
char *host, *d;
@@ -369,3 +369,4 @@ err_fmt:
free(host);
}
+DEFINE_INIT(11, init);
diff --git a/accel-pppd/cli/telnet.c b/accel-pppd/cli/telnet.c
index 82bcb0d..2643692 100644
--- a/accel-pppd/cli/telnet.c
+++ b/accel-pppd/cli/telnet.c
@@ -718,7 +718,7 @@ static void load_history_file(void)
fclose(f);
}
-static void __init init(void)
+static void init(void)
{
const char *opt;
char *host, *d;
@@ -757,3 +757,4 @@ err_fmt:
free(host);
}
+DEFINE_INIT(11, init);
diff --git a/accel-pppd/ctrl/l2tp/dict.c b/accel-pppd/ctrl/l2tp/dict.c
index c93ccd4..aaa7da4 100644
--- a/accel-pppd/ctrl/l2tp/dict.c
+++ b/accel-pppd/ctrl/l2tp/dict.c
@@ -257,7 +257,7 @@ static int l2tp_dict_load(const char *fname)
return r;
}
-static void __init dict_init(void)
+static void dict_init(void)
{
char *opt;
@@ -269,3 +269,4 @@ static void __init dict_init(void)
_exit(EXIT_FAILURE);
}
+DEFINE_INIT(20, dict_init);
diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c
index ca56051..c9ed08e 100644
--- a/accel-pppd/ctrl/l2tp/l2tp.c
+++ b/accel-pppd/ctrl/l2tp/l2tp.c
@@ -48,6 +48,7 @@ int conf_timeout = 60;
int conf_rtimeout = 5;
int conf_retransmit = 5;
int conf_hello_interval = 60;
+int conf_dir300_quirk = 0;
char *conf_host_name = NULL;
static unsigned int stat_active;
@@ -300,6 +301,7 @@ static int l2tp_tunnel_alloc(struct l2tp_serv_t *serv, struct l2tp_packet_t *pac
conn->hello_timer.expire = l2tp_send_HELLO;
conn->hello_timer.period = conf_hello_interval * 1000;
conn->ctrl.ctx = &conn->ctx;
+ conn->ctrl.type = CTRL_TYPE_L2TP;
conn->ctrl.name = "l2tp";
conn->ctrl.started = l2tp_ppp_started;
conn->ctrl.finished = l2tp_ppp_finished;
@@ -838,7 +840,7 @@ static int l2tp_conn_read(struct triton_md_handler_t *h)
if (!pack)
continue;
- if (ntohs(pack->hdr.tid) != conn->tid) {
+ if (ntohs(pack->hdr.tid) != conn->tid && (pack->hdr.tid || !conf_dir300_quirk)) {
if (conf_verbose)
log_warn("l2tp: incorrect tid %i in tunnel %i\n", ntohs(pack->hdr.tid), conn->tid);
l2tp_packet_free(pack);
@@ -1090,6 +1092,12 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt,
return CLI_CMD_OK;
}
+void __export l2tp_get_stat(unsigned int **starting, unsigned int **active)
+{
+ *starting = &stat_starting;
+ *active = &stat_active;
+}
+
static void load_config(void)
{
char *opt;
@@ -1121,9 +1129,13 @@ static void load_config(void)
conf_host_name = _strdup(opt);
else
conf_host_name = NULL;
+
+ opt = conf_get_opt("l2tp", "dir300_quirk");
+ if (opt)
+ conf_dir300_quirk = atoi(opt);
}
-static void __init l2tp_init(void)
+static void l2tp_init(void)
{
l2tp_conn = malloc(L2TP_MAX_TID * sizeof(void *));
memset(l2tp_conn, 0, L2TP_MAX_TID * sizeof(void *));
@@ -1139,3 +1151,4 @@ static void __init l2tp_init(void)
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
}
+DEFINE_INIT(22, l2tp_init);
diff --git a/accel-pppd/ctrl/l2tp/netlink.c b/accel-pppd/ctrl/l2tp/netlink.c
index 7c8c79a..c8dce89 100644
--- a/accel-pppd/ctrl/l2tp/netlink.c
+++ b/accel-pppd/ctrl/l2tp/netlink.c
@@ -80,7 +80,7 @@ void l2tp_nl_create_session(int tid, int sid, int peer_sid)
nl_socket_free(nl_sock);
}
-static void __init init(void)
+static void init(void)
{
struct nl_sock *nl_sock = nl_socket_alloc();
@@ -92,3 +92,4 @@ static void __init init(void)
nl_socket_free(nl_sock);
}
+DEFINE_INIT(21, init);
diff --git a/accel-pppd/ctrl/l2tp/packet.c b/accel-pppd/ctrl/l2tp/packet.c
index e3f6896..d312118 100644
--- a/accel-pppd/ctrl/l2tp/packet.c
+++ b/accel-pppd/ctrl/l2tp/packet.c
@@ -485,10 +485,11 @@ int l2tp_packet_add_octets(struct l2tp_packet_t *pack, int id, const uint8_t *va
return 0;
}
-static void __init init(void)
+static void init(void)
{
attr_pool = mempool_create(sizeof(struct l2tp_attr_t));
pack_pool = mempool_create(sizeof(struct l2tp_packet_t));
buf_pool = mempool_create(L2TP_MAX_PACKET_SIZE);
}
+DEFINE_INIT(21, init);
diff --git a/accel-pppd/ctrl/pppoe/cli.c b/accel-pppd/ctrl/pppoe/cli.c
index 9929f66..37aec3a 100644
--- a/accel-pppd/ctrl/pppoe/cli.c
+++ b/accel-pppd/ctrl/pppoe/cli.c
@@ -189,7 +189,7 @@ static int set_ac_name_exec(const char *cmd, char * const *f, int f_cnt, void *c
//===================================
-static void __init init(void)
+static void init(void)
{
cli_register_simple_cmd2(show_stat_exec, NULL, 2, "show", "stat");
cli_register_simple_cmd2(intf_exec, intf_help, 2, "pppoe", "interface");
@@ -203,3 +203,4 @@ static void __init init(void)
cli_register_simple_cmd2(show_ac_name_exec, NULL, 3, "pppoe", "show", "AC-Name");
}
+DEFINE_INIT(22, init);
diff --git a/accel-pppd/ctrl/pppoe/mac_filter.c b/accel-pppd/ctrl/pppoe/mac_filter.c
index 9b101c6..8d72c31 100644
--- a/accel-pppd/ctrl/pppoe/mac_filter.c
+++ b/accel-pppd/ctrl/pppoe/mac_filter.c
@@ -244,7 +244,7 @@ static void cmd_help(char * const *fields, int fields_cnt, void *client)
cli_send(client, "pppoe mac-filter show - show current mac-filter list\r\n");
}
-static void __init init(void)
+static void init(void)
{
const char *opt = conf_get_opt("pppoe", "mac-filter");
if (!opt || mac_filter_load(opt))
@@ -253,3 +253,4 @@ static void __init init(void)
cli_register_simple_cmd2(cmd_exec, cmd_help, 2, "pppoe", "mac-filter");
}
+DEFINE_INIT(20, init);
diff --git a/accel-pppd/ctrl/pppoe/pppoe.c b/accel-pppd/ctrl/pppoe/pppoe.c
index c7612e2..031766b 100644
--- a/accel-pppd/ctrl/pppoe/pppoe.c
+++ b/accel-pppd/ctrl/pppoe/pppoe.c
@@ -69,10 +69,12 @@ char *conf_service_name;
char *conf_ac_name;
int conf_ifname_in_sid;
char *conf_pado_delay;
+int conf_tr101 = 1;
static mempool_t conn_pool;
static mempool_t pado_pool;
+unsigned int stat_starting;
unsigned int stat_active;
unsigned int stat_delayed_pado;
unsigned long stat_PADI_recv;
@@ -246,6 +248,7 @@ static struct pppoe_conn_t *allocate_channel(struct pppoe_serv_t *serv, const ui
conn->ctrl.started = ppp_started;
conn->ctrl.finished = ppp_finished;
conn->ctrl.max_mtu = MAX_PPPOE_MTU;
+ conn->ctrl.type = CTRL_TYPE_PPPOE;
conn->ctrl.name = "pppoe";
conn->ctrl.calling_station_id = _malloc(IFNAMSIZ + 19);
@@ -857,7 +860,8 @@ static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size)
continue;
vendor_id = ntohl(*(uint32_t *)tag->tag_data);
if (vendor_id == VENDOR_ADSL_FORUM)
- tr101_tag = tag;
+ if (conf_tr101)
+ tr101_tag = tag;
break;
}
}
@@ -1215,6 +1219,12 @@ void pppoe_server_stop(const char *ifname)
pthread_rwlock_unlock(&serv_lock);
}
+void __export pppoe_get_stat(unsigned int **starting, unsigned int **active)
+{
+ *starting = &stat_starting;
+ *active = &stat_active;
+}
+
static int init_secret(struct pppoe_serv_t *serv)
{
int fd;
@@ -1241,7 +1251,57 @@ static int init_secret(struct pppoe_serv_t *serv)
return 0;
}
-static void __init pppoe_init(void)
+static void load_config(void)
+{
+ char *opt;
+
+ opt = conf_get_opt("pppoe", "verbose");
+ if (opt)
+ conf_verbose = atoi(opt);
+
+ opt = conf_get_opt("pppoe", "ac-name");
+ if (!opt)
+ opt = conf_get_opt("pppoe", "AC-Name");
+ if (opt) {
+ if (conf_ac_name)
+ _free(conf_ac_name);
+ conf_ac_name = _strdup(opt);
+ } else
+ conf_ac_name = _strdup("accel-ppp");
+
+ opt = conf_get_opt("pppoe", "service-name");
+ if (!opt)
+ opt = conf_get_opt("pppoe", "Service-Name");
+ if (opt) {
+ if (conf_service_name)
+ _free(conf_service_name);
+ conf_service_name = _strdup(opt);
+ }
+
+ opt = conf_get_opt("pppoe", "ifname-in-sid");
+ if (opt) {
+ if (!strcmp(opt, "called-sid"))
+ conf_ifname_in_sid = 1;
+ else if (!strcmp(opt, "calling-sid"))
+ conf_ifname_in_sid = 2;
+ else if (!strcmp(opt, "both"))
+ conf_ifname_in_sid = 3;
+ else if (atoi(opt) >= 0)
+ conf_ifname_in_sid = atoi(opt);
+ }
+
+ opt = conf_get_opt("pppoe", "pado-delay");
+ if (!opt)
+ opt = conf_get_opt("pppoe", "PADO-Delay");
+ if (opt)
+ dpado_parse(opt);
+
+ opt = conf_get_opt("pppoe", "tr101");
+ if (opt)
+ conf_tr101 = atoi(opt);
+}
+
+static void pppoe_init(void)
{
struct conf_sect_t *s = conf_get_section("pppoe");
struct conf_option_t *opt;
@@ -1258,33 +1318,12 @@ static void __init pppoe_init(void)
if (!strcmp(opt->name, "interface")) {
if (opt->val)
pppoe_server_start(opt->val, NULL);
- } else if (!strcmp(opt->name, "verbose")) {
- if (atoi(opt->val) > 0)
- conf_verbose = 1;
- } else if (!strcmp(opt->name, "ac-name") || !strcmp(opt->name, "AC-Name")) {
- if (opt->val && strlen(opt->val))
- conf_ac_name = _strdup(opt->val);
- } else if (!strcmp(opt->name, "service-name") || !strcmp(opt->name, "Service-Name")) {
- if (opt->val && strlen(opt->val))
- conf_service_name = _strdup(opt->val);
- } else if (!strcmp(opt->name, "pado-delay") || !strcmp(opt->name, "PADO-delay")) {
- if (dpado_parse(opt->val))
- _exit(EXIT_FAILURE);
- } else if (!strcmp(opt->name, "ifname-in-sid")) {
- if (!opt->val)
- continue;
- if (!strcmp(opt->val, "called-sid"))
- conf_ifname_in_sid = 1;
- else if (!strcmp(opt->val, "calling-sid"))
- conf_ifname_in_sid = 2;
- else if (!strcmp(opt->val, "both"))
- conf_ifname_in_sid = 3;
- else if (atoi(opt->val) >= 0)
- conf_ifname_in_sid = atoi(opt->val);
}
}
- if (!conf_ac_name)
- conf_ac_name = _strdup("accel-ppp");
+ load_config();
+
+ triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
}
+DEFINE_INIT(21, pppoe_init);
diff --git a/accel-pppd/ctrl/pptp/pptp.c b/accel-pppd/ctrl/pptp/pptp.c
index 17087fa..715a77b 100644
--- a/accel-pppd/ctrl/pptp/pptp.c
+++ b/accel-pppd/ctrl/pptp/pptp.c
@@ -402,10 +402,10 @@ static int pptp_echo_rply(struct pptp_conn_t *conn)
if (conf_verbose)
log_ppp_debug("recv [PPTP Echo-Reply <Identifier %x>]\n", msg->identifier);
- if (msg->identifier != conn->echo_sent) {
+ /*if (msg->identifier != conn->echo_sent) {
log_ppp_warn("pptp:echo: identifier mismatch\n");
//return -1;
- }
+ }*/
conn->echo_sent = 0;
return 0;
}
@@ -656,6 +656,7 @@ static int pptp_connect(struct triton_md_handler_t *h)
conn->ctrl.started = ppp_started;
conn->ctrl.finished = ppp_finished;
conn->ctrl.max_mtu = PPTP_MAX_MTU;
+ conn->ctrl.type = CTRL_TYPE_PPTP;
conn->ctrl.name = "pptp";
conn->ctrl.calling_station_id = _malloc(17);
@@ -703,6 +704,12 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt,
return CLI_CMD_OK;
}
+void __export pptp_get_stat(unsigned int **starting, unsigned int **active)
+{
+ *starting = &stat_starting;
+ *active = &stat_active;
+}
+
static void load_config(void)
{
char *opt;
@@ -724,7 +731,7 @@ static void load_config(void)
conf_verbose = 1;
}
-static void __init pptp_init(void)
+static void pptp_init(void)
{
struct sockaddr_in addr;
char *opt;
@@ -776,3 +783,4 @@ static void __init pptp_init(void)
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
}
+DEFINE_INIT(20, pptp_init);
diff --git a/accel-pppd/extra/CMakeLists.txt b/accel-pppd/extra/CMakeLists.txt
index 03d857a..2144906 100644
--- a/accel-pppd/extra/CMakeLists.txt
+++ b/accel-pppd/extra/CMakeLists.txt
@@ -17,3 +17,7 @@ IF (SHAPER)
INSTALL(TARGETS shaper_tbf LIBRARY DESTINATION lib/accel-ppp)
ENDIF (SHAPER)
+
+IF (NETSNMP)
+ ADD_SUBDIRECTORY(net-snmp)
+ENDIF (NETSNMP)
diff --git a/accel-pppd/extra/chap-secrets.c b/accel-pppd/extra/chap-secrets.c
index 3a299cc..61cd2a9 100644
--- a/accel-pppd/extra/chap-secrets.c
+++ b/accel-pppd/extra/chap-secrets.c
@@ -154,11 +154,11 @@ found:
}
pd->ip.addr = conf_gw_ip_address;
- if (n >= 3)
+ if (n >= 3 && ptr[2][0] != '*')
pd->ip.peer_addr = inet_addr(ptr[2]);
pd->ip.owner = &ipdb;
- if (n == 4)
+ if (n >= 4)
pd->rate = _strdup(ptr[3]);
list_add_tail(&pd->pd.entry, &ppp->pd_list);
@@ -224,7 +224,7 @@ static struct ipv4db_item_t *get_ip(struct ppp_t *ppp)
if (!pd)
return NULL;
- if (!pd->ip.addr)
+ if (!pd->ip.peer_addr)
return NULL;
return &pd->ip;
@@ -268,7 +268,7 @@ static void load_config(void)
conf_gw_ip_address = inet_addr(opt);
}
-static void __init init(void)
+static void init(void)
{
load_config();
@@ -280,3 +280,4 @@ static void __init init(void)
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
}
+DEFINE_INIT(100, init);
diff --git a/accel-pppd/extra/ippool.c b/accel-pppd/extra/ippool.c
index 2637c6a..d49f0f4 100644
--- a/accel-pppd/extra/ippool.c
+++ b/accel-pppd/extra/ippool.c
@@ -182,7 +182,7 @@ static struct ipdb_t ipdb = {
.put_ipv4 = put_ip,
};
-static void __init ipool_init(void)
+static void ippool_init(void)
{
struct conf_sect_t *s = conf_get_section("ip-pool");
struct conf_option_t *opt;
@@ -206,3 +206,5 @@ static void __init ipool_init(void)
ipdb_register(&ipdb);
}
+DEFINE_INIT(101, ippool_init);
+
diff --git a/accel-pppd/extra/net-snmp/ACCEL-PPP-MIB.txt b/accel-pppd/extra/net-snmp/ACCEL-PPP-MIB.txt
new file mode 100644
index 0000000..5af38e8
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/ACCEL-PPP-MIB.txt
@@ -0,0 +1,326 @@
+ACCEL-PPP-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+ MODULE-IDENTITY, OBJECT-TYPE, Gauge32
+ NOTIFICATION-TYPE FROM SNMPv2-SMI
+ netSnmp FROM NET-SNMP-MIB
+ InetAddressIPv4 FROM INET-ADDRESS-MIB
+ IANAtunnelType FROM IANAifType-MIB
+;
+
+accelPPP MODULE-IDENTITY
+ LAST-UPDATED "201108180000Z"
+ ORGANIZATION "accel-ppp.sourceforge.net"
+ CONTACT-INFO
+ "email: xeb@mail.ru"
+ DESCRIPTION
+ "MIB objects for accel-ppp"
+ REVISION "201108180000Z"
+ DESCRIPTION
+ "First draft"
+ ::= { netSnmp 100 }
+
+--
+-- top level structure
+--
+accelPPPStat OBJECT IDENTIFIER ::= { accelPPP 1 }
+accelPPPSessions OBJECT IDENTIFIER ::= { accelPPP 2 }
+accelPPPAdmin OBJECT IDENTIFIER ::= { accelPPP 3 }
+--accelPPPNotifications OBJECT IDENTIFIER ::= { accelPPP 4 }
+
+statCore OBJECT IDENTIFIER ::= { accelPPPStat 1 }
+statPPP OBJECT IDENTIFIER ::= { accelPPPStat 2 }
+statPPTP OBJECT IDENTIFIER ::= { accelPPPStat 3 }
+statL2TP OBJECT IDENTIFIER ::= { accelPPPStat 4 }
+statPPPOE OBJECT IDENTIFIER ::= { accelPPPStat 5 }
+--statRadius OBJECT IDENTIFIER ::= { accelPPPStat 6 }
+
+
+statCoreUpTime OBJECT-TYPE
+ SYNTAX Gauge32
+ UNITS "seconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "accel-ppp uptime"
+ ::= { statCore 1 }
+
+statCoreCPU OBJECT-TYPE
+ SYNTAX INTEGER (0..100)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "cpu utilization"
+ ::= { statCore 2 }
+
+statCoreMemRss OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "memory rss size"
+ ::= { statCore 3 }
+
+
+--
+-- PPP stats
+--
+
+statPPPStarting OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "count of sessions which are
+ in starting phase"
+ ::= { statPPP 1 }
+
+statPPPActive OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "count of active sessions"
+ ::= { statPPP 2 }
+
+statPPPFinishing OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "count of active which are
+ in finishing phase"
+ ::= { statPPP 3 }
+
+--
+-- PPTP stats
+--
+
+statPPTPStarting OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "count of connections which are
+ in starting phase"
+ ::= { statPPTP 1 }
+
+statPPTPActive OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "count of active connections"
+ ::= { statPPTP 2 }
+
+--
+-- L2TP stats
+--
+
+statL2TPStarting OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "count of connections which are
+ in starting phase"
+ ::= { statL2TP 1 }
+
+statL2TPActive OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "count of active connections"
+ ::= { statL2TP 2 }
+
+--
+-- PPPOE stats
+--
+
+statPPPOEStarting OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "count of connections which are
+ in starting phase"
+ ::= { statPPPOE 1 }
+
+statPPPOEActive OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "count of active connections"
+ ::= { statPPPOE 2 }
+
+
+--
+-- PPP session table
+--
+
+sessionTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF sessionEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "this table contains information about
+ connected sessions"
+ ::= { accelPPPSessions 1 }
+
+sessionEntry OBJECT-TYPE
+ SYNTAX sessionEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A row describing a given session"
+ INDEX { sesSID }
+ ::= { sessionTable 1 }
+
+sessionEntry ::= SEQUENCE {
+ sesSID OCTET STRING,
+ sesIfName OCTET STRING,
+ sesUsername OCTET STRING,
+ sesIP InetAddress,
+ sesType IANAtunnelType,
+ sesState INTEGER,
+ sesUptime TimeTicks,
+ sesCallingSID OCTET STRING,
+ sesCalledSID OCTET STRING
+}
+
+sesSID OBJECT-TYPE
+ SYNTAX OCTET STRING (SIZE(16))
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Acct-Session-ID"
+ ::= { sessionEntry 1 }
+
+sesIfName OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "name of ppp interface"
+ ::= { sessionEntry 2 }
+
+sesUsername OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "session user name"
+ ::= { sessionEntry 3 }
+
+sesIP OBJECT-TYPE
+ SYNTAX InetAddressIPv4
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "assigned IP address"
+ ::= { sessionEntry 4 }
+
+sesType OBJECT-TYPE
+ SYNTAX INTEGER {
+ pptp(1),
+ l2tp(2),
+ pppoe(3)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "name of ppp interface"
+ ::= { sessionEntry 5 }
+
+sesState OBJECT-TYPE
+ SYNTAX INTEGER {
+ starting(1),
+ active(2),
+ finishing(3)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "state of session"
+ ::= { sessionEntry 6 }
+
+sesUptime OBJECT-TYPE
+ SYNTAX Gauge32
+ UNITS "seconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "uptime of session"
+ ::= { sessionEntry 7 }
+
+sesCallingSID OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Calling-Station-ID"
+ ::= { sessionEntry 8 }
+
+sesCalledSID OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Called-Station-ID"
+ ::= { sessionEntry 9 }
+
+--
+-- Administration
+--
+
+terminate OBJECT IDENTIFIER ::= { accelPPPAdmin 1 }
+
+termBySID OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS write-only
+ STATUS current
+ DESCRIPTION
+ "Terminate session softly identified by Acct-Session-ID"
+ ::= { terminate 1 }
+
+termByIfName OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS write-only
+ STATUS current
+ DESCRIPTION
+ "Terminate session softly identified by interface name"
+ ::= { terminate 2 }
+
+termByIP OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS write-only
+ STATUS current
+ DESCRIPTION
+ "Terminate session softly identified by Framed-IP-Address"
+ ::= { terminate 3 }
+
+termByUsername OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS write-only
+ STATUS current
+ DESCRIPTION
+ "Terminate session softly identified by username"
+ ::= { terminate 4 }
+
+
+shutdown OBJECT-TYPE
+ SYNTAX INTEGER {
+ normal(0),
+ soft(1),
+ hard(2),
+ cancel(3)
+ }
+ MAX-ACCESS write-only
+ STATUS current
+ DESCRIPTION
+ "shutdown accel-ppp"
+ ::= { accelPPPAdmin 2 }
+
+END
diff --git a/accel-pppd/extra/net-snmp/CMakeLists.txt b/accel-pppd/extra/net-snmp/CMakeLists.txt
new file mode 100644
index 0000000..4dadb2c
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/CMakeLists.txt
@@ -0,0 +1,23 @@
+SET(sources
+ agent.c
+ sessionTable.c
+ sessionTable_data_access.c
+ sessionTable_data_get.c
+ sessionTable_data_set.c
+ sessionTable_interface.c
+ statCore.c
+ statL2TP.c
+ statPPP.c
+ statPPPOE.c
+ statPPTP.c
+ terminate.c
+ shutdown.c
+)
+
+ADD_LIBRARY(net-snmp SHARED ${sources})
+TARGET_LINK_LIBRARIES(net-snmp netsnmpagent netsnmphelpers netsnmpmibs
+netsnmp)
+
+INSTALL(TARGETS net-snmp
+ LIBRARY DESTINATION lib/accel-ppp
+)
diff --git a/accel-pppd/extra/net-snmp/agent.c b/accel-pppd/extra/net-snmp/agent.c
new file mode 100644
index 0000000..dd38b44
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/agent.c
@@ -0,0 +1,150 @@
+#include <pthread.h>
+#include <signal.h>
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#include "log.h"
+#include "triton.h"
+
+#include "statCore.h"
+#include "statPPP.h"
+#include "statPPTP.h"
+#include "statL2TP.h"
+#include "statPPPOE.h"
+#include "terminate.h"
+#include "shutdown.h"
+#include "sessionTable.h"
+
+static const char *conf_agent_name = "accel-ppp";
+static int conf_master = 0;
+/*static const char *conf_oid_prefix = "1.3.6.1.4.1.8072.100";
+
+static oid* oid_prefix;
+static size_t oid_prefix_size;*/
+
+static pthread_t snmp_thr;
+static int snmp_term = 0;
+
+/*int accel_ppp_alloc_oid(oid tail, size_t size, oid **oid)
+{
+ *oid = malloc(sizeof(oid) * (oid_prefix_size + size));
+
+ memcpy(*oid, oid_prefix, oid_prefix_size);
+ memcpy((*oid) + oid_prefix_size, tail, size);
+
+ return oid_prefix_size + size;
+}*/
+
+static int agent_log(int major, int minor, void *serv_arg, void *cl_arg)
+{
+ struct snmp_log_message *m = serv_arg;
+
+ switch (m->priority) {
+ case LOG_EMERG:
+ log_emerg("net-snmp: %s", m->msg);
+ break;
+ case LOG_ALERT:
+ case LOG_CRIT:
+ case LOG_ERR:
+ log_error("net-snmp: %s", m->msg);
+ break;
+ case LOG_WARNING:
+ log_warn("net-snmp: %s", m->msg);
+ break;
+ case LOG_NOTICE:
+ log_info1("net-snmp: %s", m->msg);
+ break;
+ case LOG_INFO:
+ log_info2("net-snmp: %s", m->msg);
+ break;
+ case LOG_DEBUG:
+ log_debug("net-snmp: %s", m->msg);
+ break;
+ default:
+ log_msg("net-snmp: %s", m->msg);
+ }
+ return 0;
+}
+
+static void *snmp_thread(void *a)
+{
+ sigset_t set;
+
+ sigfillset(&set);
+ sigdelset(&set, SIGKILL);
+ sigdelset(&set, SIGSTOP);
+ pthread_sigmask(SIG_BLOCK, &set, NULL);
+
+ snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_LOGGING, agent_log, NULL);
+ snmp_disable_log();
+ snmp_enable_calllog();
+ //snmp_set_do_debugging(1);
+ //netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
+
+ if (!conf_master)
+ netsnmp_enable_subagent();
+
+ init_agent(conf_agent_name);
+
+ init_statCore();
+ init_statPPP();
+ init_statPPTP();
+ init_statL2TP();
+ init_statPPPOE();
+ init_terminate();
+ init_shutdown();
+ init_sessionTable();
+
+ init_snmp(conf_agent_name);
+
+ if (conf_master)
+ init_master_agent();
+
+ while (!snmp_term) {
+ agent_check_and_process(1);
+ }
+
+ snmp_shutdown(conf_agent_name);
+
+ SOCK_CLEANUP;
+
+ return NULL;
+}
+
+static void snmp_ctx_close(struct triton_context_t *ctx)
+{
+ snmp_term = 1;
+ snmp_shutdown(conf_agent_name);
+ triton_context_unregister(ctx);
+}
+
+static struct triton_context_t ctx = {
+ .close = snmp_ctx_close,
+};
+
+static void init(void)
+{
+ const char *opt;
+
+ opt = conf_get_opt("snmp", "master");
+ if (opt)
+ conf_master = atoi(opt);
+
+ opt = conf_get_opt("snmp", "agent-name");
+ if (opt)
+ conf_agent_name = opt;
+
+ /*opt = conf_get_opt("snmp", "oid-prefix")
+ if (opt)
+ conf_oid_prefix = opt;*/
+
+ pthread_create(&snmp_thr, NULL, snmp_thread, NULL);
+ triton_context_register(&ctx, NULL);
+ triton_context_wakeup(&ctx);
+ triton_collect_cpu_usage();
+}
+
+DEFINE_INIT(100, init);
+
diff --git a/accel-pppd/extra/net-snmp/sessionTable.c b/accel-pppd/extra/net-snmp/sessionTable.c
new file mode 100644
index 0000000..dc7d62b
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/sessionTable.c
@@ -0,0 +1,201 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * version : 14170 $ of $
+ *
+ * $Id:$
+ */
+/** \page MFD helper for sessionTable
+ *
+ * \section intro Introduction
+ * Introductory text.
+ *
+ */
+/* standard Net-SNMP includes */
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+/* include our parent header */
+#include "sessionTable.h"
+
+#include <net-snmp/agent/mib_modules.h>
+
+#include "sessionTable_interface.h"
+
+oid sessionTable_oid[] = { SESSIONTABLE_OID };
+int sessionTable_oid_size = OID_LENGTH(sessionTable_oid);
+
+ sessionTable_registration sessionTable_user_context;
+
+void initialize_table_sessionTable(void);
+void shutdown_table_sessionTable(void);
+
+
+/**
+ * Initializes the sessionTable module
+ */
+void
+init_sessionTable(void)
+{
+ DEBUGMSGTL(("verbose:sessionTable:init_sessionTable","called\n"));
+
+ /*
+ * TODO:300:o: Perform sessionTable one-time module initialization.
+ */
+
+ /*
+ * here we initialize all the tables we're planning on supporting
+ */
+ if (should_init("sessionTable"))
+ initialize_table_sessionTable();
+
+} /* init_sessionTable */
+
+/**
+ * Shut-down the sessionTable module (agent is exiting)
+ */
+void
+shutdown_sessionTable(void)
+{
+ if (should_init("sessionTable"))
+ shutdown_table_sessionTable();
+
+}
+
+/**
+ * Initialize the table sessionTable
+ * (Define its contents and how it's structured)
+ */
+void
+initialize_table_sessionTable(void)
+{
+ sessionTable_registration * user_context;
+ u_long flags;
+
+ DEBUGMSGTL(("verbose:sessionTable:initialize_table_sessionTable","called\n"));
+
+ /*
+ * TODO:301:o: Perform sessionTable one-time table initialization.
+ */
+
+ /*
+ * TODO:302:o: |->Initialize sessionTable user context
+ * if you'd like to pass in a pointer to some data for this
+ * table, allocate or set it up here.
+ */
+ /*
+ * a netsnmp_data_list is a simple way to store void pointers. A simple
+ * string token is used to add, find or remove pointers.
+ */
+ user_context = netsnmp_create_data_list("sessionTable", NULL, NULL);
+
+ /*
+ * No support for any flags yet, but in the future you would
+ * set any flags here.
+ */
+ flags = 0;
+
+ /*
+ * call interface initialization code
+ */
+ _sessionTable_initialize_interface(user_context, flags);
+} /* initialize_table_sessionTable */
+
+/**
+ * Shutdown the table sessionTable
+ */
+void
+shutdown_table_sessionTable(void)
+{
+ /*
+ * call interface shutdown code
+ */
+ _sessionTable_shutdown_interface(&sessionTable_user_context);
+}
+
+/**
+ * extra context initialization (eg default values)
+ *
+ * @param rowreq_ctx : row request context
+ * @param user_init_ctx : void pointer for user (parameter to rowreq_ctx_allocate)
+ *
+ * @retval MFD_SUCCESS : no errors
+ * @retval MFD_ERROR : error (context allocate will fail)
+ */
+int
+sessionTable_rowreq_ctx_init(sessionTable_rowreq_ctx *rowreq_ctx,
+ void *user_init_ctx)
+{
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_rowreq_ctx_init","called\n"));
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ /*
+ * TODO:210:o: |-> Perform extra sessionTable rowreq initialization. (eg DEFVALS)
+ */
+
+ return MFD_SUCCESS;
+} /* sessionTable_rowreq_ctx_init */
+
+/**
+ * extra context cleanup
+ *
+ */
+void sessionTable_rowreq_ctx_cleanup(sessionTable_rowreq_ctx *rowreq_ctx)
+{
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_rowreq_ctx_cleanup","called\n"));
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ /*
+ * TODO:211:o: |-> Perform extra sessionTable rowreq cleanup.
+ */
+} /* sessionTable_rowreq_ctx_cleanup */
+
+/**
+ * pre-request callback
+ *
+ *
+ * @retval MFD_SUCCESS : success.
+ * @retval MFD_ERROR : other error
+ */
+int
+sessionTable_pre_request(sessionTable_registration * user_context)
+{
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_pre_request","called\n"));
+
+ /*
+ * TODO:510:o: Perform sessionTable pre-request actions.
+ */
+
+ return MFD_SUCCESS;
+} /* sessionTable_pre_request */
+
+/**
+ * post-request callback
+ *
+ * Note:
+ * New rows have been inserted into the container, and
+ * deleted rows have been removed from the container and
+ * released.
+ *
+ * @param user_context
+ * @param rc : MFD_SUCCESS if all requests succeeded
+ *
+ * @retval MFD_SUCCESS : success.
+ * @retval MFD_ERROR : other error (ignored)
+ */
+int
+sessionTable_post_request(sessionTable_registration * user_context, int rc)
+{
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_post_request","called\n"));
+
+ /*
+ * TODO:511:o: Perform sessionTable post-request actions.
+ */
+
+ return MFD_SUCCESS;
+} /* sessionTable_post_request */
+
+
+/** @{ */
diff --git a/accel-pppd/extra/net-snmp/sessionTable.h b/accel-pppd/extra/net-snmp/sessionTable.h
new file mode 100644
index 0000000..f5619d9
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/sessionTable.h
@@ -0,0 +1,195 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * version : 14170 $ of $
+ *
+ * $Id:$
+ */
+#ifndef SESSIONTABLE_H
+#define SESSIONTABLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @addtogroup misc misc: Miscellaneous routines
+ *
+ * @{
+ */
+#include <net-snmp/library/asn1.h>
+
+#include "ppp.h"
+
+/* other required module components */
+ /* *INDENT-OFF* */
+config_add_mib(ACCEL-PPP-MIB)
+config_require(ACCEL-PPP-MIB/sessionTable/sessionTable_interface)
+config_require(ACCEL-PPP-MIB/sessionTable/sessionTable_data_access)
+config_require(ACCEL-PPP-MIB/sessionTable/sessionTable_data_get)
+config_require(ACCEL-PPP-MIB/sessionTable/sessionTable_data_set)
+ /* *INDENT-ON* */
+
+/* OID and column number definitions for sessionTable */
+#include "sessionTable_oids.h"
+
+/* enum definions */
+#include "sessionTable_enums.h"
+
+/* *********************************************************************
+ * function declarations
+ */
+void init_sessionTable(void);
+void shutdown_sessionTable(void);
+
+/* *********************************************************************
+ * Table declarations
+ */
+/**********************************************************************
+ **********************************************************************
+ ***
+ *** Table sessionTable
+ ***
+ **********************************************************************
+ **********************************************************************/
+/*
+ * ACCEL-PPP-MIB::sessionTable is subid 1 of accelPPPSessions.
+ * Its status is Current.
+ * OID: .1.3.6.1.4.1.8072.100.2.1, length: 10
+*/
+/* *********************************************************************
+ * When you register your mib, you get to provide a generic
+ * pointer that will be passed back to you for most of the
+ * functions calls.
+ *
+ * TODO:100:r: Review all context structures
+ */
+ /*
+ * TODO:101:o: |-> Review sessionTable registration context.
+ */
+typedef netsnmp_data_list sessionTable_registration;
+
+/**********************************************************************/
+/*
+ * TODO:110:r: |-> Review sessionTable data context structure.
+ * This structure is used to represent the data for sessionTable.
+ */
+struct sessionTable_data_s
+{
+ char ifname[PPP_IFNAME_LEN];
+ char *username;
+ in_addr_t peer_addr;
+ int type;
+ int state;
+ unsigned long uptime;
+ char *calling_sid;
+ char *called_sid;
+};
+typedef struct sessionTable_data_s sessionTable_data;
+
+
+/*
+ * TODO:120:r: |-> Review sessionTable mib index.
+ * This structure is used to represent the index for sessionTable.
+ */
+typedef struct sessionTable_mib_index_s {
+
+ /*
+ * sesSID(1)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/h
+ */
+ char sesSID[PPP_SESSIONID_LEN];
+ size_t sesSID_len;
+
+
+} sessionTable_mib_index;
+
+ /*
+ * TODO:121:r: | |-> Review sessionTable max index length.
+ * If you KNOW that your indexes will never exceed a certain
+ * length, update this macro to that length.
+ *
+ * BE VERY CAREFUL TO TAKE INTO ACCOUNT THE MAXIMUM
+ * POSSIBLE LENGHT FOR EVERY VARIABLE LENGTH INDEX!
+ * Guessing 128 - col/entry(2) - oid len(10)
+*/
+#define MAX_sessionTable_IDX_LEN PPP_SESSIONID_LEN + 1
+
+
+/* *********************************************************************
+ * TODO:130:o: |-> Review sessionTable Row request (rowreq) context.
+ * When your functions are called, you will be passed a
+ * sessionTable_rowreq_ctx pointer.
+ */
+typedef struct sessionTable_rowreq_ctx_s {
+
+ /** this must be first for container compare to work */
+ netsnmp_index oid_idx;
+ oid oid_tmp[MAX_sessionTable_IDX_LEN];
+
+ sessionTable_mib_index tbl_idx;
+
+ sessionTable_data * data;
+
+ /*
+ * flags per row. Currently, the first (lower) 8 bits are reserved
+ * for the user. See mfd.h for other flags.
+ */
+ u_int rowreq_flags;
+
+ /*
+ * TODO:131:o: | |-> Add useful data to sessionTable rowreq context.
+ */
+
+ /*
+ * storage for future expansion
+ */
+ netsnmp_data_list *sessionTable_data_list;
+
+} sessionTable_rowreq_ctx;
+
+typedef struct sessionTable_ref_rowreq_ctx_s {
+ sessionTable_rowreq_ctx *rowreq_ctx;
+} sessionTable_ref_rowreq_ctx;
+
+/* *********************************************************************
+ * function prototypes
+ */
+ int sessionTable_pre_request(sessionTable_registration * user_context);
+ int sessionTable_post_request(sessionTable_registration * user_context,
+ int rc);
+
+ int sessionTable_rowreq_ctx_init(sessionTable_rowreq_ctx *rowreq_ctx,
+ void *user_init_ctx);
+ void sessionTable_rowreq_ctx_cleanup(sessionTable_rowreq_ctx *rowreq_ctx);
+
+ sessionTable_data * sessionTable_allocate_data(void);
+ void sessionTable_release_data(sessionTable_data *data);
+
+
+ sessionTable_rowreq_ctx *
+ sessionTable_row_find_by_mib_index(sessionTable_mib_index *mib_idx);
+
+extern oid sessionTable_oid[];
+extern int sessionTable_oid_size;
+
+
+#include "sessionTable_interface.h"
+#include "sessionTable_data_access.h"
+#include "sessionTable_data_get.h"
+#include "sessionTable_data_set.h"
+
+/*
+ * DUMMY markers, ignore
+ *
+ * TODO:099:x: *************************************************************
+ * TODO:199:x: *************************************************************
+ * TODO:299:x: *************************************************************
+ * TODO:399:x: *************************************************************
+ * TODO:499:x: *************************************************************
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SESSIONTABLE_H */
+/** @} */
diff --git a/accel-pppd/extra/net-snmp/sessionTable_data_access.c b/accel-pppd/extra/net-snmp/sessionTable_data_access.c
new file mode 100644
index 0000000..847197a
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/sessionTable_data_access.c
@@ -0,0 +1,304 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * version : 14170 $ of $
+ *
+ * $Id:$
+ */
+/* standard Net-SNMP includes */
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+/* include our parent header */
+#include "sessionTable.h"
+
+
+#include "sessionTable_data_access.h"
+
+#include "ppp.h"
+
+/** @ingroup interface
+ * @addtogroup data_access data_access: Routines to access data
+ *
+ * These routines are used to locate the data used to satisfy
+ * requests.
+ *
+ * @{
+ */
+/**********************************************************************
+ **********************************************************************
+ ***
+ *** Table sessionTable
+ ***
+ **********************************************************************
+ **********************************************************************/
+/*
+ * ACCEL-PPP-MIB::sessionTable is subid 1 of accelPPPSessions.
+ * Its status is Current.
+ * OID: .1.3.6.1.4.1.8072.100.2.1, length: 10
+*/
+
+/**
+ * initialization for sessionTable data access
+ *
+ * This function is called during startup to allow you to
+ * allocate any resources you need for the data table.
+ *
+ * @param sessionTable_reg
+ * Pointer to sessionTable_registration
+ *
+ * @retval MFD_SUCCESS : success.
+ * @retval MFD_ERROR : unrecoverable error.
+ */
+int
+sessionTable_init_data(sessionTable_registration * sessionTable_reg)
+{
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_init_data","called\n"));
+
+ /*
+ * TODO:303:o: Initialize sessionTable data->
+ */
+ /*
+ ***************************************************
+ *** START EXAMPLE CODE ***
+ ***---------------------------------------------***/
+ /*
+ * if you are the sole writer for the file, you could
+ * open it here. However, as stated earlier, we are assuming
+ * the worst case, which in this case means that the file is
+ * written to by someone else, and might not even exist when
+ * we start up. So we can't do anything here.
+ */
+ /*
+ ***---------------------------------------------***
+ *** END EXAMPLE CODE ***
+ ***************************************************/
+
+ return MFD_SUCCESS;
+} /* sessionTable_init_data */
+
+/**
+ * container overview
+ *
+ */
+
+/**
+ * container initialization
+ *
+ * @param container_ptr_ptr A pointer to a container pointer. If you
+ * create a custom container, use this parameter to return it
+ * to the MFD helper. If set to NULL, the MFD helper will
+ * allocate a container for you.
+ *
+ * This function is called at startup to allow you to customize certain
+ * aspects of the access method. For the most part, it is for advanced
+ * users. The default code should suffice for most cases. If no custom
+ * container is allocated, the MFD code will create one for your.
+ *
+ * @remark
+ * This would also be a good place to do any initialization needed
+ * for you data source. For example, opening a connection to another
+ * process that will supply the data, opening a database, etc.
+ */
+void
+sessionTable_container_init(netsnmp_container **container_ptr_ptr,
+ netsnmp_cache *cache)
+{
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_container_init","called\n"));
+
+ if (NULL == container_ptr_ptr) {
+ snmp_log(LOG_ERR,"bad container param to sessionTable_container_init\n");
+ return;
+ }
+
+ /*
+ * For advanced users, you can use a custom container. If you
+ * do not create one, one will be created for you.
+ */
+ *container_ptr_ptr = NULL;
+
+ if (NULL == cache) {
+ snmp_log(LOG_ERR,"bad cache param to sessionTable_container_init\n");
+ return;
+ }
+
+ /*
+ * TODO:345:A: Set up sessionTable cache properties.
+ *
+ * Also for advanced users, you can set parameters for the
+ * cache. Do not change the magic pointer, as it is used
+ * by the MFD helper. To completely disable caching, set
+ * cache->enabled to 0.
+ */
+ cache->timeout = -1; /* seconds */
+} /* sessionTable_container_init */
+
+/**
+ * container shutdown
+ *
+ * @param container_ptr A pointer to the container.
+ *
+ * This function is called at shutdown to allow you to customize certain
+ * aspects of the access method. For the most part, it is for advanced
+ * users. The default code should suffice for most cases.
+ *
+ * This function is called before sessionTable_container_free().
+ *
+ * @remark
+ * This would also be a good place to do any cleanup needed
+ * for you data source. For example, closing a connection to another
+ * process that supplied the data, closing a database, etc.
+ */
+void
+sessionTable_container_shutdown(netsnmp_container *container_ptr)
+{
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_container_shutdown","called\n"));
+
+ if (NULL == container_ptr) {
+ snmp_log(LOG_ERR,"bad params to sessionTable_container_shutdown\n");
+ return;
+ }
+
+} /* sessionTable_container_shutdown */
+
+/**
+ * load initial data
+ *
+ * TODO:350:M: Implement sessionTable data load
+ *
+ * @param container container to which items should be inserted
+ *
+ * @retval MFD_SUCCESS : success.
+ * @retval MFD_RESOURCE_UNAVAILABLE : Can't access data source
+ * @retval MFD_ERROR : other error.
+ *
+ * This function is called to load the index(es) (and data, optionally)
+ * for the every row in the data set.
+ *
+ * @remark
+ * While loading the data, the only important thing is the indexes.
+ * If access to your data is cheap/fast (e.g. you have a pointer to a
+ * structure in memory), it would make sense to update the data here.
+ * If, however, the accessing the data invovles more work (e.g. parsing
+ * some other existing data, or peforming calculations to derive the data),
+ * then you can limit yourself to setting the indexes and saving any
+ * information you will need later. Then use the saved information in
+ * sessionTable_row_prep() for populating data->
+ *
+ * @note
+ * If you need consistency between rows (like you want statistics
+ * for each row to be from the same time frame), you should set all
+ * data here.
+ *
+ */
+int
+sessionTable_container_load(netsnmp_container *container)
+{
+ sessionTable_rowreq_ctx *rowreq_ctx;
+ size_t count = 0;
+ struct ppp_t *ppp;
+ time_t t;
+
+ time(&t);
+
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_container_load","called\n"));
+
+ pthread_rwlock_rdlock(&ppp_lock);
+ list_for_each_entry(ppp, &ppp_list, entry) {
+ rowreq_ctx = sessionTable_allocate_rowreq_ctx(NULL, NULL);
+ if (NULL == rowreq_ctx) {
+ pthread_rwlock_unlock(&ppp_lock);
+ snmp_log(LOG_ERR, "memory allocation failed\n");
+ return MFD_RESOURCE_UNAVAILABLE;
+ }
+ if(MFD_SUCCESS != sessionTable_indexes_set(rowreq_ctx
+ , ppp->sessionid, PPP_SESSIONID_LEN
+ )) {
+ snmp_log(LOG_ERR,"error setting index while loading "
+ "sessionTable data->\n");
+ sessionTable_release_rowreq_ctx(rowreq_ctx);
+ continue;
+ }
+
+ strcpy(rowreq_ctx->data->ifname, ppp->ifname);
+
+ if (ppp->username)
+ rowreq_ctx->data->username = strdup(ppp->username);
+ else
+ ppp->username = strdup("");
+
+ rowreq_ctx->data->peer_addr = ppp->peer_ipaddr;
+ rowreq_ctx->data->type = ppp->ctrl->type;
+ rowreq_ctx->data->state = ppp->state;
+ rowreq_ctx->data->uptime = (ppp->stop_time ? ppp->stop_time : t) - ppp->start_time;
+ rowreq_ctx->data->calling_sid = strdup(ppp->ctrl->calling_station_id);
+ rowreq_ctx->data->called_sid = strdup(ppp->ctrl->called_station_id);
+
+ CONTAINER_INSERT(container, rowreq_ctx);
+ ++count;
+ }
+ pthread_rwlock_unlock(&ppp_lock);
+
+ DEBUGMSGT(("verbose:sessionTable:sessionTable_container_load",
+ "inserted %d records\n", count));
+
+ return MFD_SUCCESS;
+} /* sessionTable_container_load */
+
+/**
+ * container clean up
+ *
+ * @param container container with all current items
+ *
+ * This optional callback is called prior to all
+ * item's being removed from the container. If you
+ * need to do any processing before that, do it here.
+ *
+ * @note
+ * The MFD helper will take care of releasing all the row contexts.
+ * If you did not pass a data context pointer when allocating
+ * the rowreq context, the one that was allocated will be deleted.
+ * If you did pass one in, it will not be deleted and that memory
+ * is your responsibility.
+ *
+ */
+void
+sessionTable_container_free(netsnmp_container *container)
+{
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_container_free","called\n"));
+
+ /*
+ * TODO:380:M: Free sessionTable container data->
+ */
+} /* sessionTable_container_free */
+
+/**
+ * prepare row for processing.
+ *
+ * When the agent has located the row for a request, this function is
+ * called to prepare the row for processing. If you fully populated
+ * the data context during the index setup phase, you may not need to
+ * do anything.
+ *
+ * @param rowreq_ctx pointer to a context.
+ *
+ * @retval MFD_SUCCESS : success.
+ * @retval MFD_ERROR : other error.
+ */
+int
+sessionTable_row_prep( sessionTable_rowreq_ctx *rowreq_ctx)
+{
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_row_prep","called\n"));
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ /*
+ * TODO:390:o: Prepare row for request.
+ * If populating row data was delayed, this is the place to
+ * fill in the row for this request.
+ */
+
+ return MFD_SUCCESS;
+} /* sessionTable_row_prep */
+
+/** @} */
diff --git a/accel-pppd/extra/net-snmp/sessionTable_data_access.h b/accel-pppd/extra/net-snmp/sessionTable_data_access.h
new file mode 100644
index 0000000..1c420ce
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/sessionTable_data_access.h
@@ -0,0 +1,76 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * version : 14170 $ of $
+ *
+ * $Id:$
+ */
+#ifndef SESSIONTABLE_DATA_ACCESS_H
+#define SESSIONTABLE_DATA_ACCESS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* *********************************************************************
+ * function declarations
+ */
+
+/* *********************************************************************
+ * Table declarations
+ */
+/**********************************************************************
+ **********************************************************************
+ ***
+ *** Table sessionTable
+ ***
+ **********************************************************************
+ **********************************************************************/
+/*
+ * ACCEL-PPP-MIB::sessionTable is subid 1 of accelPPPSessions.
+ * Its status is Current.
+ * OID: .1.3.6.1.4.1.8072.100.2.1, length: 10
+*/
+
+
+ int sessionTable_init_data(sessionTable_registration * sessionTable_reg);
+
+
+ /*
+ * TODO:180:o: Review sessionTable cache timeout.
+ * The number of seconds before the cache times out
+ */
+#define SESSIONTABLE_CACHE_TIMEOUT 60
+
+void sessionTable_container_init(netsnmp_container **container_ptr_ptr,
+ netsnmp_cache *cache);
+void sessionTable_container_shutdown(netsnmp_container *container_ptr);
+
+int sessionTable_container_load(netsnmp_container *container);
+void sessionTable_container_free(netsnmp_container *container);
+
+int sessionTable_cache_load(netsnmp_container *container);
+void sessionTable_cache_free(netsnmp_container *container);
+
+ /*
+ ***************************************************
+ *** START EXAMPLE CODE ***
+ ***---------------------------------------------***/
+/* *********************************************************************
+ * Since we have no idea how you really access your data, we'll go with
+ * a worst case example: a flat text file.
+ */
+#define MAX_LINE_SIZE 256
+ /*
+ ***---------------------------------------------***
+ *** END EXAMPLE CODE ***
+ ***************************************************/
+ int sessionTable_row_prep( sessionTable_rowreq_ctx *rowreq_ctx);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SESSIONTABLE_DATA_ACCESS_H */
diff --git a/accel-pppd/extra/net-snmp/sessionTable_data_get.c b/accel-pppd/extra/net-snmp/sessionTable_data_get.c
new file mode 100644
index 0000000..1dcea1e
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/sessionTable_data_get.c
@@ -0,0 +1,696 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * version : 12088 $ of $
+ *
+ * $Id:$
+ */
+/* standard Net-SNMP includes */
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+/* include our parent header */
+#include "sessionTable.h"
+
+
+/** @defgroup data_get data_get: Routines to get data
+ *
+ * TODO:230:M: Implement sessionTable get routines.
+ * TODO:240:M: Implement sessionTable mapping routines (if any).
+ *
+ * These routine are used to get the value for individual objects. The
+ * row context is passed, along with a pointer to the memory where the
+ * value should be copied.
+ *
+ * @{
+ */
+/**********************************************************************
+ **********************************************************************
+ ***
+ *** Table sessionTable
+ ***
+ **********************************************************************
+ **********************************************************************/
+/*
+ * ACCEL-PPP-MIB::sessionTable is subid 1 of accelPPPSessions.
+ * Its status is Current.
+ * OID: .1.3.6.1.4.1.8072.100.2.1, length: 10
+*/
+
+/* ---------------------------------------------------------------------
+ * TODO:200:r: Implement sessionTable data context functions.
+ */
+/*
+ * sessionTable_allocate_data
+ *
+ * Purpose: create new sessionTable_data->
+ */
+sessionTable_data *
+sessionTable_allocate_data(void)
+{
+ sessionTable_data *rtn = SNMP_MALLOC_TYPEDEF(sessionTable_data);
+
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_allocate_data","called\n"));
+
+ if(NULL == rtn) {
+ snmp_log(LOG_ERR, "unable to malloc memory for new "
+ "sessionTable_data->\n");
+ }
+
+ memset(rtn, 0, sizeof(*rtn));
+
+ return rtn;
+} /* sessionTable_allocate_data */
+
+/*
+ * sessionTable_release_data
+ *
+ * Purpose: release sessionTable data->
+ */
+void
+sessionTable_release_data(sessionTable_data *data)
+{
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_release_data","called\n"));
+
+ if (data->username)
+ free(data->username);
+
+ if (data->calling_sid)
+ free(data->calling_sid);
+
+ if (data->called_sid)
+ free(data->called_sid);
+
+ free(data);
+} /* sessionTable_release_data */
+
+
+
+/**
+ * set mib index(es)
+ *
+ * @param tbl_idx mib index structure
+ * @param sesSID_ptr
+ * @param sesSID_ptr_len
+ *
+ * @retval MFD_SUCCESS : success.
+ * @retval MFD_ERROR : other error.
+ *
+ * @remark
+ * This convenience function is useful for setting all the MIB index
+ * components with a single function call. It is assume that the C values
+ * have already been mapped from their native/rawformat to the MIB format.
+ */
+int
+sessionTable_indexes_set_tbl_idx(sessionTable_mib_index *tbl_idx, char *sesSID_val_ptr, size_t sesSID_val_ptr_len)
+{
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_indexes_set_tbl_idx","called\n"));
+
+ /* sesSID(1)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/h */
+ tbl_idx->sesSID_len = sizeof(tbl_idx->sesSID)/sizeof(tbl_idx->sesSID[0]); /* max length */
+ /** WARNING: this code might not work for struct sessionTable_data_s */
+ /*
+ * make sure there is enough space for sesSID data
+ */
+ if ((NULL == tbl_idx->sesSID) ||
+ (tbl_idx->sesSID_len <
+ (sesSID_val_ptr_len))) {
+ snmp_log(LOG_ERR,"not enough space for value\n");
+ return MFD_ERROR;
+ }
+ tbl_idx->sesSID_len = sesSID_val_ptr_len;
+ memcpy( tbl_idx->sesSID, sesSID_val_ptr, sesSID_val_ptr_len* sizeof(sesSID_val_ptr[0]) );
+
+
+ return MFD_SUCCESS;
+} /* sessionTable_indexes_set_tbl_idx */
+
+/**
+ * @internal
+ * set row context indexes
+ *
+ * @param reqreq_ctx the row context that needs updated indexes
+ *
+ * @retval MFD_SUCCESS : success.
+ * @retval MFD_ERROR : other error.
+ *
+ * @remark
+ * This function sets the mib indexs, then updates the oid indexs
+ * from the mib index.
+ */
+int
+sessionTable_indexes_set(sessionTable_rowreq_ctx *rowreq_ctx, char *sesSID_val_ptr, size_t sesSID_val_ptr_len)
+{
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_indexes_set","called\n"));
+
+ if(MFD_SUCCESS != sessionTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx
+ , sesSID_val_ptr, sesSID_val_ptr_len
+ ))
+ return MFD_ERROR;
+
+ /*
+ * convert mib index to oid index
+ */
+ rowreq_ctx->oid_idx.len = sizeof(rowreq_ctx->oid_tmp) / sizeof(oid);
+ if(0 != sessionTable_index_to_oid(&rowreq_ctx->oid_idx,
+ &rowreq_ctx->tbl_idx)) {
+ return MFD_ERROR;
+ }
+
+ return MFD_SUCCESS;
+} /* sessionTable_indexes_set */
+
+
+/*---------------------------------------------------------------------
+ * ACCEL-PPP-MIB::sessionEntry.sesIfName
+ * sesIfName is subid 2 of sessionEntry.
+ * Its status is Current, and its access level is ReadOnly.
+ * OID: .1.3.6.1.4.1.8072.100.2.1.1.2
+ * Description:
+name of ppp interface
+ *
+ * Attributes:
+ * accessible 1 isscalar 0 enums 0 hasdefval 0
+ * readable 1 iscolumn 1 ranges 0 hashint 0
+ * settable 0
+ *
+ *
+ * Its syntax is OCTETSTR (based on perltype OCTETSTR)
+ * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
+ * This data type requires a length.
+ */
+/**
+ * Extract the current value of the sesIfName data->
+ *
+ * Set a value using the data context for the row.
+ *
+ * @param rowreq_ctx
+ * Pointer to the row request context.
+ * @param sesIfName_val_ptr_ptr
+ * Pointer to storage for a char variable
+ * @param sesIfName_val_ptr_len_ptr
+ * Pointer to a size_t. On entry, it will contain the size (in bytes)
+ * pointed to by sesIfName.
+ * On exit, this value should contain the data size (in bytes).
+ *
+ * @retval MFD_SUCCESS : success
+ * @retval MFD_SKIP : skip this node (no value for now)
+ * @retval MFD_ERROR : Any other error
+*
+ * @note If you need more than (*sesIfName_val_ptr_len_ptr) bytes of memory,
+ * allocate it using malloc() and update sesIfName_val_ptr_ptr.
+ * <b>DO NOT</b> free the previous pointer.
+ * The MFD helper will release the memory you allocate.
+ *
+ * @remark If you call this function yourself, you are responsible
+ * for checking if the pointer changed, and freeing any
+ * previously allocated memory. (Not necessary if you pass
+ * in a pointer to static memory, obviously.)
+ */
+int
+sesIfName_get( sessionTable_rowreq_ctx *rowreq_ctx, char **sesIfName_val_ptr_ptr, size_t *sesIfName_val_ptr_len_ptr )
+{
+ int len;
+ /** we should have a non-NULL pointer and enough storage */
+ netsnmp_assert( (NULL != sesIfName_val_ptr_ptr) && (NULL != *sesIfName_val_ptr_ptr));
+ netsnmp_assert( NULL != sesIfName_val_ptr_len_ptr );
+
+
+ DEBUGMSGTL(("verbose:sessionTable:sesIfName_get","called\n"));
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ len = strlen(rowreq_ctx->data->ifname);
+
+ if ((NULL == (* sesIfName_val_ptr_ptr )) ||
+ ((* sesIfName_val_ptr_len_ptr ) < len)) {
+ /*
+ * allocate space for sesIfName data
+ */
+ (* sesIfName_val_ptr_ptr ) = malloc(len);
+ if(NULL == (* sesIfName_val_ptr_ptr )) {
+ snmp_log(LOG_ERR,"could not allocate memory\n");
+ return MFD_ERROR;
+ }
+ }
+ (* sesIfName_val_ptr_len_ptr ) = len;
+ memcpy( (* sesIfName_val_ptr_ptr ), rowreq_ctx->data->ifname, len);
+
+ return MFD_SUCCESS;
+} /* sesIfName_get */
+
+/*---------------------------------------------------------------------
+ * ACCEL-PPP-MIB::sessionEntry.sesUsername
+ * sesUsername is subid 3 of sessionEntry.
+ * Its status is Current, and its access level is ReadOnly.
+ * OID: .1.3.6.1.4.1.8072.100.2.1.1.3
+ * Description:
+session user name
+ *
+ * Attributes:
+ * accessible 1 isscalar 0 enums 0 hasdefval 0
+ * readable 1 iscolumn 1 ranges 0 hashint 0
+ * settable 0
+ *
+ *
+ * Its syntax is OCTETSTR (based on perltype OCTETSTR)
+ * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
+ * This data type requires a length.
+ */
+/**
+ * Extract the current value of the sesUsername data->
+ *
+ * Set a value using the data context for the row.
+ *
+ * @param rowreq_ctx
+ * Pointer to the row request context.
+ * @param sesUsername_val_ptr_ptr
+ * Pointer to storage for a char variable
+ * @param sesUsername_val_ptr_len_ptr
+ * Pointer to a size_t. On entry, it will contain the size (in bytes)
+ * pointed to by sesUsername.
+ * On exit, this value should contain the data size (in bytes).
+ *
+ * @retval MFD_SUCCESS : success
+ * @retval MFD_SKIP : skip this node (no value for now)
+ * @retval MFD_ERROR : Any other error
+*
+ * @note If you need more than (*sesUsername_val_ptr_len_ptr) bytes of memory,
+ * allocate it using malloc() and update sesUsername_val_ptr_ptr.
+ * <b>DO NOT</b> free the previous pointer.
+ * The MFD helper will release the memory you allocate.
+ *
+ * @remark If you call this function yourself, you are responsible
+ * for checking if the pointer changed, and freeing any
+ * previously allocated memory. (Not necessary if you pass
+ * in a pointer to static memory, obviously.)
+ */
+int
+sesUsername_get( sessionTable_rowreq_ctx *rowreq_ctx, char **sesUsername_val_ptr_ptr, size_t *sesUsername_val_ptr_len_ptr )
+{
+ int len;
+ /** we should have a non-NULL pointer and enough storage */
+ netsnmp_assert( (NULL != sesUsername_val_ptr_ptr) && (NULL != *sesUsername_val_ptr_ptr));
+ netsnmp_assert( NULL != sesUsername_val_ptr_len_ptr );
+
+
+ DEBUGMSGTL(("verbose:sessionTable:sesUsername_get","called\n"));
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ len = strlen(rowreq_ctx->data->username);
+
+ if ((NULL == (* sesUsername_val_ptr_ptr )) ||
+ ((* sesUsername_val_ptr_len_ptr ) < len)) {
+ /*
+ * allocate space for sesIfName data
+ */
+ (* sesUsername_val_ptr_ptr ) = malloc(len);
+ if(NULL == (* sesUsername_val_ptr_ptr )) {
+ snmp_log(LOG_ERR,"could not allocate memory\n");
+ return MFD_ERROR;
+ }
+ }
+ (* sesUsername_val_ptr_len_ptr ) = len;
+ memcpy( (* sesUsername_val_ptr_ptr ), rowreq_ctx->data->username, len);
+
+ return MFD_SUCCESS;
+} /* sesUsername_get */
+
+/*---------------------------------------------------------------------
+ * ACCEL-PPP-MIB::sessionEntry.sesIP
+ * sesIP is subid 4 of sessionEntry.
+ * Its status is Current, and its access level is ReadOnly.
+ * OID: .1.3.6.1.4.1.8072.100.2.1.1.4
+ * Description:
+assigned IP address
+ *
+ * Attributes:
+ * accessible 1 isscalar 0 enums 0 hasdefval 0
+ * readable 1 iscolumn 1 ranges 0 hashint 0
+ * settable 0
+ *
+ *
+ * Its syntax is OCTETSTR (based on perltype OCTETSTR)
+ * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
+ * This data type requires a length.
+ */
+/**
+ * Extract the current value of the sesIP data->
+ *
+ * Set a value using the data context for the row.
+ *
+ * @param rowreq_ctx
+ * Pointer to the row request context.
+ * @param sesIP_val_ptr_ptr
+ * Pointer to storage for a char variable
+ * @param sesIP_val_ptr_len_ptr
+ * Pointer to a size_t. On entry, it will contain the size (in bytes)
+ * pointed to by sesIP.
+ * On exit, this value should contain the data size (in bytes).
+ *
+ * @retval MFD_SUCCESS : success
+ * @retval MFD_SKIP : skip this node (no value for now)
+ * @retval MFD_ERROR : Any other error
+*
+ * @note If you need more than (*sesIP_val_ptr_len_ptr) bytes of memory,
+ * allocate it using malloc() and update sesIP_val_ptr_ptr.
+ * <b>DO NOT</b> free the previous pointer.
+ * The MFD helper will release the memory you allocate.
+ *
+ * @remark If you call this function yourself, you are responsible
+ * for checking if the pointer changed, and freeing any
+ * previously allocated memory. (Not necessary if you pass
+ * in a pointer to static memory, obviously.)
+ */
+int
+sesIP_get( sessionTable_rowreq_ctx *rowreq_ctx, char **sesIP_val_ptr_ptr, size_t *sesIP_val_ptr_len_ptr )
+{
+ int len = 4;
+ /** we should have a non-NULL pointer and enough storage */
+ netsnmp_assert( (NULL != sesIP_val_ptr_ptr) && (NULL != *sesIP_val_ptr_ptr));
+ netsnmp_assert( NULL != sesIP_val_ptr_len_ptr );
+
+
+ DEBUGMSGTL(("verbose:sessionTable:sesIP_get","called\n"));
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ if ((NULL == (* sesIP_val_ptr_ptr )) ||
+ ((* sesIP_val_ptr_len_ptr ) < len)) {
+ /*
+ * allocate space for sesIfName data
+ */
+ (* sesIP_val_ptr_ptr ) = malloc(len);
+ if(NULL == (* sesIP_val_ptr_ptr )) {
+ snmp_log(LOG_ERR,"could not allocate memory\n");
+ return MFD_ERROR;
+ }
+ }
+ (* sesIP_val_ptr_len_ptr ) = len;
+ memcpy( (* sesIP_val_ptr_ptr ), &rowreq_ctx->data->peer_addr, len);
+
+ return MFD_SUCCESS;
+} /* sesIP_get */
+
+/*---------------------------------------------------------------------
+ * ACCEL-PPP-MIB::sessionEntry.sesType
+ * sesType is subid 5 of sessionEntry.
+ * Its status is Current, and its access level is ReadOnly.
+ * OID: .1.3.6.1.4.1.8072.100.2.1.1.5
+ * Description:
+name of ppp interface
+ *
+ * Attributes:
+ * accessible 1 isscalar 0 enums 1 hasdefval 0
+ * readable 1 iscolumn 1 ranges 0 hashint 0
+ * settable 0
+ *
+ * Enum range: 10/16. Values: other(1), direct(2), gre(3), minimal(4), l2tp(5), pptp(6), l2f(7), udp(8), atmp(9), msdp(10), sixToFour(11), sixOverFour(12), isatap(13), teredo(14)
+ *
+ * Its syntax is IANAtunnelType (based on perltype INTEGER)
+ * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
+ */
+/**
+ * Extract the current value of the sesType data->
+ *
+ * Set a value using the data context for the row.
+ *
+ * @param rowreq_ctx
+ * Pointer to the row request context.
+ * @param sesType_val_ptr
+ * Pointer to storage for a long variable
+ *
+ * @retval MFD_SUCCESS : success
+ * @retval MFD_SKIP : skip this node (no value for now)
+ * @retval MFD_ERROR : Any other error
+ */
+int
+sesType_get( sessionTable_rowreq_ctx *rowreq_ctx, u_long * sesType_val_ptr )
+{
+ /** we should have a non-NULL pointer */
+ netsnmp_assert( NULL != sesType_val_ptr );
+
+
+ DEBUGMSGTL(("verbose:sessionTable:sesType_get","called\n"));
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ (* sesType_val_ptr ) = rowreq_ctx->data->type;
+
+ return MFD_SUCCESS;
+} /* sesType_get */
+
+/*---------------------------------------------------------------------
+ * ACCEL-PPP-MIB::sessionEntry.sesState
+ * sesState is subid 6 of sessionEntry.
+ * Its status is Current, and its access level is ReadOnly.
+ * OID: .1.3.6.1.4.1.8072.100.2.1.1.6
+ * Description:
+state of session
+ *
+ * Attributes:
+ * accessible 1 isscalar 0 enums 1 hasdefval 0
+ * readable 1 iscolumn 1 ranges 0 hashint 0
+ * settable 0
+ *
+ * Enum range: 3/8. Values: starting(1), active(2), finishing(3)
+ *
+ * Its syntax is INTEGER (based on perltype INTEGER)
+ * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
+ */
+/**
+ * Extract the current value of the sesState data->
+ *
+ * Set a value using the data context for the row.
+ *
+ * @param rowreq_ctx
+ * Pointer to the row request context.
+ * @param sesState_val_ptr
+ * Pointer to storage for a long variable
+ *
+ * @retval MFD_SUCCESS : success
+ * @retval MFD_SKIP : skip this node (no value for now)
+ * @retval MFD_ERROR : Any other error
+ */
+int
+sesState_get( sessionTable_rowreq_ctx *rowreq_ctx, u_long * sesState_val_ptr )
+{
+ /** we should have a non-NULL pointer */
+ netsnmp_assert( NULL != sesState_val_ptr );
+
+
+ DEBUGMSGTL(("verbose:sessionTable:sesState_get","called\n"));
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ (* sesState_val_ptr ) = rowreq_ctx->data->state;
+
+ return MFD_SUCCESS;
+} /* sesState_get */
+
+/*---------------------------------------------------------------------
+ * ACCEL-PPP-MIB::sessionEntry.sesUptime
+ * sesUptime is subid 7 of sessionEntry.
+ * Its status is Current, and its access level is ReadOnly.
+ * OID: .1.3.6.1.4.1.8072.100.2.1.1.7
+ * Description:
+uptime of session
+ *
+ * Attributes:
+ * accessible 1 isscalar 0 enums 0 hasdefval 0
+ * readable 1 iscolumn 1 ranges 0 hashint 0
+ * settable 0
+ *
+ *
+ * Its syntax is TICKS (based on perltype TICKS)
+ * The net-snmp type is ASN_TIMETICKS. The C type decl is u_long (u_long)
+ */
+/**
+ * Extract the current value of the sesUptime data->
+ *
+ * Set a value using the data context for the row.
+ *
+ * @param rowreq_ctx
+ * Pointer to the row request context.
+ * @param sesUptime_val_ptr
+ * Pointer to storage for a u_long variable
+ *
+ * @retval MFD_SUCCESS : success
+ * @retval MFD_SKIP : skip this node (no value for now)
+ * @retval MFD_ERROR : Any other error
+ */
+int
+sesUptime_get( sessionTable_rowreq_ctx *rowreq_ctx, u_long * sesUptime_val_ptr )
+{
+ /** we should have a non-NULL pointer */
+ netsnmp_assert( NULL != sesUptime_val_ptr );
+
+
+ DEBUGMSGTL(("verbose:sessionTable:sesUptime_get","called\n"));
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ (* sesUptime_val_ptr ) = rowreq_ctx->data->uptime;
+
+ return MFD_SUCCESS;
+} /* sesUptime_get */
+
+/*---------------------------------------------------------------------
+ * ACCEL-PPP-MIB::sessionEntry.sesCallingSID
+ * sesCallingSID is subid 8 of sessionEntry.
+ * Its status is Current, and its access level is ReadOnly.
+ * OID: .1.3.6.1.4.1.8072.100.2.1.1.8
+ * Description:
+Calling-Station-ID
+ *
+ * Attributes:
+ * accessible 1 isscalar 0 enums 0 hasdefval 0
+ * readable 1 iscolumn 1 ranges 0 hashint 0
+ * settable 0
+ *
+ *
+ * Its syntax is OCTETSTR (based on perltype OCTETSTR)
+ * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
+ * This data type requires a length.
+ */
+/**
+ * Extract the current value of the sesCallingSID data->
+ *
+ * Set a value using the data context for the row.
+ *
+ * @param rowreq_ctx
+ * Pointer to the row request context.
+ * @param sesCallingSID_val_ptr_ptr
+ * Pointer to storage for a char variable
+ * @param sesCallingSID_val_ptr_len_ptr
+ * Pointer to a size_t. On entry, it will contain the size (in bytes)
+ * pointed to by sesCallingSID.
+ * On exit, this value should contain the data size (in bytes).
+ *
+ * @retval MFD_SUCCESS : success
+ * @retval MFD_SKIP : skip this node (no value for now)
+ * @retval MFD_ERROR : Any other error
+*
+ * @note If you need more than (*sesCallingSID_val_ptr_len_ptr) bytes of memory,
+ * allocate it using malloc() and update sesCallingSID_val_ptr_ptr.
+ * <b>DO NOT</b> free the previous pointer.
+ * The MFD helper will release the memory you allocate.
+ *
+ * @remark If you call this function yourself, you are responsible
+ * for checking if the pointer changed, and freeing any
+ * previously allocated memory. (Not necessary if you pass
+ * in a pointer to static memory, obviously.)
+ */
+int
+sesCallingSID_get( sessionTable_rowreq_ctx *rowreq_ctx, char **sesCallingSID_val_ptr_ptr, size_t *sesCallingSID_val_ptr_len_ptr )
+{
+ int len;
+ /** we should have a non-NULL pointer and enough storage */
+ netsnmp_assert( (NULL != sesCallingSID_val_ptr_ptr) && (NULL != *sesCallingSID_val_ptr_ptr));
+ netsnmp_assert( NULL != sesCallingSID_val_ptr_len_ptr );
+
+
+ DEBUGMSGTL(("verbose:sessionTable:sesCallingSID_get","called\n"));
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ len = strlen(rowreq_ctx->data->calling_sid);
+
+ if ((NULL == (* sesCallingSID_val_ptr_ptr )) ||
+ ((* sesCallingSID_val_ptr_len_ptr ) < len)) {
+ /*
+ * allocate space for sesCallingSID data
+ */
+ (* sesCallingSID_val_ptr_ptr ) = malloc(len);
+ if(NULL == (* sesCallingSID_val_ptr_ptr )) {
+ snmp_log(LOG_ERR,"could not allocate memory\n");
+ return MFD_ERROR;
+ }
+ }
+ (* sesCallingSID_val_ptr_len_ptr ) = len;
+ memcpy( (* sesCallingSID_val_ptr_ptr ), rowreq_ctx->data->calling_sid, len);
+
+ return MFD_SUCCESS;
+} /* sesCallingSID_get */
+
+/*---------------------------------------------------------------------
+ * ACCEL-PPP-MIB::sessionEntry.sesCalledSID
+ * sesCalledSID is subid 9 of sessionEntry.
+ * Its status is Current, and its access level is ReadOnly.
+ * OID: .1.3.6.1.4.1.8072.100.2.1.1.9
+ * Description:
+Called-Station-ID
+ *
+ * Attributes:
+ * accessible 1 isscalar 0 enums 0 hasdefval 0
+ * readable 1 iscolumn 1 ranges 0 hashint 0
+ * settable 0
+ *
+ *
+ * Its syntax is OCTETSTR (based on perltype OCTETSTR)
+ * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
+ * This data type requires a length.
+ */
+/**
+ * Extract the current value of the sesCalledSID data->
+ *
+ * Set a value using the data context for the row.
+ *
+ * @param rowreq_ctx
+ * Pointer to the row request context.
+ * @param sesCalledSID_val_ptr_ptr
+ * Pointer to storage for a char variable
+ * @param sesCalledSID_val_ptr_len_ptr
+ * Pointer to a size_t. On entry, it will contain the size (in bytes)
+ * pointed to by sesCalledSID.
+ * On exit, this value should contain the data size (in bytes).
+ *
+ * @retval MFD_SUCCESS : success
+ * @retval MFD_SKIP : skip this node (no value for now)
+ * @retval MFD_ERROR : Any other error
+*
+ * @note If you need more than (*sesCalledSID_val_ptr_len_ptr) bytes of memory,
+ * allocate it using malloc() and update sesCalledSID_val_ptr_ptr.
+ * <b>DO NOT</b> free the previous pointer.
+ * The MFD helper will release the memory you allocate.
+ *
+ * @remark If you call this function yourself, you are responsible
+ * for checking if the pointer changed, and freeing any
+ * previously allocated memory. (Not necessary if you pass
+ * in a pointer to static memory, obviously.)
+ */
+int
+sesCalledSID_get( sessionTable_rowreq_ctx *rowreq_ctx, char **sesCalledSID_val_ptr_ptr, size_t *sesCalledSID_val_ptr_len_ptr )
+{
+ int len;
+
+ /** we should have a non-NULL pointer and enough storage */
+ netsnmp_assert( (NULL != sesCalledSID_val_ptr_ptr) && (NULL != *sesCalledSID_val_ptr_ptr));
+ netsnmp_assert( NULL != sesCalledSID_val_ptr_len_ptr );
+
+
+ DEBUGMSGTL(("verbose:sessionTable:sesCalledSID_get","called\n"));
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ len = strlen(rowreq_ctx->data->called_sid);
+
+ if ((NULL == (* sesCalledSID_val_ptr_ptr )) ||
+ ((* sesCalledSID_val_ptr_len_ptr ) < len)) {
+ /*
+ * allocate space for sesCalledSID data
+ */
+ (* sesCalledSID_val_ptr_ptr ) = malloc(len);
+ if(NULL == (* sesCalledSID_val_ptr_ptr )) {
+ snmp_log(LOG_ERR,"could not allocate memory\n");
+ return MFD_ERROR;
+ }
+ }
+ (* sesCalledSID_val_ptr_len_ptr ) = len;
+ memcpy( (* sesCalledSID_val_ptr_ptr ), rowreq_ctx->data->called_sid, len);
+
+ return MFD_SUCCESS;
+} /* sesCalledSID_get */
+
+/** @} */
diff --git a/accel-pppd/extra/net-snmp/sessionTable_data_get.h b/accel-pppd/extra/net-snmp/sessionTable_data_get.h
new file mode 100644
index 0000000..e5a3ae6
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/sessionTable_data_get.h
@@ -0,0 +1,66 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * version : 12088 $ of $
+ *
+ * $Id:$
+ *
+ * @file sessionTable_data_get.h
+ *
+ * @addtogroup get
+ *
+ * Prototypes for get functions
+ *
+ * @{
+ */
+#ifndef SESSIONTABLE_DATA_GET_H
+#define SESSIONTABLE_DATA_GET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* *********************************************************************
+ * GET function declarations
+ */
+
+/* *********************************************************************
+ * GET Table declarations
+ */
+/**********************************************************************
+ **********************************************************************
+ ***
+ *** Table sessionTable
+ ***
+ **********************************************************************
+ **********************************************************************/
+/*
+ * ACCEL-PPP-MIB::sessionTable is subid 1 of accelPPPSessions.
+ * Its status is Current.
+ * OID: .1.3.6.1.4.1.8072.100.2.1, length: 10
+*/
+ /*
+ * indexes
+ */
+
+ int sesIfName_get( sessionTable_rowreq_ctx *rowreq_ctx, char **sesIfName_val_ptr_ptr, size_t *sesIfName_val_ptr_len_ptr );
+ int sesUsername_get( sessionTable_rowreq_ctx *rowreq_ctx, char **sesUsername_val_ptr_ptr, size_t *sesUsername_val_ptr_len_ptr );
+ int sesIP_get( sessionTable_rowreq_ctx *rowreq_ctx, char **sesIP_val_ptr_ptr, size_t *sesIP_val_ptr_len_ptr );
+ int sesType_get( sessionTable_rowreq_ctx *rowreq_ctx, u_long * sesType_val_ptr );
+ int sesState_get( sessionTable_rowreq_ctx *rowreq_ctx, u_long * sesState_val_ptr );
+ int sesUptime_get( sessionTable_rowreq_ctx *rowreq_ctx, u_long * sesUptime_val_ptr );
+ int sesCallingSID_get( sessionTable_rowreq_ctx *rowreq_ctx, char **sesCallingSID_val_ptr_ptr, size_t *sesCallingSID_val_ptr_len_ptr );
+ int sesCalledSID_get( sessionTable_rowreq_ctx *rowreq_ctx, char **sesCalledSID_val_ptr_ptr, size_t *sesCalledSID_val_ptr_len_ptr );
+
+
+int sessionTable_indexes_set_tbl_idx(sessionTable_mib_index *tbl_idx, char *sesSID_val_ptr, size_t sesSID_val_ptr_len);
+int sessionTable_indexes_set(sessionTable_rowreq_ctx *rowreq_ctx, char *sesSID_val_ptr, size_t sesSID_val_ptr_len);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SESSIONTABLE_DATA_GET_H */
+/** @} */
diff --git a/accel-pppd/extra/net-snmp/sessionTable_data_set.c b/accel-pppd/extra/net-snmp/sessionTable_data_set.c
new file mode 100644
index 0000000..ebfeeea
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/sessionTable_data_set.c
@@ -0,0 +1,24 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * version : 12077 $ of $
+ *
+ * $Id:$
+ *
+ */
+/* standard Net-SNMP includes */
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+/* include our parent header */
+#include "sessionTable.h"
+
+
+/** @defgroup data_set data_set: Routines to set data
+ *
+ * These routines are used to set the value for individual objects. The
+ * row context is passed, along with the new value.
+ *
+ * @{
+ */
+/** @} */
diff --git a/accel-pppd/extra/net-snmp/sessionTable_data_set.h b/accel-pppd/extra/net-snmp/sessionTable_data_set.h
new file mode 100644
index 0000000..70534ba
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/sessionTable_data_set.h
@@ -0,0 +1,27 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * version : 12077 $ of $
+ *
+ * $Id:$
+ */
+#ifndef SESSIONTABLE_DATA_SET_H
+#define SESSIONTABLE_DATA_SET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* *********************************************************************
+ * SET function declarations
+ */
+
+/* *********************************************************************
+ * SET Table declarations
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SESSIONTABLE_DATA_SET_H */
diff --git a/accel-pppd/extra/net-snmp/sessionTable_enums.h b/accel-pppd/extra/net-snmp/sessionTable_enums.h
new file mode 100644
index 0000000..c7ce845
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/sessionTable_enums.h
@@ -0,0 +1,85 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : generic-table-enums.m2c 12526 2005-07-15 22:41:16Z rstory $
+ *
+ * $Id:$
+ */
+#ifndef SESSIONTABLE_ENUMS_H
+#define SESSIONTABLE_ENUMS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * NOTES on enums
+ * ==============
+ *
+ * Value Mapping
+ * -------------
+ * If the values for your data type don't exactly match the
+ * possible values defined by the mib, you should map them
+ * below. For example, a boolean flag (1/0) is usually represented
+ * as a TruthValue in a MIB, which maps to the values (1/2).
+ *
+ */
+/*************************************************************************
+ *************************************************************************
+ *
+ * enum definitions for table sessionTable
+ *
+ *************************************************************************
+ *************************************************************************/
+
+/*************************************************************
+ * constants for enums for the MIB node
+ * sesType (IANAtunnelType / ASN_INTEGER)
+ *
+ * since a Textual Convention may be referenced more than once in a
+ * MIB, protect againt redefinitions of the enum values.
+ */
+#ifndef IANATUNNELTYPE_ENUMS
+#define IANATUNNELTYPE_ENUMS
+
+#define IANATUNNELTYPE_OTHER 1
+#define IANATUNNELTYPE_DIRECT 2
+#define IANATUNNELTYPE_GRE 3
+#define IANATUNNELTYPE_MINIMAL 4
+#define IANATUNNELTYPE_L2TP 5
+#define IANATUNNELTYPE_PPTP 6
+#define IANATUNNELTYPE_L2F 7
+#define IANATUNNELTYPE_UDP 8
+#define IANATUNNELTYPE_ATMP 9
+#define IANATUNNELTYPE_MSDP 10
+#define IANATUNNELTYPE_SIXTOFOUR 11
+#define IANATUNNELTYPE_SIXOVERFOUR 12
+#define IANATUNNELTYPE_ISATAP 13
+#define IANATUNNELTYPE_TEREDO 14
+
+#endif /* IANATUNNELTYPE_ENUMS */
+
+
+/*************************************************************
+ * constants for enums for the MIB node
+ * sesState (INTEGER / ASN_INTEGER)
+ *
+ * since a Textual Convention may be referenced more than once in a
+ * MIB, protect againt redefinitions of the enum values.
+ */
+#ifndef SESSTATE_ENUMS
+#define SESSTATE_ENUMS
+
+#define SESSTATE_STARTING 1
+#define SESSTATE_ACTIVE 2
+#define SESSTATE_FINISHING 3
+
+#endif /* SESSTATE_ENUMS */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SESSIONTABLE_ENUMS_H */
diff --git a/accel-pppd/extra/net-snmp/sessionTable_interface.c b/accel-pppd/extra/net-snmp/sessionTable_interface.c
new file mode 100644
index 0000000..cf60f91
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/sessionTable_interface.c
@@ -0,0 +1,946 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * version : 15899 $ of $
+ *
+ * $Id:$
+ */
+/*
+ * *********************************************************************
+ * *********************************************************************
+ * *********************************************************************
+ * *** ***
+ * *** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ***
+ * *** ***
+ * *** ***
+ * *** THIS FILE DOES NOT CONTAIN ANY USER EDITABLE CODE. ***
+ * *** ***
+ * *** ***
+ * *** THE GENERATED CODE IS INTERNAL IMPLEMENTATION, AND ***
+ * *** ***
+ * *** ***
+ * *** IS SUBJECT TO CHANGE WITHOUT WARNING IN FUTURE RELEASES. ***
+ * *** ***
+ * *** ***
+ * *********************************************************************
+ * *********************************************************************
+ * *********************************************************************
+ */
+
+/* standard Net-SNMP includes */
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+/* include our parent header */
+#include "sessionTable.h"
+
+
+#include <net-snmp/agent/table_container.h>
+#include <net-snmp/library/container.h>
+
+#include "sessionTable_interface.h"
+
+#include <ctype.h>
+
+/**********************************************************************
+ **********************************************************************
+ ***
+ *** Table sessionTable
+ ***
+ **********************************************************************
+ **********************************************************************/
+/*
+ * ACCEL-PPP-MIB::sessionTable is subid 1 of accelPPPSessions.
+ * Its status is Current.
+ * OID: .1.3.6.1.4.1.8072.100.2.1, length: 10
+*/
+typedef struct sessionTable_interface_ctx_s {
+
+ netsnmp_container *container;
+ netsnmp_cache *cache;
+
+ sessionTable_registration * user_ctx;
+
+ netsnmp_table_registration_info tbl_info;
+
+ netsnmp_baby_steps_access_methods access_multiplexer;
+
+} sessionTable_interface_ctx;
+
+static sessionTable_interface_ctx sessionTable_if_ctx;
+
+static void _sessionTable_container_init(
+ sessionTable_interface_ctx *if_ctx);
+static void _sessionTable_container_shutdown(
+ sessionTable_interface_ctx *if_ctx);
+
+
+netsnmp_container *
+sessionTable_container_get( void )
+{
+ return sessionTable_if_ctx.container;
+}
+
+sessionTable_registration *
+sessionTable_registration_get( void )
+{
+ return sessionTable_if_ctx.user_ctx;
+}
+
+sessionTable_registration *
+sessionTable_registration_set( sessionTable_registration * newreg )
+{
+ sessionTable_registration * old = sessionTable_if_ctx.user_ctx;
+ sessionTable_if_ctx.user_ctx = newreg;
+ return old;
+}
+
+int
+sessionTable_container_size( void )
+{
+ return CONTAINER_SIZE(sessionTable_if_ctx.container);
+}
+
+/*
+ * mfd multiplexer modes
+ */
+static Netsnmp_Node_Handler _mfd_sessionTable_pre_request;
+static Netsnmp_Node_Handler _mfd_sessionTable_post_request;
+static Netsnmp_Node_Handler _mfd_sessionTable_object_lookup;
+static Netsnmp_Node_Handler _mfd_sessionTable_get_values;
+/**
+ * @internal
+ * Initialize the table sessionTable
+ * (Define its contents and how it's structured)
+ */
+void
+_sessionTable_initialize_interface(sessionTable_registration * reg_ptr, u_long flags)
+{
+ netsnmp_baby_steps_access_methods *access_multiplexer =
+ &sessionTable_if_ctx.access_multiplexer;
+ netsnmp_table_registration_info *tbl_info = &sessionTable_if_ctx.tbl_info;
+ netsnmp_handler_registration *reginfo;
+ netsnmp_mib_handler *handler;
+ int mfd_modes = 0;
+
+ DEBUGMSGTL(("internal:sessionTable:_sessionTable_initialize_interface","called\n"));
+
+
+ /*************************************************
+ *
+ * save interface context for sessionTable
+ */
+ /*
+ * Setting up the table's definition
+ */
+ netsnmp_table_helper_add_indexes(tbl_info,
+ ASN_OCTET_STR, /** index: sesSID */
+ 0);
+
+ /* Define the minimum and maximum accessible columns. This
+ optimizes retrival. */
+ tbl_info->min_column = SESSIONTABLE_MIN_COL;
+ tbl_info->max_column = SESSIONTABLE_MAX_COL;
+
+ /*
+ * save users context
+ */
+ sessionTable_if_ctx.user_ctx = reg_ptr;
+
+ /*
+ * call data access initialization code
+ */
+ sessionTable_init_data(reg_ptr);
+
+ /*
+ * set up the container
+ */
+ _sessionTable_container_init(&sessionTable_if_ctx);
+ if (NULL == sessionTable_if_ctx.container) {
+ snmp_log(LOG_ERR,"could not initialize container for sessionTable\n");
+ return;
+ }
+
+ /*
+ * access_multiplexer: REQUIRED wrapper for get request handling
+ */
+ access_multiplexer->object_lookup = _mfd_sessionTable_object_lookup;
+ access_multiplexer->get_values = _mfd_sessionTable_get_values;
+
+ /*
+ * no wrappers yet
+ */
+ access_multiplexer->pre_request = _mfd_sessionTable_pre_request;
+ access_multiplexer->post_request = _mfd_sessionTable_post_request;
+
+
+ /*************************************************
+ *
+ * Create a registration, save our reg data, register table.
+ */
+ DEBUGMSGTL(("sessionTable:init_sessionTable",
+ "Registering sessionTable as a mibs-for-dummies table.\n"));
+ handler = netsnmp_baby_steps_access_multiplexer_get(access_multiplexer);
+ reginfo = netsnmp_handler_registration_create("sessionTable", handler,
+ sessionTable_oid,
+ sessionTable_oid_size,
+ HANDLER_CAN_BABY_STEP |
+ HANDLER_CAN_RONLY
+ );
+ if(NULL == reginfo) {
+ snmp_log(LOG_ERR,"error registering table sessionTable\n");
+ return;
+ }
+ reginfo->my_reg_void = &sessionTable_if_ctx;
+
+ /*************************************************
+ *
+ * set up baby steps handler, create it and inject it
+ */
+ if( access_multiplexer->object_lookup )
+ mfd_modes |= BABY_STEP_OBJECT_LOOKUP;
+ if( access_multiplexer->set_values )
+ mfd_modes |= BABY_STEP_SET_VALUES;
+ if( access_multiplexer->irreversible_commit )
+ mfd_modes |= BABY_STEP_IRREVERSIBLE_COMMIT;
+ if( access_multiplexer->object_syntax_checks )
+ mfd_modes |= BABY_STEP_CHECK_OBJECT;
+
+ if( access_multiplexer->pre_request )
+ mfd_modes |= BABY_STEP_PRE_REQUEST;
+ if( access_multiplexer->post_request )
+ mfd_modes |= BABY_STEP_POST_REQUEST;
+
+ if( access_multiplexer->undo_setup )
+ mfd_modes |= BABY_STEP_UNDO_SETUP;
+ if( access_multiplexer->undo_cleanup )
+ mfd_modes |= BABY_STEP_UNDO_CLEANUP;
+ if( access_multiplexer->undo_sets )
+ mfd_modes |= BABY_STEP_UNDO_SETS;
+
+ if( access_multiplexer->row_creation )
+ mfd_modes |= BABY_STEP_ROW_CREATE;
+ if( access_multiplexer->consistency_checks )
+ mfd_modes |= BABY_STEP_CHECK_CONSISTENCY;
+ if( access_multiplexer->commit )
+ mfd_modes |= BABY_STEP_COMMIT;
+ if( access_multiplexer->undo_commit )
+ mfd_modes |= BABY_STEP_UNDO_COMMIT;
+
+ handler = netsnmp_baby_steps_handler_get(mfd_modes);
+ netsnmp_inject_handler(reginfo, handler);
+
+ /*************************************************
+ *
+ * inject row_merge helper with prefix rootoid_len + 2 (entry.col)
+ */
+ handler = netsnmp_get_row_merge_handler(reginfo->rootoid_len + 2);
+ netsnmp_inject_handler(reginfo, handler);
+
+ /*************************************************
+ *
+ * inject container_table helper
+ */
+ handler =
+ netsnmp_container_table_handler_get(tbl_info,
+ sessionTable_if_ctx.container,
+ TABLE_CONTAINER_KEY_NETSNMP_INDEX);
+ netsnmp_inject_handler( reginfo, handler );
+
+ /*************************************************
+ *
+ * inject cache helper
+ */
+ if(NULL != sessionTable_if_ctx.cache) {
+ handler = netsnmp_cache_handler_get(sessionTable_if_ctx.cache);
+ netsnmp_inject_handler( reginfo, handler );
+ }
+
+ /*
+ * register table
+ */
+ netsnmp_register_table(reginfo, tbl_info);
+
+} /* _sessionTable_initialize_interface */
+
+/**
+ * @internal
+ * Shutdown the table sessionTable
+ */
+void
+_sessionTable_shutdown_interface(sessionTable_registration * reg_ptr)
+{
+ /*
+ * shutdown the container
+ */
+ _sessionTable_container_shutdown(&sessionTable_if_ctx);
+}
+
+void
+sessionTable_valid_columns_set(netsnmp_column_info *vc)
+{
+ sessionTable_if_ctx.tbl_info.valid_columns = vc;
+} /* sessionTable_valid_columns_set */
+
+/**
+ * @internal
+ * convert the index component stored in the context to an oid
+ */
+int
+sessionTable_index_to_oid(netsnmp_index *oid_idx,
+ sessionTable_mib_index *mib_idx)
+{
+ int err = SNMP_ERR_NOERROR;
+
+ /*
+ * temp storage for parsing indexes
+ */
+ /*
+ * sesSID(1)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/h
+ */
+ netsnmp_variable_list var_sesSID;
+
+ /*
+ * set up varbinds
+ */
+ memset( &var_sesSID, 0x00, sizeof(var_sesSID) );
+ var_sesSID.type = ASN_OCTET_STR;
+
+ /*
+ * chain temp index varbinds together
+ */
+ var_sesSID.next_variable = NULL;
+
+
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_index_to_oid","called\n"));
+
+ /* sesSID(1)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/h */
+ snmp_set_var_value(&var_sesSID, (u_char*)&mib_idx->sesSID,
+ mib_idx->sesSID_len * sizeof(mib_idx->sesSID[0]));
+
+
+ err = build_oid_noalloc(oid_idx->oids, oid_idx->len, &oid_idx->len,
+ NULL, 0, &var_sesSID);
+ if(err)
+ snmp_log(LOG_ERR,"error %d converting index to oid\n", err);
+
+ /*
+ * parsing may have allocated memory. free it.
+ */
+ snmp_reset_var_buffers( &var_sesSID );
+
+ return err;
+} /* sessionTable_index_to_oid */
+
+/**
+ * extract sessionTable indexes from a netsnmp_index
+ *
+ * @retval SNMP_ERR_NOERROR : no error
+ * @retval SNMP_ERR_GENERR : error
+ */
+int
+sessionTable_index_from_oid(netsnmp_index *oid_idx,
+ sessionTable_mib_index *mib_idx)
+{
+ int err = SNMP_ERR_NOERROR;
+
+ /*
+ * temp storage for parsing indexes
+ */
+ /*
+ * sesSID(1)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/h
+ */
+ netsnmp_variable_list var_sesSID;
+
+ /*
+ * set up varbinds
+ */
+ memset( &var_sesSID, 0x00, sizeof(var_sesSID) );
+ var_sesSID.type = ASN_OCTET_STR;
+
+ /*
+ * chain temp index varbinds together
+ */
+ var_sesSID.next_variable = NULL;
+
+
+ DEBUGMSGTL(("verbose:sessionTable:sessionTable_index_from_oid","called\n"));
+
+ /*
+ * parse the oid into the individual index components
+ */
+ err = parse_oid_indexes( oid_idx->oids, oid_idx->len,
+ &var_sesSID );
+ if (err == SNMP_ERR_NOERROR) {
+ /*
+ * copy out values
+ */
+ /*
+ * NOTE: val_len is in bytes, sesSID_len might not be
+ */
+ if(var_sesSID.val_len > sizeof(mib_idx->sesSID))
+ err = SNMP_ERR_GENERR;
+ else {
+ memcpy(mib_idx->sesSID, var_sesSID.val.string, var_sesSID.val_len);
+ mib_idx->sesSID_len = var_sesSID.val_len / sizeof(mib_idx->sesSID[0]);
+ }
+
+
+ }
+
+ /*
+ * parsing may have allocated memory. free it.
+ */
+ snmp_reset_var_buffers( &var_sesSID );
+
+ return err;
+} /* sessionTable_index_from_oid */
+
+
+/* *********************************************************************
+ * @internal
+ * allocate resources for a sessionTable_rowreq_ctx
+ */
+sessionTable_rowreq_ctx *
+sessionTable_allocate_rowreq_ctx(sessionTable_data *data, void *user_init_ctx)
+{
+ sessionTable_rowreq_ctx *rowreq_ctx =
+ SNMP_MALLOC_TYPEDEF(sessionTable_rowreq_ctx);
+
+ DEBUGMSGTL(("internal:sessionTable:sessionTable_allocate_rowreq_ctx","called\n"));
+
+ if(NULL == rowreq_ctx) {
+ snmp_log(LOG_ERR,"Couldn't allocate memory for a "
+ "sessionTable_rowreq_ctx.\n");
+ return NULL;
+ }
+ else {
+ if(NULL != data) {
+ /*
+ * track if we got data from user
+ */
+ rowreq_ctx->rowreq_flags |= MFD_ROW_DATA_FROM_USER;
+ rowreq_ctx->data = data;
+ }
+ else if (NULL == (rowreq_ctx->data = sessionTable_allocate_data())) {
+ SNMP_FREE(rowreq_ctx);
+ return NULL;
+ }
+ }
+
+ /*
+ * undo context will be allocated when needed (in *_undo_setup)
+ */
+
+ rowreq_ctx->oid_idx.oids = rowreq_ctx->oid_tmp;
+
+ rowreq_ctx->sessionTable_data_list = NULL;
+
+ /*
+ * if we allocated data, call init routine
+ */
+ if (!(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER)) {
+ if(SNMPERR_SUCCESS !=
+ sessionTable_rowreq_ctx_init(rowreq_ctx, user_init_ctx)) {
+ sessionTable_release_rowreq_ctx(rowreq_ctx);
+ rowreq_ctx = NULL;
+ }
+ }
+
+ return rowreq_ctx;
+} /* sessionTable_allocate_rowreq_ctx */
+
+/*
+ * @internal
+ * release resources for a sessionTable_rowreq_ctx
+ */
+void
+sessionTable_release_rowreq_ctx(sessionTable_rowreq_ctx *rowreq_ctx)
+{
+ DEBUGMSGTL(("internal:sessionTable:sessionTable_release_rowreq_ctx","called\n"));
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ sessionTable_rowreq_ctx_cleanup(rowreq_ctx);
+
+ /*
+ * for non-transient data, don't free data we got from the user
+ */
+ if ((rowreq_ctx->data) &&
+ !(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER))
+ sessionTable_release_data(rowreq_ctx->data);
+
+ /*
+ * free index oid pointer
+ */
+ if(rowreq_ctx->oid_idx.oids != rowreq_ctx->oid_tmp)
+ free(rowreq_ctx->oid_idx.oids);
+
+ SNMP_FREE(rowreq_ctx);
+} /* sessionTable_release_rowreq_ctx */
+
+/**
+ * @internal
+ * wrapper
+ */
+static int
+_mfd_sessionTable_pre_request(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *agtreq_info,
+ netsnmp_request_info *requests)
+{
+ int rc;
+
+ DEBUGMSGTL(("internal:sessionTable:_mfd_sessionTable_pre_request",
+ "called\n"));
+
+ if (1 != netsnmp_row_merge_status_first(reginfo, agtreq_info)) {
+ DEBUGMSGTL(("internal:sessionTable",
+ "skipping additional pre_request\n"));
+ return SNMP_ERR_NOERROR;
+ }
+
+ rc = sessionTable_pre_request(sessionTable_if_ctx.user_ctx);
+ if (MFD_SUCCESS != rc) {
+ /*
+ * nothing we can do about it but log it
+ */
+ DEBUGMSGTL(("sessionTable","error %d from "
+ "sessionTable_pre_request\n", rc));
+ netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
+ }
+
+ return SNMP_ERR_NOERROR;
+} /* _mfd_sessionTable_pre_request */
+
+/**
+ * @internal
+ * wrapper
+ */
+static int
+_mfd_sessionTable_post_request(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *agtreq_info,
+ netsnmp_request_info *requests)
+{
+ sessionTable_rowreq_ctx *rowreq_ctx =
+ netsnmp_container_table_row_extract(requests);
+ int rc, packet_rc;
+
+ DEBUGMSGTL(("internal:sessionTable:_mfd_sessionTable_post_request",
+ "called\n"));
+
+ /*
+ * release row context, if deleted
+ */
+ if (rowreq_ctx && (rowreq_ctx->rowreq_flags & MFD_ROW_DELETED))
+ sessionTable_release_rowreq_ctx(rowreq_ctx);
+
+ /*
+ * wait for last call before calling user
+ */
+ if (1 != netsnmp_row_merge_status_last(reginfo, agtreq_info)) {
+ DEBUGMSGTL(("internal:sessionTable",
+ "waiting for last post_request\n"));
+ return SNMP_ERR_NOERROR;
+ }
+
+ packet_rc = netsnmp_check_all_requests_error(agtreq_info->asp, 0);
+ rc = sessionTable_post_request(sessionTable_if_ctx.user_ctx,packet_rc);
+ if (MFD_SUCCESS != rc) {
+ /*
+ * nothing we can do about it but log it
+ */
+ DEBUGMSGTL(("sessionTable","error %d from "
+ "sessionTable_post_request\n", rc));
+ }
+
+ return SNMP_ERR_NOERROR;
+} /* _mfd_sessionTable_post_request */
+
+/**
+ * @internal
+ * wrapper
+ */
+static int
+_mfd_sessionTable_object_lookup(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *agtreq_info,
+ netsnmp_request_info *requests)
+{
+ int rc = SNMP_ERR_NOERROR;
+ sessionTable_rowreq_ctx *rowreq_ctx =
+ netsnmp_container_table_row_extract(requests);
+
+ DEBUGMSGTL(("internal:sessionTable:_mfd_sessionTable_object_lookup","called\n"));
+
+ /*
+ * get our context from mfd
+ * sessionTable_interface_ctx *if_ctx =
+ * (sessionTable_interface_ctx *)reginfo->my_reg_void;
+ */
+
+ if(NULL == rowreq_ctx) {
+ rc = SNMP_ERR_NOCREATION;
+ }
+
+ if (MFD_SUCCESS != rc)
+ netsnmp_request_set_error_all(requests, rc);
+ else
+ sessionTable_row_prep(rowreq_ctx);
+
+ return SNMP_VALIDATE_ERR(rc);
+} /* _mfd_sessionTable_object_lookup */
+
+/***********************************************************************
+ *
+ * GET processing
+ *
+ ***********************************************************************/
+/*
+ * @internal
+ * Retrieve the value for a particular column
+ */
+NETSNMP_STATIC_INLINE int
+_sessionTable_get_column( sessionTable_rowreq_ctx *rowreq_ctx,
+ netsnmp_variable_list *var, int column )
+{
+ int rc = SNMPERR_SUCCESS;
+
+ DEBUGMSGTL(("internal:sessionTable:_mfd_sessionTable_get_column",
+ "called for %d\n", column));
+
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ switch(column) {
+
+ /* (INDEX) sesSID(1)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/h */
+ case COLUMN_SESSID:
+ var->type = ASN_OCTET_STR;
+ /*
+ * NOTE: val_len is in bytes, sesSID_len might not be (e.g. oids)
+ */
+ if (var->val_len < (rowreq_ctx->tbl_idx.sesSID_len *
+ sizeof(rowreq_ctx->tbl_idx.sesSID[0]))) {
+ var->val.string = malloc(rowreq_ctx->tbl_idx.sesSID_len *
+ sizeof(rowreq_ctx->tbl_idx.sesSID[0]));
+ }
+ var->val_len = rowreq_ctx->tbl_idx.sesSID_len * sizeof(rowreq_ctx->tbl_idx.sesSID[0]);
+ memcpy( var->val.string, rowreq_ctx->tbl_idx.sesSID, var->val_len );
+ break;
+
+ /* sesIfName(2)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/r/d/h */
+ case COLUMN_SESIFNAME:
+ var->type = ASN_OCTET_STR;
+rc = sesIfName_get(rowreq_ctx, (char **)&var->val.string, &var->val_len );
+ break;
+
+ /* sesUsername(3)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/r/d/h */
+ case COLUMN_SESUSERNAME:
+ var->type = ASN_OCTET_STR;
+rc = sesUsername_get(rowreq_ctx, (char **)&var->val.string, &var->val_len );
+ break;
+
+ /* sesIP(4)/InetAddressIPv4/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/H */
+ case COLUMN_SESIP:
+ var->type = ASN_OCTET_STR;
+rc = sesIP_get(rowreq_ctx, (char **)&var->val.string, &var->val_len );
+ break;
+
+ /* sesType(5)/INTEGER/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h */
+ case COLUMN_SESTYPE:
+ var->val_len = sizeof(u_long);
+ var->type = ASN_INTEGER;
+rc = sesType_get(rowreq_ctx, (u_long *)var->val.string );
+ break;
+
+ /* sesState(6)/INTEGER/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h */
+ case COLUMN_SESSTATE:
+ var->val_len = sizeof(u_long);
+ var->type = ASN_INTEGER;
+rc = sesState_get(rowreq_ctx, (u_long *)var->val.string );
+ break;
+
+ /* sesUptime(7)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h */
+ case COLUMN_SESUPTIME:
+ var->val_len = sizeof(u_long);
+ var->type = ASN_GAUGE;
+rc = sesUptime_get(rowreq_ctx, (u_long *)var->val.string );
+ break;
+
+ /* sesCallingSID(8)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/r/d/h */
+ case COLUMN_SESCALLINGSID:
+ var->type = ASN_OCTET_STR;
+rc = sesCallingSID_get(rowreq_ctx, (char **)&var->val.string, &var->val_len );
+ break;
+
+ /* sesCalledSID(9)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/r/d/h */
+ case COLUMN_SESCALLEDSID:
+ var->type = ASN_OCTET_STR;
+rc = sesCalledSID_get(rowreq_ctx, (char **)&var->val.string, &var->val_len );
+ break;
+
+ default:
+ if (SESSIONTABLE_MIN_COL <= column && column <= SESSIONTABLE_MAX_COL) {
+ DEBUGMSGTL(("internal:sessionTable:_mfd_sessionTable_get_column",
+ "assume column %d is reserved\n", column));
+ rc = MFD_SKIP;
+ } else {
+ snmp_log(LOG_ERR,
+ "unknown column %d in _sessionTable_get_column\n", column);
+ }
+ break;
+ }
+
+ return rc;
+} /* _sessionTable_get_column */
+
+int
+_mfd_sessionTable_get_values(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *agtreq_info,
+ netsnmp_request_info *requests)
+{
+ sessionTable_rowreq_ctx *rowreq_ctx =
+ netsnmp_container_table_row_extract(requests);
+ netsnmp_table_request_info * tri;
+ u_char * old_string;
+ void (*dataFreeHook)(void *);
+ int rc;
+
+ DEBUGMSGTL(("internal:sessionTable:_mfd_sessionTable_get_values","called\n"));
+
+ netsnmp_assert(NULL != rowreq_ctx);
+
+ for(;requests; requests = requests->next) {
+ /*
+ * save old pointer, so we can free it if replaced
+ */
+ old_string = requests->requestvb->val.string;
+ dataFreeHook = requests->requestvb->dataFreeHook;
+ if(NULL == requests->requestvb->val.string) {
+ requests->requestvb->val.string = requests->requestvb->buf;
+ requests->requestvb->val_len = sizeof(requests->requestvb->buf);
+ }
+ else if(requests->requestvb->buf == requests->requestvb->val.string) {
+ if(requests->requestvb->val_len != sizeof(requests->requestvb->buf))
+ requests->requestvb->val_len = sizeof(requests->requestvb->buf);
+ }
+
+ /*
+ * get column data
+ */
+ tri = netsnmp_extract_table_info(requests);
+ if(NULL == tri)
+ continue;
+
+ rc = _sessionTable_get_column(rowreq_ctx, requests->requestvb, tri->colnum);
+ if(rc) {
+ if(MFD_SKIP == rc) {
+ requests->requestvb->type = SNMP_NOSUCHINSTANCE;
+ rc = SNMP_ERR_NOERROR;
+ }
+ }
+ else if (NULL == requests->requestvb->val.string) {
+ snmp_log(LOG_ERR,"NULL varbind data pointer!\n");
+ rc = SNMP_ERR_GENERR;
+ }
+ if(rc)
+ netsnmp_request_set_error(requests, SNMP_VALIDATE_ERR(rc));
+
+ /*
+ * if the buffer wasn't used previously for the old data (i.e. it
+ * was allcoated memory) and the get routine replaced the pointer,
+ * we need to free the previous pointer.
+ */
+ if(old_string && (old_string != requests->requestvb->buf) &&
+ (requests->requestvb->val.string != old_string)) {
+ if(dataFreeHook)
+ (*dataFreeHook)(old_string);
+ else
+ free(old_string);
+ }
+ } /* for results */
+
+ return SNMP_ERR_NOERROR;
+} /* _mfd_sessionTable_get_values */
+
+
+/***********************************************************************
+ *
+ * SET processing
+ *
+ ***********************************************************************/
+
+/*
+ * SET PROCESSING NOT APPLICABLE (per MIB or user setting)
+ */
+/***********************************************************************
+ *
+ * DATA ACCESS
+ *
+ ***********************************************************************/
+static void _container_free(netsnmp_container *container);
+
+/**
+ * @internal
+ */
+static int
+_cache_load(netsnmp_cache *cache, void *vmagic)
+{
+ DEBUGMSGTL(("internal:sessionTable:_cache_load","called\n"));
+
+ if((NULL == cache) || (NULL == cache->magic)) {
+ snmp_log(LOG_ERR, "invalid cache for sessionTable_cache_load\n");
+ return -1;
+ }
+
+ /** should only be called for an invalid or expired cache */
+ netsnmp_assert((0 == cache->valid) || (1 == cache->expired));
+
+ /*
+ * call user code
+ */
+ return sessionTable_container_load((netsnmp_container*)cache->magic);
+} /* _cache_load */
+
+/**
+ * @internal
+ */
+static void
+_cache_free(netsnmp_cache *cache, void *magic)
+{
+ netsnmp_container *container;
+
+ DEBUGMSGTL(("internal:sessionTable:_cache_free","called\n"));
+
+ if((NULL == cache) || (NULL == cache->magic)) {
+ snmp_log(LOG_ERR, "invalid cache in sessionTable_cache_free\n");
+ return;
+ }
+
+ container = (netsnmp_container*)cache->magic;
+
+ _container_free(container);
+} /* _cache_free */
+
+/**
+ * @internal
+ */
+static void
+_container_item_free(sessionTable_rowreq_ctx *rowreq_ctx, void *context)
+{
+ DEBUGMSGTL(("internal:sessionTable:_container_item_free","called\n"));
+
+ if(NULL == rowreq_ctx)
+ return;
+
+ sessionTable_release_rowreq_ctx(rowreq_ctx);
+} /* _container_item_free */
+
+/**
+ * @internal
+ */
+static void
+_container_free(netsnmp_container *container)
+{
+ DEBUGMSGTL(("internal:sessionTable:_container_free","called\n"));
+
+ if (NULL == container) {
+ snmp_log(LOG_ERR, "invalid container in sessionTable_container_free\n");
+ return;
+ }
+
+ /*
+ * call user code
+ */
+ sessionTable_container_free(container);
+
+ /*
+ * free all items. inefficient, but easy.
+ */
+ CONTAINER_CLEAR(container,
+ (netsnmp_container_obj_func *)_container_item_free,
+ NULL);
+} /* _container_free */
+
+/**
+ * @internal
+ * initialize the container with functions or wrappers
+ */
+void
+_sessionTable_container_init(sessionTable_interface_ctx *if_ctx)
+{
+ DEBUGMSGTL(("internal:sessionTable:_sessionTable_container_init","called\n"));
+
+ /*
+ * cache init
+ */
+ if_ctx->cache = netsnmp_cache_create(30, /* timeout in seconds */
+ _cache_load, _cache_free,
+ sessionTable_oid,
+ sessionTable_oid_size);
+
+ if(NULL == if_ctx->cache) {
+ snmp_log(LOG_ERR, "error creating cache for sessionTable\n");
+ return;
+ }
+
+ if_ctx->cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;
+
+ sessionTable_container_init(&if_ctx->container, if_ctx->cache);
+ if(NULL == if_ctx->container)
+ if_ctx->container = netsnmp_container_find("sessionTable:table_container");
+ if(NULL == if_ctx->container) {
+ snmp_log(LOG_ERR,"error creating container in "
+ "sessionTable_container_init\n");
+ return;
+ }
+
+ if (NULL != if_ctx->cache)
+ if_ctx->cache->magic = (void*)if_ctx->container;
+} /* _sessionTable_container_init */
+
+/**
+ * @internal
+ * shutdown the container with functions or wrappers
+ */
+void
+_sessionTable_container_shutdown(sessionTable_interface_ctx *if_ctx)
+{
+ DEBUGMSGTL(("internal:sessionTable:_sessionTable_container_shutdown","called\n"));
+
+ sessionTable_container_shutdown(if_ctx->container);
+
+ _container_free(if_ctx->container);
+
+} /* _sessionTable_container_shutdown */
+
+
+sessionTable_rowreq_ctx *
+sessionTable_row_find_by_mib_index(sessionTable_mib_index *mib_idx)
+{
+ sessionTable_rowreq_ctx *rowreq_ctx;
+ oid oid_tmp[MAX_OID_LEN];
+ netsnmp_index oid_idx;
+ int rc;
+
+ /*
+ * set up storage for OID
+ */
+ oid_idx.oids = oid_tmp;
+ oid_idx.len = sizeof(oid_tmp)/sizeof(oid);
+
+ /*
+ * convert
+ */
+ rc = sessionTable_index_to_oid(&oid_idx, mib_idx);
+ if (MFD_SUCCESS != rc)
+ return NULL;
+
+ rowreq_ctx = CONTAINER_FIND(sessionTable_if_ctx.container, &oid_idx);
+
+ return rowreq_ctx;
+}
+
diff --git a/accel-pppd/extra/net-snmp/sessionTable_interface.h b/accel-pppd/extra/net-snmp/sessionTable_interface.h
new file mode 100644
index 0000000..ebd1143
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/sessionTable_interface.h
@@ -0,0 +1,84 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * version : 15899 $ of $
+ *
+ * $Id:$
+ */
+/** @ingroup interface: Routines to interface to Net-SNMP
+ *
+ * \warning This code should not be modified, called directly,
+ * or used to interpret functionality. It is subject to
+ * change at any time.
+ *
+ * @{
+ */
+/*
+ * *********************************************************************
+ * *********************************************************************
+ * *********************************************************************
+ * *** ***
+ * *** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ***
+ * *** ***
+ * *** ***
+ * *** THIS FILE DOES NOT CONTAIN ANY USER EDITABLE CODE. ***
+ * *** ***
+ * *** ***
+ * *** THE GENERATED CODE IS INTERNAL IMPLEMENTATION, AND ***
+ * *** ***
+ * *** ***
+ * *** IS SUBJECT TO CHANGE WITHOUT WARNING IN FUTURE RELEASES. ***
+ * *** ***
+ * *** ***
+ * *********************************************************************
+ * *********************************************************************
+ * *********************************************************************
+ */
+#ifndef SESSIONTABLE_INTERFACE_H
+#define SESSIONTABLE_INTERFACE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "sessionTable.h"
+
+
+/* ********************************************************************
+ * Table declarations
+ */
+
+/* PUBLIC interface initialization routine */
+void _sessionTable_initialize_interface(sessionTable_registration * user_ctx,
+ u_long flags);
+void _sessionTable_shutdown_interface(sessionTable_registration * user_ctx);
+
+sessionTable_registration *
+sessionTable_registration_get( void );
+
+sessionTable_registration *
+sessionTable_registration_set( sessionTable_registration * newreg );
+
+netsnmp_container *sessionTable_container_get( void );
+int sessionTable_container_size( void );
+
+ sessionTable_rowreq_ctx * sessionTable_allocate_rowreq_ctx(sessionTable_data *, void *);
+void sessionTable_release_rowreq_ctx(sessionTable_rowreq_ctx *rowreq_ctx);
+
+int sessionTable_index_to_oid(netsnmp_index *oid_idx,
+ sessionTable_mib_index *mib_idx);
+int sessionTable_index_from_oid(netsnmp_index *oid_idx,
+ sessionTable_mib_index *mib_idx);
+
+/*
+ * access to certain internals. use with caution!
+ */
+void sessionTable_valid_columns_set(netsnmp_column_info *vc);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SESSIONTABLE_INTERFACE_H */
+/** @} */
diff --git a/accel-pppd/extra/net-snmp/sessionTable_oids.h b/accel-pppd/extra/net-snmp/sessionTable_oids.h
new file mode 100644
index 0000000..42ec6e5
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/sessionTable_oids.h
@@ -0,0 +1,46 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : generic-table-oids.m2c 12855 2005-09-27 15:56:08Z rstory $
+ *
+ * $Id:$
+ */
+#ifndef SESSIONTABLE_OIDS_H
+#define SESSIONTABLE_OIDS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* column number definitions for table sessionTable */
+#define SESSIONTABLE_OID 1,3,6,1,4,1,8072,100,2,1
+
+#define COLUMN_SESSID 1
+
+#define COLUMN_SESIFNAME 2
+
+#define COLUMN_SESUSERNAME 3
+
+#define COLUMN_SESIP 4
+
+#define COLUMN_SESTYPE 5
+
+#define COLUMN_SESSTATE 6
+
+#define COLUMN_SESUPTIME 7
+
+#define COLUMN_SESCALLINGSID 8
+
+#define COLUMN_SESCALLEDSID 9
+
+
+#define SESSIONTABLE_MIN_COL COLUMN_SESSID
+#define SESSIONTABLE_MAX_COL COLUMN_SESCALLEDSID
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SESSIONTABLE_OIDS_H */
diff --git a/accel-pppd/extra/net-snmp/shutdown.c b/accel-pppd/extra/net-snmp/shutdown.c
new file mode 100644
index 0000000..82f8540
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/shutdown.c
@@ -0,0 +1,88 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.scalar.conf 11805 2005-01-07 09:37:18Z dts12 $
+ */
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include "shutdown.h"
+
+/** Initializes the shutdown module */
+void
+init_shutdown(void)
+{
+ static oid shutdown_oid[] = { 1,3,6,1,4,1,8072,100,3,2 };
+
+ DEBUGMSGTL(("shutdown", "Initializing\n"));
+
+ netsnmp_register_scalar(
+ netsnmp_create_handler_registration("shutdown", handle_shutdown,
+ shutdown_oid, OID_LENGTH(shutdown_oid),
+ HANDLER_CAN_RWRITE
+ ));
+}
+
+int
+handle_shutdown(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ int ret;
+ /* We are never called for a GETNEXT if it's registered as a
+ "instance", as it's "magically" handled for us. */
+
+ /* a instance handler also only hands us one request at a time, so
+ we don't need to loop over a list of requests; we'll only get one. */
+
+ switch(reqinfo->mode) {
+
+ case MODE_GET:
+ netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHINSTANCE );
+ break;
+
+ /*
+ * SET REQUEST
+ *
+ * multiple states in the transaction. See:
+ * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg
+ */
+ case MODE_SET_RESERVE1:
+ /* or you could use netsnmp_check_vb_type_and_size instead */
+ ret = netsnmp_check_vb_type(requests->requestvb, ASN_INTEGER);
+ if ( ret != SNMP_ERR_NOERROR ) {
+ netsnmp_set_request_error(reqinfo, requests, ret );
+ }
+ break;
+
+ case MODE_SET_RESERVE2:
+ /* XXX malloc "undo" storage buffer */
+ break;
+
+ case MODE_SET_FREE:
+ /* XXX: free resources allocated in RESERVE1 and/or
+ RESERVE2. Something failed somewhere, and the states
+ below won't be called. */
+ break;
+
+ case MODE_SET_ACTION:
+ /* XXX: perform the value change here */
+ break;
+
+ case MODE_SET_COMMIT:
+ /* XXX: delete temporary storage */
+ break;
+
+ case MODE_SET_UNDO:
+ /* XXX: UNDO and return to previous value for the object */
+ break;
+
+ default:
+ /* we should never get here, so this is a really bad error */
+ snmp_log(LOG_ERR, "unknown mode (%d) in handle_shutdown\n", reqinfo->mode );
+ return SNMP_ERR_GENERR;
+ }
+
+ return SNMP_ERR_NOERROR;
+}
diff --git a/accel-pppd/extra/net-snmp/shutdown.h b/accel-pppd/extra/net-snmp/shutdown.h
new file mode 100644
index 0000000..02bda94
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/shutdown.h
@@ -0,0 +1,12 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.scalar.conf 11805 2005-01-07 09:37:18Z dts12 $
+ */
+#ifndef SHUTDOWN_H
+#define SHUTDOWN_H
+
+/* function declarations */
+void init_shutdown(void);
+Netsnmp_Node_Handler handle_shutdown;
+
+#endif /* SHUTDOWN_H */
diff --git a/accel-pppd/extra/net-snmp/statCore.c b/accel-pppd/extra/net-snmp/statCore.c
new file mode 100644
index 0000000..74a6b35
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/statCore.c
@@ -0,0 +1,147 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.scalar.conf 11805 2005-01-07 09:37:18Z dts12 $
+ */
+
+#include <time.h>
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#include "triton.h"
+#include "statCore.h"
+
+/** Initializes the statCore module */
+void
+init_statCore(void)
+{
+ static oid statCoreUpTime_oid[] = { 1,3,6,1,4,1,8072,100,1,1,1 };
+ static oid statCoreCPU_oid[] = { 1,3,6,1,4,1,8072,100,1,1,2 };
+ static oid statCoreMemRss_oid[] = { 1,3,6,1,4,1,8072,100,1,1,3 };
+
+ DEBUGMSGTL(("statCore", "Initializing\n"));
+
+ netsnmp_register_scalar(
+ netsnmp_create_handler_registration("statCoreUpTime", handle_statCoreUpTime,
+ statCoreUpTime_oid, OID_LENGTH(statCoreUpTime_oid),
+ HANDLER_CAN_RONLY
+ ));
+ netsnmp_register_scalar(
+ netsnmp_create_handler_registration("statCoreCPU", handle_statCoreCPU,
+ statCoreCPU_oid, OID_LENGTH(statCoreCPU_oid),
+ HANDLER_CAN_RONLY
+ ));
+ netsnmp_register_scalar(
+ netsnmp_create_handler_registration("statCoreMemRss", handle_statCoreMemRss,
+ statCoreMemRss_oid, OID_LENGTH(statCoreMemRss_oid),
+ HANDLER_CAN_RONLY
+ ));
+}
+
+int
+handle_statCoreUpTime(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ struct timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ ts.tv_sec -= triton_stat.start_time;
+
+ /* We are never called for a GETNEXT if it's registered as a
+ "instance", as it's "magically" handled for us. */
+
+ /* a instance handler also only hands us one request at a time, so
+ we don't need to loop over a list of requests; we'll only get one. */
+
+ switch(reqinfo->mode) {
+
+ case MODE_GET:
+ snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE,
+ (u_char *)&ts.tv_sec /* XXX: a pointer to the scalar's data */,
+ sizeof(ts.tv_sec)/* XXX: the length of the data in bytes */);
+ break;
+
+
+ default:
+ /* we should never get here, so this is a really bad error */
+ snmp_log(LOG_ERR, "unknown mode (%d) in handle_statCoreUpTime\n", reqinfo->mode );
+ return SNMP_ERR_GENERR;
+ }
+
+ return SNMP_ERR_NOERROR;
+}
+int
+handle_statCoreCPU(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ /* We are never called for a GETNEXT if it's registered as a
+ "instance", as it's "magically" handled for us. */
+
+ /* a instance handler also only hands us one request at a time, so
+ we don't need to loop over a list of requests; we'll only get one. */
+
+ switch(reqinfo->mode) {
+
+ case MODE_GET:
+ snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
+ (u_char *)&triton_stat.cpu /* XXX: a pointer to the scalar's data */,
+ sizeof(triton_stat.cpu)/* XXX: the length of the data in bytes */);
+ break;
+
+
+ default:
+ /* we should never get here, so this is a really bad error */
+ snmp_log(LOG_ERR, "unknown mode (%d) in handle_statCoreCPU\n", reqinfo->mode );
+ return SNMP_ERR_GENERR;
+ }
+
+ return SNMP_ERR_NOERROR;
+}
+int
+handle_statCoreMemRss(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ char statm_fname[128];
+ FILE *f;
+ unsigned long vmsize = 0, vmrss = 0;
+ unsigned long page_size = sysconf(_SC_PAGE_SIZE);
+
+ sprintf(statm_fname, "/proc/%i/statm", getpid());
+ f = fopen(statm_fname, "r");
+ if (f) {
+ fscanf(f, "%lu %lu", &vmsize, &vmrss);
+ fclose(f);
+ }
+
+ vmrss *= page_size;
+
+ /* We are never called for a GETNEXT if it's registered as a
+ "instance", as it's "magically" handled for us. */
+
+ /* a instance handler also only hands us one request at a time, so
+ we don't need to loop over a list of requests; we'll only get one. */
+
+ switch(reqinfo->mode) {
+
+ case MODE_GET:
+ snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
+ (u_char *)&vmrss /* XXX: a pointer to the scalar's data */,
+ sizeof(vmrss)/* XXX: the length of the data in bytes */);
+ break;
+
+
+ default:
+ /* we should never get here, so this is a really bad error */
+ snmp_log(LOG_ERR, "unknown mode (%d) in handle_statCoreMemRss\n", reqinfo->mode );
+ return SNMP_ERR_GENERR;
+ }
+
+ return SNMP_ERR_NOERROR;
+}
diff --git a/accel-pppd/extra/net-snmp/statCore.h b/accel-pppd/extra/net-snmp/statCore.h
new file mode 100644
index 0000000..1a09685
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/statCore.h
@@ -0,0 +1,14 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.scalar.conf 11805 2005-01-07 09:37:18Z dts12 $
+ */
+#ifndef STATCORE_H
+#define STATCORE_H
+
+/* function declarations */
+void init_statCore(void);
+Netsnmp_Node_Handler handle_statCoreUpTime;
+Netsnmp_Node_Handler handle_statCoreCPU;
+Netsnmp_Node_Handler handle_statCoreMemRss;
+
+#endif /* STATCORE_H */
diff --git a/accel-pppd/extra/net-snmp/statL2TP.c b/accel-pppd/extra/net-snmp/statL2TP.c
new file mode 100644
index 0000000..a91d336
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/statL2TP.c
@@ -0,0 +1,94 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.int_watch.conf 13957 2005-12-20 15:33:08Z tanders $
+ */
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#include "triton.h"
+#include "statL2TP.h"
+
+
+/*
+ * The variables we want to tie the relevant OIDs to.
+ * The agent will handle all GET and (if applicable) SET requests
+ * to these variables automatically, changing the values as needed.
+ */
+
+void l2tp_get_stat(unsigned int **, unsigned int **);
+
+static unsigned int *stat_starting;
+static unsigned int *stat_active;
+
+/*
+ * Our initialization routine, called automatically by the agent
+ * (Note that the function name must match init_FILENAME())
+ */
+void
+init_statL2TP(void)
+{
+ netsnmp_handler_registration *reg;
+ netsnmp_watcher_info *winfo;
+
+ static oid statL2TPStarting_oid[] = { 1,3,6,1,4,1,8072,100,1,4,1 };
+ static oid statL2TPActive_oid[] = { 1,3,6,1,4,1,8072,100,1,4,2 };
+
+ /*
+ * a debugging statement. Run the agent with -DstatL2TP to see
+ * the output of this debugging statement.
+ */
+ DEBUGMSGTL(("statL2TP", "Initializing the statL2TP module\n"));
+
+ if (!triton_module_loaded("l2tp"))
+ return;
+
+ l2tp_get_stat(&stat_starting, &stat_active);
+
+ /*
+ * Register scalar watchers for each of the MIB objects.
+ * The ASN type and RO/RW status are taken from the MIB definition,
+ * but can be adjusted if needed.
+ *
+ * In most circumstances, the scalar watcher will handle all
+ * of the necessary processing. But the NULL parameter in the
+ * netsnmp_create_handler_registration() call can be used to
+ * supply a user-provided handler if necessary.
+ *
+ * This approach can also be used to handle Counter64, string-
+ * and OID-based watched scalars (although variable-sized writeable
+ * objects will need some more specialised initialisation).
+ */
+ DEBUGMSGTL(("statL2TP",
+ "Initializing statL2TPStarting scalar integer. Default value = %d\n",
+ 0));
+ reg = netsnmp_create_handler_registration(
+ "statL2TPStarting", NULL,
+ statL2TPStarting_oid, OID_LENGTH(statL2TPStarting_oid),
+ HANDLER_CAN_RONLY);
+ winfo = netsnmp_create_watcher_info(
+ stat_starting, sizeof(*stat_starting),
+ ASN_INTEGER, WATCHER_FIXED_SIZE);
+ if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) {
+ snmp_log( LOG_ERR, "Failed to register watched statL2TPStarting" );
+ }
+
+ DEBUGMSGTL(("statL2TP",
+ "Initializing statL2TPActive scalar integer. Default value = %d\n",
+ 0));
+ reg = netsnmp_create_handler_registration(
+ "statL2TPActive", NULL,
+ statL2TPActive_oid, OID_LENGTH(statL2TPActive_oid),
+ HANDLER_CAN_RONLY);
+ winfo = netsnmp_create_watcher_info(
+ stat_active, sizeof(*stat_active),
+ ASN_INTEGER, WATCHER_FIXED_SIZE);
+ if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) {
+ snmp_log( LOG_ERR, "Failed to register watched statL2TPActive" );
+ }
+
+
+ DEBUGMSGTL(("statL2TP",
+ "Done initalizing statL2TP module\n"));
+}
diff --git a/accel-pppd/extra/net-snmp/statL2TP.h b/accel-pppd/extra/net-snmp/statL2TP.h
new file mode 100644
index 0000000..e038906
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/statL2TP.h
@@ -0,0 +1,11 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.int_watch.conf 13957 2005-12-20 15:33:08Z tanders $
+ */
+#ifndef STATL2TP_H
+#define STATL2TP_H
+
+/* function declarations */
+void init_statL2TP(void);
+
+#endif /* STATL2TP_H */
diff --git a/accel-pppd/extra/net-snmp/statPPP.c b/accel-pppd/extra/net-snmp/statPPP.c
new file mode 100644
index 0000000..7199b57
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/statPPP.c
@@ -0,0 +1,93 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.int_watch.conf 13957 2005-12-20 15:33:08Z tanders $
+ */
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include "statPPP.h"
+
+#include "ppp.h"
+
+/*
+ * Our initialization routine, called automatically by the agent
+ * (Note that the function name must match init_FILENAME())
+ */
+void
+init_statPPP(void)
+{
+ netsnmp_handler_registration *reg;
+ netsnmp_watcher_info *winfo;
+
+ static oid statPPPStarting_oid[] = { 1,3,6,1,4,1,8072,100,1,2,1 };
+ static oid statPPPActive_oid[] = { 1,3,6,1,4,1,8072,100,1,2,2 };
+ static oid statPPPFinishing_oid[] = { 1,3,6,1,4,1,8072,100,1,2,3 };
+
+ /*
+ * a debugging statement. Run the agent with -DstatPPP to see
+ * the output of this debugging statement.
+ */
+ DEBUGMSGTL(("statPPP", "Initializing the statPPP module\n"));
+
+
+ /*
+ * Register scalar watchers for each of the MIB objects.
+ * The ASN type and RO/RW status are taken from the MIB definition,
+ * but can be adjusted if needed.
+ *
+ * In most circumstances, the scalar watcher will handle all
+ * of the necessary processing. But the NULL parameter in the
+ * netsnmp_create_handler_registration() call can be used to
+ * supply a user-provided handler if necessary.
+ *
+ * This approach can also be used to handle Counter64, string-
+ * and OID-based watched scalars (although variable-sized writeable
+ * objects will need some more specialised initialisation).
+ */
+ DEBUGMSGTL(("statPPP",
+ "Initializing statPPPStarting scalar integer. Default value = %d\n",
+ 0));
+ reg = netsnmp_create_handler_registration(
+ "statPPPStarting", NULL,
+ statPPPStarting_oid, OID_LENGTH(statPPPStarting_oid),
+ HANDLER_CAN_RONLY);
+ winfo = netsnmp_create_watcher_info(
+ &ppp_stat.starting, sizeof(ppp_stat.starting),
+ ASN_INTEGER, WATCHER_FIXED_SIZE);
+ if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) {
+ snmp_log( LOG_ERR, "Failed to register watched statPPPStarting" );
+ }
+
+ DEBUGMSGTL(("statPPP",
+ "Initializing statPPPActive scalar integer. Default value = %d\n",
+ 0));
+ reg = netsnmp_create_handler_registration(
+ "statPPPActive", NULL,
+ statPPPActive_oid, OID_LENGTH(statPPPActive_oid),
+ HANDLER_CAN_RONLY);
+ winfo = netsnmp_create_watcher_info(
+ &ppp_stat.active, sizeof(ppp_stat.active),
+ ASN_INTEGER, WATCHER_FIXED_SIZE);
+ if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) {
+ snmp_log( LOG_ERR, "Failed to register watched statPPPActive" );
+ }
+
+ DEBUGMSGTL(("statPPP",
+ "Initializing statPPPFinishing scalar integer. Default value = %d\n",
+ 0));
+ reg = netsnmp_create_handler_registration(
+ "statPPPFinishing", NULL,
+ statPPPFinishing_oid, OID_LENGTH(statPPPFinishing_oid),
+ HANDLER_CAN_RONLY);
+ winfo = netsnmp_create_watcher_info(
+ &ppp_stat.finishing, sizeof(ppp_stat.finishing),
+ ASN_INTEGER, WATCHER_FIXED_SIZE);
+ if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) {
+ snmp_log( LOG_ERR, "Failed to register watched statPPPFinishing" );
+ }
+
+
+ DEBUGMSGTL(("statPPP",
+ "Done initalizing statPPP module\n"));
+}
diff --git a/accel-pppd/extra/net-snmp/statPPP.h b/accel-pppd/extra/net-snmp/statPPP.h
new file mode 100644
index 0000000..15a1bf3
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/statPPP.h
@@ -0,0 +1,11 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.int_watch.conf 13957 2005-12-20 15:33:08Z tanders $
+ */
+#ifndef STATPPP_H
+#define STATPPP_H
+
+/* function declarations */
+void init_statPPP(void);
+
+#endif /* STATPPP_H */
diff --git a/accel-pppd/extra/net-snmp/statPPPOE.c b/accel-pppd/extra/net-snmp/statPPPOE.c
new file mode 100644
index 0000000..0ca2dd8
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/statPPPOE.c
@@ -0,0 +1,93 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.int_watch.conf 13957 2005-12-20 15:33:08Z tanders $
+ */
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#include "triton.h"
+#include "statPPPOE.h"
+
+/*
+ * The variables we want to tie the relevant OIDs to.
+ * The agent will handle all GET and (if applicable) SET requests
+ * to these variables automatically, changing the values as needed.
+ */
+
+void pppoe_get_stat(unsigned int **, unsigned int **);
+
+static unsigned int *stat_starting;
+static unsigned int *stat_active;
+
+/*
+ * Our initialization routine, called automatically by the agent
+ * (Note that the function name must match init_FILENAME())
+ */
+void
+init_statPPPOE(void)
+{
+ netsnmp_handler_registration *reg;
+ netsnmp_watcher_info *winfo;
+
+ static oid statPPPOEStarting_oid[] = { 1,3,6,1,4,1,8072,100,1,5,1 };
+ static oid statPPPOEActive_oid[] = { 1,3,6,1,4,1,8072,100,1,5,2 };
+
+ /*
+ * a debugging statement. Run the agent with -DstatPPPOE to see
+ * the output of this debugging statement.
+ */
+ DEBUGMSGTL(("statPPPOE", "Initializing the statPPPOE module\n"));
+
+ if (!triton_module_loaded("pppoe"))
+ return;
+
+ pppoe_get_stat(&stat_starting, &stat_active);
+
+ /*
+ * Register scalar watchers for each of the MIB objects.
+ * The ASN type and RO/RW status are taken from the MIB definition,
+ * but can be adjusted if needed.
+ *
+ * In most circumstances, the scalar watcher will handle all
+ * of the necessary processing. But the NULL parameter in the
+ * netsnmp_create_handler_registration() call can be used to
+ * supply a user-provided handler if necessary.
+ *
+ * This approach can also be used to handle Counter64, string-
+ * and OID-based watched scalars (although variable-sized writeable
+ * objects will need some more specialised initialisation).
+ */
+ DEBUGMSGTL(("statPPPOE",
+ "Initializing statPPPOEStarting scalar integer. Default value = %d\n",
+ 0));
+ reg = netsnmp_create_handler_registration(
+ "statPPPOEStarting", NULL,
+ statPPPOEStarting_oid, OID_LENGTH(statPPPOEStarting_oid),
+ HANDLER_CAN_RONLY);
+ winfo = netsnmp_create_watcher_info(
+ stat_starting, sizeof(*stat_starting),
+ ASN_INTEGER, WATCHER_FIXED_SIZE);
+ if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) {
+ snmp_log( LOG_ERR, "Failed to register watched statPPPOEStarting" );
+ }
+
+ DEBUGMSGTL(("statPPPOE",
+ "Initializing statPPPOEActive scalar integer. Default value = %d\n",
+ 0));
+ reg = netsnmp_create_handler_registration(
+ "statPPPOEActive", NULL,
+ statPPPOEActive_oid, OID_LENGTH(statPPPOEActive_oid),
+ HANDLER_CAN_RONLY);
+ winfo = netsnmp_create_watcher_info(
+ stat_active, sizeof(*stat_active),
+ ASN_INTEGER, WATCHER_FIXED_SIZE);
+ if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) {
+ snmp_log( LOG_ERR, "Failed to register watched statPPPOEActive" );
+ }
+
+
+ DEBUGMSGTL(("statPPPOE",
+ "Done initalizing statPPPOE module\n"));
+}
diff --git a/accel-pppd/extra/net-snmp/statPPPOE.h b/accel-pppd/extra/net-snmp/statPPPOE.h
new file mode 100644
index 0000000..bb0bcc0
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/statPPPOE.h
@@ -0,0 +1,11 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.int_watch.conf 13957 2005-12-20 15:33:08Z tanders $
+ */
+#ifndef STATPPPOE_H
+#define STATPPPOE_H
+
+/* function declarations */
+void init_statPPPOE(void);
+
+#endif /* STATPPPOE_H */
diff --git a/accel-pppd/extra/net-snmp/statPPTP.c b/accel-pppd/extra/net-snmp/statPPTP.c
new file mode 100644
index 0000000..1a13ad0
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/statPPTP.c
@@ -0,0 +1,92 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.int_watch.conf 13957 2005-12-20 15:33:08Z tanders $
+ */
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include "statPPTP.h"
+
+#include "triton.h"
+
+/*
+ * The variables we want to tie the relevant OIDs to.
+ * The agent will handle all GET and (if applicable) SET requests
+ * to these variables automatically, changing the values as needed.
+ */
+
+void pptp_get_stat(unsigned int **, unsigned int **);
+
+static unsigned int *stat_starting;
+static unsigned int *stat_active;
+
+/*
+ * Our initialization routine, called automatically by the agent
+ * (Note that the function name must match init_FILENAME())
+ */
+void
+init_statPPTP(void)
+{
+ netsnmp_handler_registration *reg;
+ netsnmp_watcher_info *winfo;
+
+ static oid statPPTPStarting_oid[] = { 1,3,6,1,4,1,8072,100,1,3,1 };
+ static oid statPPTPActive_oid[] = { 1,3,6,1,4,1,8072,100,1,3,2 };
+
+ /*
+ * a debugging statement. Run the agent with -DstatPPTP to see
+ * the output of this debugging statement.
+ */
+ DEBUGMSGTL(("statPPTP", "Initializing the statPPTP module\n"));
+
+ if (!triton_module_loaded("pptp"))
+ return;
+
+ pptp_get_stat(&stat_starting, &stat_active);
+ /*
+ * Register scalar watchers for each of the MIB objects.
+ * The ASN type and RO/RW status are taken from the MIB definition,
+ * but can be adjusted if needed.
+ *
+ * In most circumstances, the scalar watcher will handle all
+ * of the necessary processing. But the NULL parameter in the
+ * netsnmp_create_handler_registration() call can be used to
+ * supply a user-provided handler if necessary.
+ *
+ * This approach can also be used to handle Counter64, string-
+ * and OID-based watched scalars (although variable-sized writeable
+ * objects will need some more specialised initialisation).
+ */
+ DEBUGMSGTL(("statPPTP",
+ "Initializing statPPTPStarting scalar integer. Default value = %d\n",
+ 0));
+ reg = netsnmp_create_handler_registration(
+ "statPPTPStarting", NULL,
+ statPPTPStarting_oid, OID_LENGTH(statPPTPStarting_oid),
+ HANDLER_CAN_RONLY);
+ winfo = netsnmp_create_watcher_info(
+ stat_starting, sizeof(*stat_starting),
+ ASN_INTEGER, WATCHER_FIXED_SIZE);
+ if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) {
+ snmp_log( LOG_ERR, "Failed to register watched statPPTPStarting" );
+ }
+
+ DEBUGMSGTL(("statPPTP",
+ "Initializing statPPTPActive scalar integer. Default value = %d\n",
+ 0));
+ reg = netsnmp_create_handler_registration(
+ "statPPTPActive", NULL,
+ statPPTPActive_oid, OID_LENGTH(statPPTPActive_oid),
+ HANDLER_CAN_RONLY);
+ winfo = netsnmp_create_watcher_info(
+ stat_active, sizeof(*stat_active),
+ ASN_INTEGER, WATCHER_FIXED_SIZE);
+ if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) {
+ snmp_log( LOG_ERR, "Failed to register watched statPPTPActive" );
+ }
+
+
+ DEBUGMSGTL(("statPPTP",
+ "Done initalizing statPPTP module\n"));
+}
diff --git a/accel-pppd/extra/net-snmp/statPPTP.h b/accel-pppd/extra/net-snmp/statPPTP.h
new file mode 100644
index 0000000..d3a9e0a
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/statPPTP.h
@@ -0,0 +1,11 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.int_watch.conf 13957 2005-12-20 15:33:08Z tanders $
+ */
+#ifndef STATPPTP_H
+#define STATPPTP_H
+
+/* function declarations */
+void init_statPPTP(void);
+
+#endif /* STATPPTP_H */
diff --git a/accel-pppd/extra/net-snmp/terminate.c b/accel-pppd/extra/net-snmp/terminate.c
new file mode 100644
index 0000000..bd38577
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/terminate.c
@@ -0,0 +1,379 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.scalar.conf 11805 2005-01-07 09:37:18Z dts12 $
+ */
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#include "triton.h"
+#include "ppp.h"
+
+#include "terminate.h"
+
+static void __terminate(struct ppp_t *ppp)
+{
+ ppp_terminate(ppp, TERM_ADMIN_RESET, 0);
+}
+
+static void terminate_by_sid(const char *val)
+{
+ struct ppp_t *ppp;
+
+ pthread_rwlock_rdlock(&ppp_lock);
+ list_for_each_entry(ppp, &ppp_list, entry) {
+ if (strncmp(ppp->sessionid, val, PPP_SESSIONID_LEN))
+ continue;
+ triton_context_call(ppp->ctrl->ctx, (triton_event_func)__terminate, ppp);
+ break;
+ }
+ pthread_rwlock_unlock(&ppp_lock);
+}
+
+static void terminate_by_ifname(const char *val, size_t len)
+{
+ struct ppp_t *ppp;
+ size_t n;
+
+ pthread_rwlock_rdlock(&ppp_lock);
+ list_for_each_entry(ppp, &ppp_list, entry) {
+ n = strlen(ppp->ifname);
+ if (n != len)
+ continue;
+ if (strncmp(ppp->ifname, val, len))
+ continue;
+ triton_context_call(ppp->ctrl->ctx, (triton_event_func)__terminate, ppp);
+ break;
+ }
+ pthread_rwlock_unlock(&ppp_lock);
+}
+
+static void terminate_by_ip(const char *val, size_t len)
+{
+ char str[len + 1];
+ in_addr_t addr;
+ struct ppp_t *ppp;
+
+ strncpy(str, val, len);
+ str[len] = 0;
+
+ addr = inet_addr(str);
+
+ pthread_rwlock_rdlock(&ppp_lock);
+ list_for_each_entry(ppp, &ppp_list, entry) {
+ if (ppp->peer_ipaddr != addr)
+ continue;
+ triton_context_call(ppp->ctrl->ctx, (triton_event_func)__terminate, ppp);
+ break;
+ }
+ pthread_rwlock_unlock(&ppp_lock);
+}
+
+static void terminate_by_username(const char *val, size_t len)
+{
+ struct ppp_t *ppp;
+ size_t n;
+
+ pthread_rwlock_rdlock(&ppp_lock);
+ list_for_each_entry(ppp, &ppp_list, entry) {
+ if (!ppp->username)
+ continue;
+ n = strlen(ppp->username);
+ if (n != len)
+ continue;
+ if (strncmp(ppp->username, val, len))
+ continue;
+ triton_context_call(ppp->ctrl->ctx, (triton_event_func)__terminate, ppp);
+ }
+ pthread_rwlock_unlock(&ppp_lock);
+}
+
+
+/** Initializes the terminate module */
+void
+init_terminate(void)
+{
+ static oid termBySID_oid[] = { 1,3,6,1,4,1,8072,100,3,1,1 };
+ static oid termByIfName_oid[] = { 1,3,6,1,4,1,8072,100,3,1,2 };
+ static oid termByIP_oid[] = { 1,3,6,1,4,1,8072,100,3,1,3 };
+ static oid termByUsername_oid[] = { 1,3,6,1,4,1,8072,100,3,1,4 };
+
+ DEBUGMSGTL(("terminate", "Initializing\n"));
+
+ netsnmp_register_scalar(
+ netsnmp_create_handler_registration("termBySID", handle_termBySID,
+ termBySID_oid, OID_LENGTH(termBySID_oid),
+ HANDLER_CAN_RWRITE
+ ));
+ netsnmp_register_scalar(
+ netsnmp_create_handler_registration("termByIfName", handle_termByIfName,
+ termByIfName_oid, OID_LENGTH(termByIfName_oid),
+ HANDLER_CAN_RWRITE
+ ));
+ netsnmp_register_scalar(
+ netsnmp_create_handler_registration("termByIP", handle_termByIP,
+ termByIP_oid, OID_LENGTH(termByIP_oid),
+ HANDLER_CAN_RWRITE
+ ));
+ netsnmp_register_scalar(
+ netsnmp_create_handler_registration("termByUsername", handle_termByUsername,
+ termByUsername_oid, OID_LENGTH(termByUsername_oid),
+ HANDLER_CAN_RWRITE
+ ));
+}
+
+int
+handle_termBySID(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ int ret;
+ /* We are never called for a GETNEXT if it's registered as a
+ "instance", as it's "magically" handled for us. */
+
+ /* a instance handler also only hands us one request at a time, so
+ we don't need to loop over a list of requests; we'll only get one. */
+
+ switch(reqinfo->mode) {
+
+ case MODE_GET:
+ netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHINSTANCE );
+ break;
+
+ /*
+ * SET REQUEST
+ *
+ * multiple states in the transaction. See:
+ * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg
+ */
+ case MODE_SET_RESERVE1:
+ /* or you could use netsnmp_check_vb_type_and_size instead */
+ ret = netsnmp_check_vb_type_and_size(requests->requestvb, ASN_OCTET_STR, PPP_SESSIONID_LEN);
+ if ( ret != SNMP_ERR_NOERROR ) {
+ netsnmp_set_request_error(reqinfo, requests, ret );
+ }
+ break;
+
+ case MODE_SET_RESERVE2:
+ break;
+
+ case MODE_SET_FREE:
+ /* XXX: free resources allocated in RESERVE1 and/or
+ RESERVE2. Something failed somewhere, and the states
+ below won't be called. */
+ break;
+
+ case MODE_SET_ACTION:
+ terminate_by_sid((char *)requests->requestvb->val.string);
+ /* XXX: perform the value change here */
+ break;
+
+ case MODE_SET_COMMIT:
+ break;
+
+ case MODE_SET_UNDO:
+ break;
+
+ default:
+ /* we should never get here, so this is a really bad error */
+ snmp_log(LOG_ERR, "unknown mode (%d) in handle_termBySID\n", reqinfo->mode );
+ return SNMP_ERR_GENERR;
+ }
+
+ return SNMP_ERR_NOERROR;
+}
+int
+handle_termByIfName(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ int ret;
+ /* We are never called for a GETNEXT if it's registered as a
+ "instance", as it's "magically" handled for us. */
+
+ /* a instance handler also only hands us one request at a time, so
+ we don't need to loop over a list of requests; we'll only get one. */
+
+ switch(reqinfo->mode) {
+
+ case MODE_GET:
+ netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHINSTANCE );
+ break;
+
+ /*
+ * SET REQUEST
+ *
+ * multiple states in the transaction. See:
+ * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg
+ */
+ case MODE_SET_RESERVE1:
+ /* or you could use netsnmp_check_vb_type_and_size instead */
+ ret = netsnmp_check_vb_type(requests->requestvb, ASN_OCTET_STR);
+ if ( ret != SNMP_ERR_NOERROR ) {
+ netsnmp_set_request_error(reqinfo, requests, ret );
+ }
+ break;
+
+ case MODE_SET_RESERVE2:
+ /* XXX malloc "undo" storage buffer */
+ break;
+
+ case MODE_SET_FREE:
+ /* XXX: free resources allocated in RESERVE1 and/or
+ RESERVE2. Something failed somewhere, and the states
+ below won't be called. */
+ break;
+
+ case MODE_SET_ACTION:
+ terminate_by_ifname((char *)requests->requestvb->val.string, requests->requestvb->val_len);
+ /* XXX: perform the value change here */
+ break;
+
+ case MODE_SET_COMMIT:
+ break;
+
+ case MODE_SET_UNDO:
+ break;
+
+ default:
+ /* we should never get here, so this is a really bad error */
+ snmp_log(LOG_ERR, "unknown mode (%d) in handle_termByIfName\n", reqinfo->mode );
+ return SNMP_ERR_GENERR;
+ }
+
+ return SNMP_ERR_NOERROR;
+}
+int
+handle_termByIP(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ int ret;
+ /* We are never called for a GETNEXT if it's registered as a
+ "instance", as it's "magically" handled for us. */
+
+ /* a instance handler also only hands us one request at a time, so
+ we don't need to loop over a list of requests; we'll only get one. */
+
+ switch(reqinfo->mode) {
+
+ case MODE_GET:
+ netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHINSTANCE );
+ break;
+
+ /*
+ * SET REQUEST
+ *
+ * multiple states in the transaction. See:
+ * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg
+ */
+ case MODE_SET_RESERVE1:
+ /* or you could use netsnmp_check_vb_type_and_size instead */
+ ret = netsnmp_check_vb_type(requests->requestvb, ASN_OCTET_STR);
+ if ( ret != SNMP_ERR_NOERROR ) {
+ netsnmp_set_request_error(reqinfo, requests, ret );
+ }
+ break;
+
+ case MODE_SET_RESERVE2:
+ /* XXX malloc "undo" storage buffer */
+ break;
+
+ case MODE_SET_FREE:
+ /* XXX: free resources allocated in RESERVE1 and/or
+ RESERVE2. Something failed somewhere, and the states
+ below won't be called. */
+ break;
+
+ case MODE_SET_ACTION:
+ terminate_by_ip((char *)requests->requestvb->val.string, requests->requestvb->val_len);
+ /* XXX: perform the value change here */
+ break;
+
+ case MODE_SET_COMMIT:
+ /* XXX: delete temporary storage */
+ break;
+
+ case MODE_SET_UNDO:
+ /* XXX: UNDO and return to previous value for the object */
+ break;
+
+ default:
+ /* we should never get here, so this is a really bad error */
+ snmp_log(LOG_ERR, "unknown mode (%d) in handle_termByIP\n", reqinfo->mode );
+ return SNMP_ERR_GENERR;
+ }
+
+ return SNMP_ERR_NOERROR;
+}
+int
+handle_termByUsername(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ int ret;
+ /* We are never called for a GETNEXT if it's registered as a
+ "instance", as it's "magically" handled for us. */
+
+ /* a instance handler also only hands us one request at a time, so
+ we don't need to loop over a list of requests; we'll only get one. */
+
+ switch(reqinfo->mode) {
+
+ case MODE_GET:
+ netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHINSTANCE );
+ break;
+
+ /*
+ * SET REQUEST
+ *
+ * multiple states in the transaction. See:
+ * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg
+ */
+ case MODE_SET_RESERVE1:
+ /* or you could use netsnmp_check_vb_type_and_size instead */
+ ret = netsnmp_check_vb_type(requests->requestvb, ASN_OCTET_STR);
+ if ( ret != SNMP_ERR_NOERROR ) {
+ netsnmp_set_request_error(reqinfo, requests, ret );
+ }
+ break;
+
+ case MODE_SET_RESERVE2:
+ /* XXX malloc "undo" storage buffer */
+ break;
+
+ case MODE_SET_FREE:
+ /* XXX: free resources allocated in RESERVE1 and/or
+ RESERVE2. Something failed somewhere, and the states
+ below won't be called. */
+ break;
+
+ case MODE_SET_ACTION:
+ terminate_by_username((char *)requests->requestvb->val.string, requests->requestvb->val_len);
+ /* XXX: perform the value change here */
+ break;
+
+ case MODE_SET_COMMIT:
+ /* XXX: delete temporary storage */
+ break;
+
+ case MODE_SET_UNDO:
+ /* XXX: UNDO and return to previous value for the object */
+ break;
+
+ default:
+ /* we should never get here, so this is a really bad error */
+ snmp_log(LOG_ERR, "unknown mode (%d) in handle_termByUsername\n", reqinfo->mode );
+ return SNMP_ERR_GENERR;
+ }
+
+ return SNMP_ERR_NOERROR;
+}
diff --git a/accel-pppd/extra/net-snmp/terminate.h b/accel-pppd/extra/net-snmp/terminate.h
new file mode 100644
index 0000000..7013182
--- /dev/null
+++ b/accel-pppd/extra/net-snmp/terminate.h
@@ -0,0 +1,15 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * : mib2c.scalar.conf 11805 2005-01-07 09:37:18Z dts12 $
+ */
+#ifndef TERMINATE_H
+#define TERMINATE_H
+
+/* function declarations */
+void init_terminate(void);
+Netsnmp_Node_Handler handle_termBySID;
+Netsnmp_Node_Handler handle_termByIfName;
+Netsnmp_Node_Handler handle_termByIP;
+Netsnmp_Node_Handler handle_termByUsername;
+
+#endif /* TERMINATE_H */
diff --git a/accel-pppd/extra/pppd_compat.c b/accel-pppd/extra/pppd_compat.c
index 5fa9beb..aa6f6b5 100644
--- a/accel-pppd/extra/pppd_compat.c
+++ b/accel-pppd/extra/pppd_compat.c
@@ -497,7 +497,7 @@ static void fill_env(char **env, struct pppd_compat_pd_t *pd)
}
}
-static void __init init(void)
+static void init(void)
{
char *opt;
@@ -537,3 +537,5 @@ static void __init init(void)
}
#endif
}
+
+DEFINE_INIT(101, init);
diff --git a/accel-pppd/extra/shaper_tbf.c b/accel-pppd/extra/shaper_tbf.c
index cc0ff22..6060027 100644
--- a/accel-pppd/extra/shaper_tbf.c
+++ b/accel-pppd/extra/shaper_tbf.c
@@ -48,6 +48,7 @@ static int temp_up_speed;
static pthread_rwlock_t shaper_lock = PTHREAD_RWLOCK_INITIALIZER;
static LIST_HEAD(shaper_list);
+static pthread_mutex_t nl_lock = PTHREAD_MUTEX_INITIALIZER;
static double tick_in_usec = 1;
static double clock_factor = 1;
@@ -87,7 +88,7 @@ struct time_range_t
static void *pd_key;
static LIST_HEAD(time_range_list);
-static int time_range_id;
+static int time_range_id = 0;
static void shaper_ctx_close(struct triton_context_t *);
static struct triton_context_t shaper_ctx = {
@@ -384,11 +385,14 @@ static int install_shaper(const char *ifname, int down_speed, int down_burst, in
strcpy(ifr.ifr_name, ifname);
if (ioctl(sock_fd, SIOCGIFINDEX, &ifr)) {
- log_ppp_error("tbf: ioctl(SIOCGIFINDEX)", strerror(errno));
+ log_ppp_error("tbf: ioctl(SIOCGIFINDEX): %s\n", strerror(errno));
return -1;
}
+ pthread_mutex_lock(&nl_lock);
h = nl_socket_alloc();
+ pthread_mutex_unlock(&nl_lock);
+
if (!h) {
log_ppp_error("tbf: nl_socket_alloc failed\n");
return -1;
@@ -396,7 +400,7 @@ static int install_shaper(const char *ifname, int down_speed, int down_burst, in
err = nl_connect(h, NETLINK_ROUTE);
if (err < 0) {
- log_ppp_error("tbf: nl_connect: %s", strerror(errno));
+ log_ppp_error("tbf: nl_connect: %s\n", strerror(errno));
goto out;
}
@@ -413,7 +417,10 @@ static int install_shaper(const char *ifname, int down_speed, int down_burst, in
nl_close(h);
out:
+
+ pthread_mutex_lock(&nl_lock);
nl_socket_free(h);
+ pthread_mutex_unlock(&nl_lock);
return 0;
}
@@ -463,7 +470,7 @@ static int remove_shaper(const char *ifname)
strcpy(ifr.ifr_name, ifname);
if (ioctl(sock_fd, SIOCGIFINDEX, &ifr)) {
- log_ppp_error("tbf: ioctl(SIOCGIFINDEX)", strerror(errno));
+ log_ppp_error("tbf: ioctl(SIOCGIFINDEX): %s\n", strerror(errno));
return -1;
}
@@ -481,7 +488,10 @@ static int remove_shaper(const char *ifname)
.tcm_parent = TC_H_INGRESS,
};
+ pthread_mutex_lock(&nl_lock);
h = nl_socket_alloc();
+ pthread_mutex_unlock(&nl_lock);
+
if (!h) {
log_ppp_error("tbf: nl_socket_alloc failed\n");
return -1;
@@ -489,9 +499,8 @@ static int remove_shaper(const char *ifname)
err = nl_connect(h, NETLINK_ROUTE);
if (err < 0) {
- log_ppp_error("tbf: nl_connect: %s", strerror(errno));
- nl_socket_free(h);
- return -1;
+ log_ppp_error("tbf: nl_connect: %s\n", strerror(errno));
+ goto out_err1;
}
pmsg = nlmsg_alloc_simple(RTM_DELQDISC, NLM_F_CREATE | NLM_F_REPLACE);
@@ -525,17 +534,25 @@ static int remove_shaper(const char *ifname)
nlmsg_free(pmsg);
nl_close(h);
+
+ pthread_mutex_lock(&nl_lock);
nl_socket_free(h);
+ pthread_mutex_unlock(&nl_lock);
+
return 0;
out_err:
- log_ppp_error("tbf: failed to remove shaper\n");
-
if (pmsg)
nlmsg_free(pmsg);
nl_close(h);
+
+out_err1:
+ pthread_mutex_lock(&nl_lock);
nl_socket_free(h);
+ pthread_mutex_unlock(&nl_lock);
+
+ log_ppp_error("tbf: failed to remove shaper\n");
return -1;
}
@@ -619,7 +636,7 @@ static struct time_range_pd_t *get_tr_pd(struct shaper_pd_t *pd, int id)
memset(tr_pd, 0, sizeof(*tr_pd));
tr_pd->id = id;
- if (id == time_range_id)
+ if (id == time_range_id || id == 0)
pd->cur_tr = tr_pd;
list_add_tail(&tr_pd->entry, &pd->tr_list);
@@ -818,13 +835,18 @@ static void shaper_change_help(char * const *f, int f_cnt, void *cli)
static void shaper_change(struct shaper_pd_t *pd)
{
- if ((pd->temp_down_speed && pd->temp_up_speed) || (pd->down_speed && pd->up_speed))
+ if (pd->down_speed && pd->up_speed)
remove_shaper(pd->ppp->ifname);
- if (pd->temp_down_speed && pd->temp_up_speed)
+ if (pd->temp_down_speed && pd->temp_up_speed) {
+ pd->down_speed = pd->temp_down_speed;
+ pd->up_speed = pd->temp_up_speed;
install_shaper(pd->ppp->ifname, pd->temp_down_speed, 0, pd->temp_up_speed, 0);
- else if (pd->down_speed && pd->up_speed)
+ } else if (pd->cur_tr->down_speed && pd->cur_tr->up_speed) {
+ pd->down_speed = pd->cur_tr->down_speed;
+ pd->up_speed = pd->cur_tr->up_speed;
install_shaper(pd->ppp->ifname, pd->cur_tr->down_speed, pd->cur_tr->down_burst, pd->cur_tr->up_speed, pd->cur_tr->up_burst);
+ }
}
static int shaper_change_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
@@ -973,6 +995,9 @@ static void update_shaper_tr(struct shaper_pd_t *pd)
{
struct time_range_pd_t *tr;
+ if (pd->ppp->terminating)
+ return;
+
list_for_each_entry(tr, &pd->tr_list, entry) {
if (tr->id != time_range_id)
continue;
@@ -998,8 +1023,7 @@ static void update_shaper_tr(struct shaper_pd_t *pd)
}
} else
if (conf_verbose)
- log_ppp_info2("tbf: removed shaper\n");
-
+ log_ppp_info2("tbf: removed shaper\n");
}
static void time_range_begin_timer(struct triton_timer_t *t)
@@ -1251,7 +1275,7 @@ static int clock_init(void)
return 0;
}
-static void __init init(void)
+static void init(void)
{
if (clock_init())
return;
@@ -1276,3 +1300,4 @@ static void __init init(void)
cli_show_ses_register("rate-limit", "rate limit down-stream/up-stream (Kbit)", print_rate);
}
+DEFINE_INIT(100, init);
diff --git a/accel-pppd/extra/sigchld.c b/accel-pppd/extra/sigchld.c
index 08bab93..8f1a979 100644
--- a/accel-pppd/extra/sigchld.c
+++ b/accel-pppd/extra/sigchld.c
@@ -109,8 +109,10 @@ void __export sigchld_unlock()
pthread_mutex_unlock(&handlers_lock);
}
-static void __init init(void)
+static void init(void)
{
if (pthread_create(&sigchld_thr, NULL, sigchld_thread, NULL))
log_emerg("sigchld: pthread_create: %s\n", strerror(errno));
}
+
+DEFINE_INIT(100, init); \ No newline at end of file
diff --git a/accel-pppd/include/events.h b/accel-pppd/include/events.h
index 6a8caf0..a59ee31 100644
--- a/accel-pppd/include/events.h
+++ b/accel-pppd/include/events.h
@@ -14,6 +14,7 @@
#define EV_PPP_PRE_UP 9
#define EV_PPP_ACCT_START 10
#define EV_CONFIG_RELOAD 11
+#define EV_PPP_AUTH_FAILED 12
#define EV_IP_CHANGED 100
#define EV_SHAPER 101
#define EV_MPPE_KEYS 102
diff --git a/accel-pppd/iprange.c b/accel-pppd/iprange.c
index 411dcb7..315a572 100644
--- a/accel-pppd/iprange.c
+++ b/accel-pppd/iprange.c
@@ -138,9 +138,10 @@ int __export iprange_tunnel_check(in_addr_t ipaddr)
return !check_range(&client_ranges, ipaddr);
}
-static void __init iprange_init(void)
+static void iprange_init(void)
{
load_ranges(&client_ranges, "client-ip-range");
//load_ranges(&tunnel_ranges, "tunnel-ip-range");
}
+DEFINE_INIT(10, iprange_init);
diff --git a/accel-pppd/log.c b/accel-pppd/log.c
index fc50d27..53612e9 100644
--- a/accel-pppd/log.c
+++ b/accel-pppd/log.c
@@ -16,6 +16,15 @@
#include "memdebug.h"
+#define LOG_MSG 0
+#define LOG_ERROR 1
+#define LOG_WARN 2
+#define LOG_INFO1 3
+#define LOG_INFO2 4
+#define LOG_DEBUG 5
+
+#define LOG_CHUNK_SIZE 128
+
struct log_pd_t
{
struct ppp_pd_t pd;
@@ -490,7 +499,7 @@ static void load_config(void)
}
}
-static void __init log_init(void)
+static void log_init(void)
{
struct sigaction sa = {
.sa_handler = sighup,
@@ -509,3 +518,4 @@ static void __init log_init(void)
sigaction(SIGHUP, &sa, NULL);
}
+DEFINE_INIT(0, log_init);
diff --git a/accel-pppd/log.h b/accel-pppd/log.h
index d87c42c..3545cb1 100644
--- a/accel-pppd/log.h
+++ b/accel-pppd/log.h
@@ -5,14 +5,6 @@
#include <sys/time.h>
#include "list.h"
-#define LOG_MSG 0
-#define LOG_ERROR 1
-#define LOG_WARN 2
-#define LOG_INFO1 3
-#define LOG_INFO2 4
-#define LOG_DEBUG 5
-
-#define LOG_CHUNK_SIZE 128
#define LOG_MAX_SIZE 4096
struct ppp_t;
diff --git a/accel-pppd/logs/log_file.c b/accel-pppd/logs/log_file.c
index e435757..f1a5018 100644
--- a/accel-pppd/logs/log_file.c
+++ b/accel-pppd/logs/log_file.c
@@ -47,20 +47,32 @@ struct log_file_pd_t
unsigned long tmp;
};
+struct fail_log_pd_t
+{
+ struct ppp_pd_t pd;
+ struct list_head msgs;
+};
+
+
static int conf_color;
static int conf_per_session;
static char *conf_per_user_dir;
static char *conf_per_session_dir;
static int conf_copy;
+static int conf_fail_log;
static const char* level_name[]={" msg", "error", " warn", " info", " info", "debug"};
static const char* level_color[]={NORMAL_COLOR, RED_COLOR, YELLOW_COLOR, GREEN_COLOR, GREEN_COLOR, BLUE_COLOR};
static void *pd_key1;
static void *pd_key2;
+static void *pd_key3;
+
static struct log_file_t *log_file;
+static struct log_file_t *fail_log_file;
static mempool_t lpd_pool;
+static mempool_t fpd_pool;
static char *log_buf;
static struct aiocb aiocb = {
@@ -248,6 +260,29 @@ static void queue_log(struct log_file_t *lf, struct log_msg_t *msg)
queue_lf(lf);
}
+static void queue_log_list(struct log_file_t *lf, struct list_head *l)
+{
+ int r;
+ struct log_msg_t *msg;
+
+ spin_lock(&lf->lock);
+ while (!list_empty(l)) {
+ msg = list_entry(l->next, typeof(*msg), entry);
+ list_del(&msg->entry);
+ list_add_tail(&msg->entry, &lf->msgs);
+ }
+ if (lf->fd != -1) {
+ r = lf->queued;
+ lf->queued = 1;
+ } else
+ r = 1;
+ spin_unlock(&lf->lock);
+
+ if (!r)
+ queue_lf(lf);
+}
+
+
static void set_hdr(struct log_msg_t *msg, struct ppp_t *ppp)
{
struct tm tm;
@@ -275,20 +310,40 @@ static void general_log(struct log_target_t *t, struct log_msg_t *msg, struct pp
queue_log(log_file, msg);
}
-static struct log_file_pd_t *find_pd(struct ppp_t *ppp, void *pd_key)
+static struct ppp_pd_t *find_pd(struct ppp_t *ppp, void *pd_key)
{
struct ppp_pd_t *pd;
- struct log_file_pd_t *lpd;
list_for_each_entry(pd, &ppp->pd_list, entry) {
if (pd->key == pd_key) {
- lpd = container_of(pd, typeof(*lpd), pd);
- return lpd;
+ return pd;
}
}
+
return NULL;
}
+static struct log_file_pd_t *find_lpd(struct ppp_t *ppp, void *pd_key)
+{
+ struct ppp_pd_t *pd = find_pd(ppp, pd_key);
+
+ if (!pd)
+ return NULL;
+
+ return container_of(pd, struct log_file_pd_t, pd);
+}
+
+static struct fail_log_pd_t *find_fpd(struct ppp_t *ppp, void *pd_key)
+{
+ struct ppp_pd_t *pd = find_pd(ppp, pd_key);
+
+ if (!pd)
+ return NULL;
+
+ return container_of(pd, struct fail_log_pd_t, pd);
+}
+
+
static void per_user_log(struct log_target_t *t, struct log_msg_t *msg, struct ppp_t *ppp)
{
struct log_file_pd_t *lpd;
@@ -298,7 +353,7 @@ static void per_user_log(struct log_target_t *t, struct log_msg_t *msg, struct p
return;
}
- lpd = find_pd(ppp, &pd_key1);
+ lpd = find_lpd(ppp, &pd_key1);
if (!lpd) {
log_free_msg(msg);
@@ -318,7 +373,7 @@ static void per_session_log(struct log_target_t *t, struct log_msg_t *msg, struc
return;
}
- lpd = find_pd(ppp, &pd_key2);
+ lpd = find_lpd(ppp, &pd_key2);
if (!lpd) {
log_free_msg(msg);
@@ -329,6 +384,38 @@ static void per_session_log(struct log_target_t *t, struct log_msg_t *msg, struc
queue_log(&lpd->lf, msg);
}
+static void fail_log(struct log_target_t *t, struct log_msg_t *msg, struct ppp_t *ppp)
+{
+ struct fail_log_pd_t *fpd;
+
+ if (!ppp || !conf_fail_log) {
+ log_free_msg(msg);
+ return;
+ }
+
+ fpd = find_fpd(ppp, &pd_key3);
+
+ if (!fpd) {
+ log_free_msg(msg);
+ return;
+ }
+
+ set_hdr(msg, ppp);
+ list_add_tail(&msg->entry, &fpd->msgs);
+}
+
+static void fail_reopen(void)
+{
+ char *fname = conf_get_opt("log", "log-fail-file");
+ int fd = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ log_emerg("log_file: open '%s': %s\n", fname, strerror(errno));
+ return;
+ }
+ fail_log_file->new_fd = fd;
+}
+
+
static void general_reopen(void)
{
char *fname = conf_get_opt("log", "log-file");
@@ -362,9 +449,75 @@ static void free_lpd(struct log_file_pd_t *lpd)
}
}
+static void ev_ppp_authorized2(struct ppp_t *ppp)
+{
+ struct fail_log_pd_t *fpd;
+ struct log_msg_t *msg;
+
+ fpd = find_fpd(ppp, &pd_key3);
+ if (!fpd)
+ return;
+
+ while (!list_empty(&fpd->msgs)) {
+ msg = list_entry(fpd->msgs.next, typeof(*msg), entry);
+ list_del(&msg->entry);
+ log_free_msg(msg);
+ }
+
+ list_del(&fpd->pd.entry);
+ mempool_free(fpd);
+}
+
+static void ev_ppp_authorized1(struct ppp_t *ppp)
+{
+ struct log_file_pd_t *lpd;
+ char *fname;
+
+ lpd = find_lpd(ppp, &pd_key1);
+ if (!lpd)
+ return;
+
+ fname = _malloc(PATH_MAX);
+ if (!fname) {
+ log_emerg("log_file: out of memory\n");
+ return;
+ }
+
+ strcpy(fname, conf_per_user_dir);
+ strcat(fname, "/");
+ strcat(fname, ppp->username);
+ if (conf_per_session) {
+ if (mkdir(fname, S_IRWXU) && errno != EEXIST) {
+ log_emerg("log_file: mkdir '%s': %s'\n", fname, strerror(errno));
+ goto out_err;
+ }
+ strcat(fname, "/");
+ strcat(fname, ppp->sessionid);
+ }
+ strcat(fname, ".log");
+
+ if (log_file_open(&lpd->lf, fname))
+ goto out_err;
+
+ _free(fname);
+
+ if (!list_empty(&lpd->lf.msgs)) {
+ lpd->lf.queued = 1;
+ queue_lf(&lpd->lf);
+ }
+
+ return;
+
+out_err:
+ _free(fname);
+ list_del(&lpd->pd.entry);
+ free_lpd(lpd);
+}
+
static void ev_ctrl_started(struct ppp_t *ppp)
{
struct log_file_pd_t *lpd;
+ struct fail_log_pd_t *fpd;
char *fname;
if (conf_per_user_dir) {
@@ -413,19 +566,38 @@ static void ev_ctrl_started(struct ppp_t *ppp)
list_add_tail(&lpd->pd.entry, &ppp->pd_list);
}
+
+ if (conf_fail_log) {
+ fpd = mempool_alloc(fpd_pool);
+ if (!fpd) {
+ log_emerg("log_file: out of memory\n");
+ return;
+ }
+ memset(fpd, 0, sizeof(*fpd));
+ fpd->pd.key = &pd_key3;
+ list_add_tail(&fpd->pd.entry, &ppp->pd_list);
+ INIT_LIST_HEAD(&fpd->msgs);
+ }
}
static void ev_ctrl_finished(struct ppp_t *ppp)
{
struct log_file_pd_t *lpd;
+ struct fail_log_pd_t *fpd;
char *fname;
- lpd = find_pd(ppp, &pd_key1);
+ fpd = find_fpd(ppp, &pd_key3);
+ if (fpd) {
+ queue_log_list(fail_log_file, &fpd->msgs);
+ list_del(&fpd->pd.entry);
+ mempool_free(fpd);
+ }
+
+ lpd = find_lpd(ppp, &pd_key1);
if (lpd)
free_lpd(lpd);
-
- lpd = find_pd(ppp, &pd_key2);
+ lpd = find_lpd(ppp, &pd_key2);
if (lpd) {
if (lpd->tmp) {
fname = _malloc(PATH_MAX);
@@ -448,7 +620,7 @@ static void ev_ppp_starting(struct ppp_t *ppp)
struct log_file_pd_t *lpd;
char *fname1, *fname2;
- lpd = find_pd(ppp, &pd_key2);
+ lpd = find_lpd(ppp, &pd_key2);
if (!lpd)
return;
@@ -483,52 +655,6 @@ static void ev_ppp_starting(struct ppp_t *ppp)
_free(fname2);
}
-static void ev_ppp_authorized(struct ppp_t *ppp)
-{
- struct log_file_pd_t *lpd;
- char *fname;
-
- lpd = find_pd(ppp, &pd_key1);
- if (!lpd)
- return;
-
- fname = _malloc(PATH_MAX);
- if (!fname) {
- log_emerg("log_file: out of memory\n");
- return;
- }
-
- strcpy(fname, conf_per_user_dir);
- strcat(fname, "/");
- strcat(fname, ppp->username);
- if (conf_per_session) {
- if (mkdir(fname, S_IRWXU) && errno != EEXIST) {
- log_emerg("log_file: mkdir '%s': %s'\n", fname, strerror(errno));
- goto out_err;
- }
- strcat(fname, "/");
- strcat(fname, ppp->sessionid);
- }
- strcat(fname, ".log");
-
- if (log_file_open(&lpd->lf, fname))
- goto out_err;
-
- _free(fname);
-
- if (!list_empty(&lpd->lf.msgs)) {
- lpd->lf.queued = 1;
- queue_lf(&lpd->lf);
- }
-
- return;
-
-out_err:
- _free(fname);
- list_del(&lpd->pd.entry);
- free_lpd(lpd);
-}
-
static struct log_target_t general_target =
{
.log = general_log,
@@ -545,7 +671,14 @@ static struct log_target_t per_session_target =
.log = per_session_log,
};
-static void __init init(void)
+static struct log_target_t fail_log_target =
+{
+ .log = fail_log,
+ .reopen = fail_reopen,
+};
+
+
+static void init(void)
{
char *opt;
@@ -560,6 +693,7 @@ static void __init init(void)
};
lpd_pool = mempool_create(sizeof(struct log_file_pd_t));
+ fpd_pool = mempool_create(sizeof(struct fail_log_pd_t));
log_buf = malloc(LOG_BUF_SIZE);
aiocb.aio_buf = log_buf;
@@ -579,6 +713,18 @@ static void __init init(void)
}
}
+ opt = conf_get_opt("log", "log-fail-file");
+ if (opt) {
+ fail_log_file = malloc(sizeof(*fail_log_file));
+ memset(fail_log_file, 0, sizeof(*fail_log_file));
+ log_file_init(fail_log_file);
+ if (log_file_open(fail_log_file, opt)) {
+ free(fail_log_file);
+ _exit(EXIT_FAILURE);
+ }
+ conf_fail_log = 1;
+ }
+
opt = conf_get_opt("log","color");
if (opt && atoi(opt) > 0)
conf_color = 1;
@@ -601,14 +747,23 @@ static void __init init(void)
log_register_target(&general_target);
- if (conf_per_user_dir)
+ if (conf_per_user_dir) {
log_register_target(&per_user_target);
+ triton_event_register_handler(EV_PPP_AUTHORIZED, (triton_event_func)ev_ppp_authorized1);
+ }
- if (conf_per_session_dir)
+ if (conf_per_session_dir) {
log_register_target(&per_session_target);
+ triton_event_register_handler(EV_PPP_STARTING, (triton_event_func)ev_ppp_starting);
+ }
+
+ if (conf_fail_log) {
+ log_register_target(&fail_log_target);
+ triton_event_register_handler(EV_PPP_AUTHORIZED, (triton_event_func)ev_ppp_authorized2);
+ }
triton_event_register_handler(EV_CTRL_STARTED, (triton_event_func)ev_ctrl_started);
triton_event_register_handler(EV_CTRL_FINISHED, (triton_event_func)ev_ctrl_finished);
- triton_event_register_handler(EV_PPP_STARTING, (triton_event_func)ev_ppp_starting);
- triton_event_register_handler(EV_PPP_AUTHORIZED, (triton_event_func)ev_ppp_authorized);
}
+
+DEFINE_INIT(1, init);
diff --git a/accel-pppd/logs/log_pgsql.c b/accel-pppd/logs/log_pgsql.c
index af67e0b..742ee62 100644
--- a/accel-pppd/logs/log_pgsql.c
+++ b/accel-pppd/logs/log_pgsql.c
@@ -280,7 +280,7 @@ static struct log_target_t target = {
.log = general_log,
};
-static void __init init(void)
+static void init(void)
{
char *opt;
@@ -319,3 +319,5 @@ static void __init init(void)
log_register_target(&target);
}
+
+DEFINE_INIT(1, init);
diff --git a/accel-pppd/logs/log_tcp.c b/accel-pppd/logs/log_tcp.c
index 306c450..ceaeb1c 100644
--- a/accel-pppd/logs/log_tcp.c
+++ b/accel-pppd/logs/log_tcp.c
@@ -301,7 +301,7 @@ static struct triton_context_t tcp_ctx ={
.before_switch = log_switch,
};
-static void __init init(void)
+static void init(void)
{
struct conf_sect_t *s = conf_get_section("log");
struct conf_option_t *opt;
@@ -321,3 +321,4 @@ static void __init init(void)
triton_context_wakeup(&tcp_ctx);
}
+DEFINE_INIT(1, init);
diff --git a/accel-pppd/main.c b/accel-pppd/main.c
index 2e48c45..e153caf 100644
--- a/accel-pppd/main.c
+++ b/accel-pppd/main.c
@@ -14,43 +14,52 @@
#include "log.h"
#include "events.h"
-static int goto_daemon;
static char *pid_file;
static char *conf_file;
-#define ARG_MAX 128
-static int parse_cmdline(char ***argv)
-{
+static void change_limits(void)
+{
FILE *f;
- int i;
- size_t len;
+ struct rlimit lim;
+ unsigned int file_max = 1024*1024;
+ unsigned int nr_open = 1024*1024;
- f = fopen("/proc/self/cmdline", "r");
- if (!f) {
- perror("open cmdline");
- _exit(EXIT_FAILURE);
+ f = fopen("/proc/sys/fs/nr_open", "r");
+ if (f) {
+ fscanf(f, "%d", &nr_open);
+ fclose(f);
}
- *argv = _malloc(ARG_MAX * sizeof(void *));
- memset(*argv, 0, ARG_MAX * sizeof(void *));
-
- for(i = 0; i < ARG_MAX; i++) {
- len = 0;
- if (getdelim(&(*argv)[i], &len, 0, f) < 0)
- break;
+ f = fopen("/proc/sys/fs/file-max", "r");
+ if (f) {
+ fscanf(f, "%d", &file_max);
+ fclose(f);
}
- fclose(f);
+ if (file_max > nr_open)
+ file_max = nr_open;
- return i;
+ lim.rlim_cur = file_max;
+ lim.rlim_max = file_max;
+ if (setrlimit(RLIMIT_NOFILE, &lim))
+ log_emerg("main: setrlimit: %s\n", strerror(errno));
}
-static void __init __main(void)
+
+static void config_reload_notify(int r)
+{
+ if (!r)
+ triton_event_fire(EV_CONFIG_RELOAD, NULL);
+}
+static void config_reload(int num)
{
- int i,argc;
- char **argv;
+ triton_conf_reload(config_reload_notify);
+}
+
+int main(int argc, char **argv)
+{
+ sigset_t set;
+ int i, sig, goto_daemon = 0;
- argc=parse_cmdline(&argv);
-
if (argc < 2)
goto usage;
@@ -74,51 +83,6 @@ static void __init __main(void)
if (triton_init(conf_file))
_exit(EXIT_FAILURE);
- return;
-
-usage:
- printf("usage: accel-pppd [-d] [-p <file>] -c <file>\n\
- where:\n\
- -d - daemon mode\n\
- -p - write pid to <file>\n\
- -c - config file\n");
- _exit(EXIT_FAILURE);
-}
-
-static void change_limits(void)
-{
- FILE *f;
- struct rlimit lim;
- unsigned int file_max;
-
- f = fopen("/proc/sys/fs/file-max", "r");
- if (f) {
- fscanf(f, "%d", &file_max);
- fclose(f);
-
- lim.rlim_cur = file_max;
- lim.rlim_max = file_max;
- if (setrlimit(RLIMIT_NOFILE, &lim))
- log_emerg("main: setrlimit: %s\n", strerror(errno));
- } else
- log_emerg("main: failed to open '/proc/sys/fs/file-max': %s\n", strerror(errno));
-}
-
-static void config_reload_notify(int r)
-{
- if (!r)
- triton_event_fire(EV_CONFIG_RELOAD, NULL);
-}
-static void config_reload(int num)
-{
- triton_conf_reload(config_reload_notify);
-}
-
-int main(int argc, char **argv)
-{
- sigset_t set;
- int sig;
-
if (goto_daemon) {
/*pid_t pid = fork();
if (pid > 0)
@@ -148,9 +112,6 @@ int main(int argc, char **argv)
}
}
- //signal(SIGTERM, sigterm);
- //signal(SIGPIPE, sigterm);
-
change_limits();
if (triton_load_modules("modules"))
@@ -197,5 +158,13 @@ int main(int argc, char **argv)
triton_terminate();
return EXIT_SUCCESS;
+
+usage:
+ printf("usage: accel-pppd [-d] [-p <file>] -c <file>\n\
+ where:\n\
+ -d - daemon mode\n\
+ -p - write pid to <file>\n\
+ -c - config file\n");
+ _exit(EXIT_FAILURE);
}
diff --git a/accel-pppd/ppp/ccp_mppe.c b/accel-pppd/ppp/ccp_mppe.c
index cf83d2d..7d9aab2 100644
--- a/accel-pppd/ppp/ccp_mppe.c
+++ b/accel-pppd/ppp/ccp_mppe.c
@@ -24,16 +24,21 @@
static struct ccp_option_t *mppe_init(struct ppp_ccp_t *ccp);
static void mppe_free(struct ppp_ccp_t *ccp, struct ccp_option_t *opt);
+static int __mppe_send_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr, int setup_key);
static int mppe_send_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr);
+static int mppe_send_conf_nak(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr);
static int mppe_recv_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr);
static int mppe_recv_conf_nak(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr);
static int mppe_recv_conf_rej(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr);
static void mppe_print(void (*print)(const char *fmt,...),struct ccp_option_t*, uint8_t *ptr);
+static int conf_mppe = -1;
+
struct mppe_option_t
{
struct ccp_option_t opt;
int mppe;
+ int enabled;
uint8_t recv_key[16];
uint8_t send_key[16];
int policy; // 1 - allowed, 2 - required
@@ -42,7 +47,7 @@ struct mppe_option_t
static struct ccp_option_handler_t mppe_opt_hnd = {
.init = mppe_init,
.send_conf_req = mppe_send_conf_req,
- .send_conf_nak = mppe_send_conf_req,
+ .send_conf_nak = mppe_send_conf_nak,
.recv_conf_req = mppe_recv_conf_req,
.recv_conf_nak = mppe_recv_conf_nak,
.recv_conf_rej = mppe_recv_conf_rej,
@@ -54,7 +59,20 @@ static struct ccp_option_t *mppe_init(struct ppp_ccp_t *ccp)
{
struct mppe_option_t *mppe_opt = _malloc(sizeof(*mppe_opt));
memset(mppe_opt, 0, sizeof(*mppe_opt));
- mppe_opt->mppe = -1;
+
+ if (conf_mppe != -1)
+ mppe_opt->policy = conf_mppe;
+ else
+ mppe_opt->policy = 1;
+
+ if (conf_mppe > 0)
+ mppe_opt->mppe = 1;
+ else
+ mppe_opt->mppe = -1;
+
+ if (conf_mppe == 2)
+ ccp->passive = 0;
+
mppe_opt->opt.id = CI_MPPE;
mppe_opt->opt.len = 6;
@@ -114,7 +132,7 @@ static int decrease_mtu(struct ppp_t *ppp)
return 0;
}
-static int mppe_send_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr)
+static int __mppe_send_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr, int setup_key)
{
struct mppe_option_t *mppe_opt = container_of(opt,typeof(*mppe_opt),opt);
struct ccp_opt32_t *opt32 = (struct ccp_opt32_t*)ptr;
@@ -124,7 +142,7 @@ static int mppe_send_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, u
opt32->hdr.len = 6;
opt32->val = mppe_opt->mppe ? htonl(MPPE_S | MPPE_H) : 0;
- if (mppe_opt->mppe && setup_mppe_key(ccp->ppp->unit_fd, 0, mppe_opt->recv_key))
+ if (setup_key && mppe_opt->mppe && setup_mppe_key(ccp->ppp->unit_fd, 0, mppe_opt->recv_key))
return 0;
return 6;
@@ -132,16 +150,27 @@ static int mppe_send_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, u
return 0;
}
+static int mppe_send_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr)
+{
+ return __mppe_send_conf_req(ccp, opt, ptr, 1);
+}
+
+static int mppe_send_conf_nak(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr)
+{
+ return __mppe_send_conf_req(ccp, opt, ptr, 0);
+}
+
+
static int mppe_recv_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr)
{
struct mppe_option_t *mppe_opt = container_of(opt, typeof(*mppe_opt), opt);
struct ccp_opt32_t *opt32 = (struct ccp_opt32_t *)ptr;
- /*if (!ptr) {
+ if (!ptr) {
if (mppe_opt->policy == 2)
return CCP_OPT_NAK;
return CCP_OPT_ACK;
- }*/
+ }
if (opt32->hdr.len != 6)
return CCP_OPT_REJ;
@@ -152,7 +181,7 @@ static int mppe_recv_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, u
} else if (mppe_opt->policy == 1) {
if (ntohl(opt32->val) == (MPPE_S | MPPE_H))
mppe_opt->mppe = 1;
- else if ((ntohl(opt32->val) & (MPPE_S | MPPE_H)) == (MPPE_S | MPPE_H)) {
+ else if ((ntohl(opt32->val) & (MPPE_S | MPPE_H)) || conf_mppe == 1) {
mppe_opt->mppe = 1;
return CCP_OPT_NAK;
} else if (opt32->val) {
@@ -167,7 +196,10 @@ static int mppe_recv_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, u
if (setup_mppe_key(ccp->ppp->unit_fd, 1, mppe_opt->send_key))
return CCP_OPT_REJ;
- decrease_mtu(ccp->ppp);
+ if (!mppe_opt->enabled) {
+ decrease_mtu(ccp->ppp);
+ mppe_opt->enabled = 1;
+ }
log_ppp_debug(" (mppe enabled)");
}
@@ -179,7 +211,7 @@ static int mppe_recv_conf_rej(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, u
{
struct mppe_option_t *mppe_opt = container_of(opt, typeof(*mppe_opt), opt);
- if (mppe_opt->mppe != 2) {
+ if (mppe_opt->policy != 2) {
mppe_opt->mppe = -1;
return 0;
}
@@ -237,24 +269,60 @@ static void mppe_print(void (*print)(const char *fmt,...),struct ccp_option_t *o
static void ev_mppe_keys(struct ev_mppe_keys_t *ev)
{
+ struct ppp_ccp_t *ccp = ccp_find_layer_data(ev->ppp);
struct mppe_option_t *mppe_opt = container_of(ccp_find_option(ev->ppp, &mppe_opt_hnd), typeof(*mppe_opt), opt);
+ memcpy(mppe_opt->recv_key, ev->recv_key, 16);
+ memcpy(mppe_opt->send_key, ev->send_key, 16);
+
+ if (ev->policy == -1)
+ return;
+
if ((ev->type & 0x04) == 0) {
log_ppp_warn("mppe: 128-bit session keys not allowed, disabling mppe ...\n");
+ mppe_opt->mppe = 0;
return;
}
- memcpy(mppe_opt->recv_key, ev->recv_key, 16);
- memcpy(mppe_opt->send_key, ev->send_key, 16);
mppe_opt->policy = ev->policy;
- if (ev->policy == 2)
+ if (ev->policy == 2) {
mppe_opt->mppe = 1;
+ ccp->passive = 0;
+ } else if (ev->policy == 1) {
+ if (conf_mppe == 1)
+ mppe_opt->mppe = 1;
+ else
+ mppe_opt->mppe = -1;
+
+ if (conf_mppe == 2)
+ ccp->passive = 1;
+ }
+}
+
+static void load_config(void)
+{
+ const char *opt;
+
+ opt = conf_get_opt("ppp", "mppe");
+ if (opt) {
+ if (!strcmp(opt,"require"))
+ conf_mppe = 2;
+ else if (!strcmp(opt,"prefere"))
+ conf_mppe = 1;
+ else if (!strcmp(opt,"deny"))
+ conf_mppe = 0;
+ } else
+ conf_mppe = -1;
}
-static void __init mppe_opt_init()
+static void mppe_opt_init()
{
ccp_option_register(&mppe_opt_hnd);
triton_event_register_handler(EV_MPPE_KEYS, (triton_event_func)ev_mppe_keys);
+
+ load_config();
+ triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
}
+DEFINE_INIT(4, mppe_opt_init);
diff --git a/accel-pppd/ppp/ipcp_opt_dns.c b/accel-pppd/ppp/ipcp_opt_dns.c
index f488f3c..4427b0e 100644
--- a/accel-pppd/ppp/ipcp_opt_dns.c
+++ b/accel-pppd/ppp/ipcp_opt_dns.c
@@ -152,7 +152,7 @@ static void load_config(void)
conf_dns2 = inet_addr(opt);
}
-static void __init dns_opt_init()
+static void dns_opt_init()
{
ipcp_option_register(&dns1_opt_hnd);
ipcp_option_register(&dns2_opt_hnd);
@@ -160,3 +160,5 @@ static void __init dns_opt_init()
load_config();
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
}
+
+DEFINE_INIT(4, dns_opt_init);
diff --git a/accel-pppd/ppp/ipcp_opt_ipaddr.c b/accel-pppd/ppp/ipcp_opt_ipaddr.c
index de1186e..217a080 100644
--- a/accel-pppd/ppp/ipcp_opt_ipaddr.c
+++ b/accel-pppd/ppp/ipcp_opt_ipaddr.c
@@ -9,6 +9,7 @@
#include "ppp.h"
#include "ppp_ipcp.h"
+#include "ppp_ccp.h"
#include "log.h"
#include "ipdb.h"
#include "iprange.h"
@@ -126,15 +127,16 @@ static int ipaddr_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o
{
struct ipaddr_option_t *ipaddr_opt = container_of(opt,typeof(*ipaddr_opt), opt);
struct ipcp_opt32_t *opt32 = (struct ipcp_opt32_t*)ptr;
- struct ifreq ifr;
- struct sockaddr_in addr;
- struct npioctl np;
if (opt32->hdr.len != 6)
return IPCP_OPT_REJ;
- if (ipaddr_opt->ip->peer_addr == opt32->val)
- goto ack;
+ if (ipaddr_opt->ip->peer_addr == opt32->val) {
+ ipcp->ppp->ipaddr = ipaddr_opt->ip->addr;
+ ipcp->ppp->peer_ipaddr = ipaddr_opt->ip->peer_addr;
+ ipcp->delay_ack = ccp_ipcp_started(ipcp->ppp);
+ return IPCP_OPT_ACK;
+ }
/*if (!ipaddr_opt->peer_addr) {
ipaddr_opt->peer_addr = opt32->val;
@@ -142,28 +144,19 @@ static int ipaddr_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o
}*/
return IPCP_OPT_NAK;
+}
-ack:
- if (ipaddr_opt->started)
- return IPCP_OPT_ACK;
+static void if_up(struct ppp_t *ppp)
+{
+ struct ipaddr_option_t *ipaddr_opt = container_of(ipcp_find_option(ppp, &ipaddr_opt_hnd), typeof(*ipaddr_opt), opt);
+ struct ifreq ifr;
+ struct sockaddr_in addr;
+ struct npioctl np;
- ipaddr_opt->started = 1;
-
- ipcp->ppp->ipaddr = ipaddr_opt->ip->addr;
- ipcp->ppp->peer_ipaddr = ipaddr_opt->ip->peer_addr;
-
- triton_event_fire(EV_PPP_ACCT_START, ipcp->ppp);
- if (ipcp->ppp->stop_time)
- return IPCP_OPT_ACK;
-
- triton_event_fire(EV_PPP_PRE_UP, ipcp->ppp);
- if (ipcp->ppp->stop_time)
- return IPCP_OPT_ACK;
-
memset(&ifr, 0, sizeof(ifr));
memset(&addr, 0, sizeof(addr));
- strcpy(ifr.ifr_name, ipcp->ppp->ifname);
+ strcpy(ifr.ifr_name, ppp->ifname);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = ipaddr_opt->ip->addr;
@@ -177,6 +170,14 @@ ack:
if (ioctl(sock_fd, SIOCSIFDSTADDR, &ifr))
log_ppp_error("ipcp: failed to set remote PA address: %s\n", strerror(errno));
+
+ triton_event_fire(EV_PPP_ACCT_START, ppp);
+ if (ppp->stop_time)
+ return;
+
+ triton_event_fire(EV_PPP_PRE_UP, ppp);
+ if (ppp->stop_time)
+ return;
if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr))
log_ppp_error("ipcp: failed to get interface flags: %s\n", strerror(errno));
@@ -189,10 +190,8 @@ ack:
np.protocol = PPP_IP;
np.mode = NPMODE_PASS;
- if (ioctl(ipcp->ppp->unit_fd, PPPIOCSNPMODE, &np))
+ if (ioctl(ppp->unit_fd, PPPIOCSNPMODE, &np))
log_ppp_error("ipcp: failed to set NP mode: %s\n", strerror(errno));
-
- return IPCP_OPT_ACK;
}
static void ipaddr_print(void (*print)(const char *fmt,...),struct ipcp_option_t *opt, uint8_t *ptr)
@@ -218,10 +217,12 @@ static void load_config(void)
conf_check_exists = 1;
}
-static void __init ipaddr_opt_init()
+static void ipaddr_opt_init()
{
ipcp_option_register(&ipaddr_opt_hnd);
load_config();
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
+ triton_event_register_handler(EV_PPP_STARTED, (triton_event_func)if_up);
}
+DEFINE_INIT(4, ipaddr_opt_init);
diff --git a/accel-pppd/ppp/lcp_opt_accomp.c b/accel-pppd/ppp/lcp_opt_accomp.c
index 241b0e0..33347d8 100644
--- a/accel-pppd/ppp/lcp_opt_accomp.c
+++ b/accel-pppd/ppp/lcp_opt_accomp.c
@@ -99,8 +99,9 @@ static void accomp_print(void (*print)(const char *fmt,...),struct lcp_option_t
print("<accomp>");
}
-static void __init accomp_opt_init()
+static void accomp_opt_init()
{
lcp_option_register(&accomp_opt_hnd);
}
+DEFINE_INIT(4, accomp_opt_init);
diff --git a/accel-pppd/ppp/lcp_opt_magic.c b/accel-pppd/ppp/lcp_opt_magic.c
index 6c0deb5..3e694d2 100644
--- a/accel-pppd/ppp/lcp_opt_magic.c
+++ b/accel-pppd/ppp/lcp_opt_magic.c
@@ -99,7 +99,9 @@ static void magic_print(void (*print)(const char *fmt,...),struct lcp_option_t *
print("<magic %04x>", magic_opt->magic);
}
-static void __init magic_opt_init()
+static void magic_opt_init()
{
lcp_option_register(&magic_opt_hnd);
}
+
+DEFINE_INIT(4, magic_opt_init);
diff --git a/accel-pppd/ppp/lcp_opt_mru.c b/accel-pppd/ppp/lcp_opt_mru.c
index 78e06b5..577e019 100644
--- a/accel-pppd/ppp/lcp_opt_mru.c
+++ b/accel-pppd/ppp/lcp_opt_mru.c
@@ -186,10 +186,11 @@ static void load_config(void)
}
}
-static void __init mru_opt_init()
+static void mru_opt_init()
{
load_config();
lcp_option_register(&mru_opt_hnd);
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
}
+DEFINE_INIT(4, mru_opt_init);
diff --git a/accel-pppd/ppp/lcp_opt_pcomp.c b/accel-pppd/ppp/lcp_opt_pcomp.c
index 1f8532b..fec5e7b 100644
--- a/accel-pppd/ppp/lcp_opt_pcomp.c
+++ b/accel-pppd/ppp/lcp_opt_pcomp.c
@@ -99,8 +99,9 @@ static void pcomp_print(void (*print)(const char *fmt,...),struct lcp_option_t *
print("<pcomp>");
}
-static void __init pcomp_opt_init()
+static void pcomp_opt_init()
{
lcp_option_register(&pcomp_opt_hnd);
}
+DEFINE_INIT(4, pcomp_opt_init);
diff --git a/accel-pppd/ppp/ppp.c b/accel-pppd/ppp/ppp.c
index 7ce3b4b..b541ba5 100644
--- a/accel-pppd/ppp/ppp.c
+++ b/accel-pppd/ppp/ppp.c
@@ -25,7 +25,8 @@
#include "memdebug.h"
int __export conf_ppp_verbose;
-static int conf_sid_ucase;
+int conf_sid_ucase;
+int conf_single_session = -1;
pthread_rwlock_t __export ppp_lock = PTHREAD_RWLOCK_INITIALIZER;
__export LIST_HEAD(ppp_list);
@@ -43,7 +44,7 @@ static unsigned long long seq;
static spinlock_t seq_lock;
#endif
-struct ppp_stat_t ppp_stat;
+__export struct ppp_stat_t ppp_stat;
struct layer_node_t
{
@@ -399,7 +400,7 @@ void __export ppp_layer_started(struct ppp_t *ppp, struct ppp_layer_data_t *d)
list_for_each_entry(d, &n->items, entry) {
d->starting = 1;
if (d->layer->start(d)) {
- ppp_terminate(ppp, TERM_NAS_ERROR, 0);
+ ppp_terminate(ppp, 1, TERM_NAS_ERROR);
return;
}
}
@@ -641,9 +642,18 @@ static void load_config(void)
else if (strcmp(opt, "lower"))
log_emerg("ppp: sid-case: invalid format\n");
}
+
+ opt = conf_get_opt("ppp", "single-session");
+ if (opt) {
+ if (!strcmp(opt, "deny"))
+ conf_single_session = 0;
+ else if (!strcmp(opt, "replace"))
+ conf_single_session = 1;
+ } else
+ conf_single_session = -1;
}
-static void __init init(void)
+static void init(void)
{
char *opt;
FILE *f;
@@ -673,3 +683,4 @@ static void __init init(void)
atexit(save_seq);
}
+DEFINE_INIT(2, init);
diff --git a/accel-pppd/ppp/ppp.h b/accel-pppd/ppp/ppp.h
index e8141cc..ae2a7c9 100644
--- a/accel-pppd/ppp/ppp.h
+++ b/accel-pppd/ppp/ppp.h
@@ -55,12 +55,16 @@
#define TERM_AUTH_ERROR 8
#define TERM_LOST_CARRIER 9
+#define CTRL_TYPE_PPTP 1
+#define CTRL_TYPE_L2TP 2
+#define CTRL_TYPE_PPPOE 3
struct ppp_t;
struct ppp_ctrl_t
{
struct triton_context_t *ctx;
+ int type;
const char *name;
int max_mtu;
char *calling_station_id;
@@ -177,6 +181,7 @@ extern int ppp_shutdown;
void ppp_shutdown_soft(void);
extern int conf_ppp_verbose;
+extern int conf_single_session;
extern pthread_rwlock_t ppp_lock;
extern struct list_head ppp_list;
diff --git a/accel-pppd/ppp/ppp_auth.c b/accel-pppd/ppp/ppp_auth.c
index 32413c6..b69c759 100644
--- a/accel-pppd/ppp/ppp_auth.c
+++ b/accel-pppd/ppp/ppp_auth.c
@@ -28,6 +28,8 @@ static int auth_layer_start(struct ppp_layer_data_t *);
static void auth_layer_finish(struct ppp_layer_data_t *);
static void auth_layer_free(struct ppp_layer_data_t *);
+static void __ppp_auth_started(struct ppp_t *ppp);
+
struct auth_option_t
{
struct lcp_option_t opt;
@@ -296,24 +298,66 @@ static void auth_layer_free(struct ppp_layer_data_t *ld)
log_ppp_debug("auth_layer_free\n");
+ triton_cancel_call(ad->ppp->ctrl->ctx, (triton_event_func)__ppp_auth_started);
+
_free(ad);
}
-void __export ppp_auth_successed(struct ppp_t *ppp, char *username)
+static void ppp_terminate_sec(struct ppp_t *ppp)
+{
+ ppp_terminate(ppp, TERM_NAS_REQUEST, 0);
+}
+
+static void __ppp_auth_started(struct ppp_t *ppp)
{
struct auth_layer_data_t *ad = container_of(ppp_find_layer_data(ppp, &auth_layer), typeof(*ad), ld);
+
log_ppp_debug("auth_layer_started\n");
- ppp->username = username;
ppp_layer_started(ppp, &ad->ld);
- log_ppp_info1("%s: authentication successed\n", username);
+ log_ppp_info1("%s: authentication successed\n", ppp->username);
triton_event_fire(EV_PPP_AUTHORIZED, ppp);
}
-void __export ppp_auth_failed(struct ppp_t *ppp, const char *username)
+int __export ppp_auth_successed(struct ppp_t *ppp, char *username)
+{
+ struct ppp_t *p;
+ struct auth_layer_data_t *ad = container_of(ppp_find_layer_data(ppp, &auth_layer), typeof(*ad), ld);
+
+ pthread_rwlock_rdlock(&ppp_lock);
+ list_for_each_entry(p, &ppp_list, entry) {
+ if (p->username && !strcmp(p->username, username)) {
+ if (conf_single_session == 0) {
+ pthread_rwlock_unlock(&ppp_lock);
+ log_ppp_info1("%s: second session denied\n", username);
+ return -1;
+ } else {
+ if (conf_single_session == 1)
+ triton_context_call(p->ctrl->ctx, (triton_event_func)ppp_terminate_sec, p);
+ }
+ }
+ }
+ pthread_rwlock_unlock(&ppp_lock);
+
+ pthread_rwlock_wrlock(&ppp_lock);
+ ppp->username = username;
+ pthread_rwlock_unlock(&ppp_lock);
+
+ triton_context_call(ppp->ctrl->ctx, (triton_event_func)__ppp_auth_started, ppp);
+
+ return 0;
+}
+
+void __export ppp_auth_failed(struct ppp_t *ppp, char *username)
{
- if (username)
+ if (username) {
+ pthread_rwlock_wrlock(&ppp_lock);
+ if (!ppp->username)
+ ppp->username = _strdup(username);
+ pthread_rwlock_unlock(&ppp_lock);
log_ppp_info1("%s: authentication failed\n", username);
- else
+ log_info1("%s: authentication failed\n", username);
+ triton_event_fire(EV_PPP_AUTH_FAILED, ppp);
+ } else
log_ppp_info1("authentication failed\n");
ppp_terminate(ppp, TERM_AUTH_ERROR, 0);
}
@@ -338,9 +382,10 @@ int __export ppp_auth_restart(struct ppp_t *ppp)
return 0;
}
-static void __init ppp_auth_init()
+static void ppp_auth_init()
{
ppp_register_layer("auth", &auth_layer);
lcp_option_register(&auth_opt_hnd);
}
+DEFINE_INIT(3, ppp_auth_init);
diff --git a/accel-pppd/ppp/ppp_auth.h b/accel-pppd/ppp/ppp_auth.h
index 87cc742..6f86d26 100644
--- a/accel-pppd/ppp/ppp_auth.h
+++ b/accel-pppd/ppp/ppp_auth.h
@@ -29,8 +29,8 @@ struct ppp_auth_handler_t
int ppp_auth_register_handler(struct ppp_auth_handler_t*);
-void ppp_auth_successed(struct ppp_t *ppp, char *username);
-void ppp_auth_failed(struct ppp_t *ppp, const char *username);
+int ppp_auth_successed(struct ppp_t *ppp, char *username);
+void ppp_auth_failed(struct ppp_t *ppp, char *username);
int ppp_auth_restart(struct ppp_t *ppp);
#endif
diff --git a/accel-pppd/ppp/ppp_ccp.c b/accel-pppd/ppp/ppp_ccp.c
index 58a4abf..79b0c32 100644
--- a/accel-pppd/ppp/ppp_ccp.c
+++ b/accel-pppd/ppp/ppp_ccp.c
@@ -26,12 +26,14 @@ struct recv_opt_t
};
static int conf_ccp = 1;
+static int conf_ccp_max_configure = 3;
static struct ppp_layer_t ccp_layer;
static LIST_HEAD(option_handlers);
static void ccp_layer_up(struct ppp_fsm_t*);
static void ccp_layer_down(struct ppp_fsm_t*);
+static void ccp_layer_finished(struct ppp_fsm_t*);
static int send_conf_req(struct ppp_fsm_t*);
static void send_conf_ack(struct ppp_fsm_t*);
static void send_conf_nak(struct ppp_fsm_t*);
@@ -105,16 +107,19 @@ static struct ppp_layer_data_t *ccp_layer_init(struct ppp_t *ppp)
ppp_register_unit_handler(ppp, &ccp->hnd);
+ ccp->passive = 1;
+
INIT_LIST_HEAD(&ccp->options);
ccp_options_init(ccp);
-
- ccp->passive = 0;
ccp->fsm.proto = PPP_CCP;
ppp_fsm_init(&ccp->fsm);
+ ccp->fsm.max_configure = conf_ccp_max_configure;
+
ccp->fsm.layer_up = ccp_layer_up;
- ccp->fsm.layer_finished = ccp_layer_down;
+ ccp->fsm.layer_finished = ccp_layer_finished;
+ ccp->fsm.layer_down = ccp_layer_down;
ccp->fsm.send_conf_req = send_conf_req;
ccp->fsm.send_conf_ack = send_conf_ack;
ccp->fsm.send_conf_nak = send_conf_nak;
@@ -134,13 +139,18 @@ int ccp_layer_start(struct ppp_layer_data_t *ld)
log_ppp_debug("ccp_layer_start\n");
if (list_empty(&ccp->options) || !conf_ccp) {
+ ccp->started = 1;
ppp_layer_started(ccp->ppp, &ccp->ld);
return 0;
}
-
- ppp_fsm_lower_up(&ccp->fsm);
- if (ppp_fsm_open(&ccp->fsm))
- return -1;
+
+ ccp->starting = 1;
+
+ if (!ccp->passive) {
+ ppp_fsm_lower_up(&ccp->fsm);
+ if (ppp_fsm_open(&ccp->fsm))
+ return -1;
+ }
if (ccp_set_flags(ccp->ppp->unit_fd, 1, 0)) {
ppp_fsm_close(&ccp->fsm);
@@ -159,7 +169,7 @@ void ccp_layer_finish(struct ppp_layer_data_t *ld)
ccp_set_flags(ccp->ppp->unit_fd, 0, 0);
ccp->fsm.fsm_state = FSM_Closed;
-
+
log_ppp_debug("ccp_layer_finished\n");
ppp_layer_finished(ccp->ppp, &ccp->ld);
}
@@ -181,9 +191,8 @@ static void ccp_layer_up(struct ppp_fsm_t *fsm)
{
struct ppp_ccp_t *ccp = container_of(fsm, typeof(*ccp), fsm);
- log_ppp_debug("ccp_layer_started\n");
-
if (!ccp->started) {
+ log_ppp_debug("ccp_layer_started\n");
ccp->started = 1;
if (ccp_set_flags(ccp->ppp->unit_fd, 1, 1)) {
ppp_terminate(ccp->ppp, TERM_NAS_ERROR, 0);
@@ -193,18 +202,28 @@ static void ccp_layer_up(struct ppp_fsm_t *fsm)
}
}
-static void ccp_layer_down(struct ppp_fsm_t *fsm)
+static void ccp_layer_finished(struct ppp_fsm_t *fsm)
{
struct ppp_ccp_t *ccp = container_of(fsm, typeof(*ccp), fsm);
log_ppp_debug("ccp_layer_finished\n");
- if (!ccp->started)
+ if (!ccp->started) {
+ ccp->started = 1;
ppp_layer_started(ccp->ppp, &ccp->ld);
- ccp->started = 0;
- ppp_layer_finished(ccp->ppp, &ccp->ld);
+ }
}
+static void ccp_layer_down(struct ppp_fsm_t *fsm)
+{
+ struct ppp_ccp_t *ccp = container_of(fsm, typeof(*ccp), fsm);
+
+ log_ppp_debug("ccp_layer_down\n");
+
+ ppp_fsm_close(fsm);
+}
+
+
static void print_ropt(struct recv_opt_t *ropt)
{
int i;
@@ -225,19 +244,15 @@ static int send_conf_req(struct ppp_fsm_t *fsm)
struct ccp_option_t *lopt;
int n;
- ccp->need_req = 0;
-
- if (ccp->passive) {
- ccp->passive--;
+ if (ccp->passive)
return 0;
- }
buf = _malloc(ccp->conf_req_len);
ccp_hdr = (struct ccp_hdr_t*)buf;
ccp_hdr->proto = htons(PPP_CCP);
ccp_hdr->code = CONFREQ;
- ccp_hdr->id = ++ccp->fsm.id;
+ ccp_hdr->id = ccp->fsm.id;
ccp_hdr->len = 0;
ptr = (uint8_t*)(ccp_hdr + 1);
@@ -287,7 +302,7 @@ static void send_conf_nak(struct ppp_fsm_t *fsm)
struct ppp_ccp_t *ccp = container_of(fsm, typeof(*ccp), fsm);
uint8_t *buf = _malloc(ccp->conf_req_len), *ptr = buf;
struct ccp_hdr_t *ccp_hdr = (struct ccp_hdr_t*)ptr;
- struct recv_opt_t *ropt;
+ struct ccp_option_t *lopt;
if (conf_ppp_verbose)
log_ppp_info2("send [CCP ConfNak id=%x", ccp->fsm.recv_id);
@@ -299,13 +314,13 @@ static void send_conf_nak(struct ppp_fsm_t *fsm)
ptr += sizeof(*ccp_hdr);
- list_for_each_entry(ropt, &ccp->ropt_list, entry) {
- if (ropt->state == CCP_OPT_NAK) {
+ list_for_each_entry(lopt, &ccp->options, entry) {
+ if (lopt->state == CCP_OPT_NAK) {
if (conf_ppp_verbose) {
log_ppp_info2(" ");
- ropt->lopt->h->print(log_ppp_info2, ropt->lopt, NULL);
+ lopt->h->print(log_ppp_info2, lopt, NULL);
}
- ptr += ropt->lopt->h->send_conf_nak(ccp, ropt->lopt, ptr);
+ ptr += lopt->h->send_conf_nak(ccp, lopt, ptr);
}
}
@@ -365,7 +380,6 @@ static int ccp_recv_conf_req(struct ppp_ccp_t *ccp, uint8_t *data, int size)
struct ccp_option_t *lopt;
int r, ret = 1, ack = 0;
- ccp->need_req = 0;
ccp->ropt_len = size;
while (size > 0) {
@@ -402,8 +416,6 @@ static int ccp_recv_conf_req(struct ppp_ccp_t *ccp, uint8_t *data, int size)
lopt->state = CCP_OPT_REJ;
ropt->state = CCP_OPT_REJ;
} else {
- /*if (lopt->state == CCP_OPT_NAK && r == CCP_OPT_ACK)
- ccp->need_req = 1;*/
lopt->state = r;
ropt->state = r;
}
@@ -428,15 +440,14 @@ static int ccp_recv_conf_req(struct ppp_ccp_t *ccp, uint8_t *data, int size)
if (conf_ppp_verbose)
log_ppp_info2("]\n");
- /*list_for_each_entry(lopt,&ccp->options,entry)
- {
- if (lopt->state==CCP_OPT_NONE)
- {
- r=lopt->h->recv_conf_req(ccp,lopt,NULL);
- lopt->state=r;
- if (r<ret) ret=r;
+ list_for_each_entry(lopt, &ccp->options, entry) {
+ if (lopt->state == CCP_OPT_NONE) {
+ r = lopt->h->recv_conf_req(ccp, lopt, NULL);
+ lopt->state = r;
+ if (r < ret)
+ ret = r;
}
- }*/
+ }
return ret;
}
@@ -461,11 +472,11 @@ static int ccp_recv_conf_rej(struct ppp_ccp_t *ccp, uint8_t *data, int size)
if (conf_ppp_verbose)
log_ppp_info2("recv [CCP ConfRej id=%x", ccp->fsm.recv_id);
- if (ccp->fsm.recv_id != ccp->fsm.id) {
+ /*if (ccp->fsm.recv_id != ccp->fsm.id) {
if (conf_ppp_verbose)
log_ppp_info2(": id mismatch ]\n");
return 0;
- }
+ }*/
while (size > 0) {
hdr = (struct ccp_opt_hdr_t *)data;
@@ -499,11 +510,11 @@ static int ccp_recv_conf_nak(struct ppp_ccp_t *ccp, uint8_t *data, int size)
if (conf_ppp_verbose)
log_ppp_info2("recv [CCP ConfNak id=%x", ccp->fsm.recv_id);
- if (ccp->fsm.recv_id != ccp->fsm.id) {
+ /*if (ccp->fsm.recv_id != ccp->fsm.id) {
if (conf_ppp_verbose)
log_ppp_info2(": id mismatch ]\n");
return 0;
- }
+ }*/
while (size > 0) {
hdr = (struct ccp_opt_hdr_t *)data;
@@ -516,8 +527,6 @@ static int ccp_recv_conf_nak(struct ppp_ccp_t *ccp, uint8_t *data, int size)
}
if (lopt->h->recv_conf_nak && lopt->h->recv_conf_nak(ccp, lopt, data))
res = -1;
- //lopt->state = CCP_OPT_NAK;
- //ccp->need_req = 1;
break;
}
}
@@ -541,11 +550,11 @@ static int ccp_recv_conf_ack(struct ppp_ccp_t *ccp, uint8_t *data, int size)
if (conf_ppp_verbose)
log_ppp_info2("recv [CCP ConfAck id=%x", ccp->fsm.recv_id);
- if (ccp->fsm.recv_id != ccp->fsm.id) {
+ /*if (ccp->fsm.recv_id != ccp->fsm.id) {
if (conf_ppp_verbose)
log_ppp_info2(": id mismatch ]\n");
return 0;
- }
+ }*/
while (size > 0) {
hdr = (struct ccp_opt_hdr_t *)data;
@@ -612,7 +621,7 @@ static void ccp_recv(struct ppp_handler_t*h)
struct ppp_ccp_t *ccp = container_of(h, typeof(*ccp), hnd);
int r;
- if (ccp->fsm.fsm_state == FSM_Initial || ccp->fsm.fsm_state == FSM_Closed || ccp->ppp->terminating) {
+ if (!ccp->starting || ccp->fsm.fsm_state == FSM_Closed || ccp->ppp->terminating) {
if (conf_ppp_verbose)
log_ppp_warn("CCP: discarding packet\n");
if (ccp->fsm.fsm_state == FSM_Closed || !conf_ccp)
@@ -631,38 +640,51 @@ static void ccp_recv(struct ppp_handler_t*h)
return;
}
+ if ((hdr->code == CONFACK || hdr->code == CONFNAK || hdr->code == CONFREJ) && hdr->id != ccp->fsm.id)
+ return;
+
ccp->fsm.recv_id = hdr->id;
+
switch(hdr->code) {
- case CONFREQ:
+ case CONFREQ:
r = ccp_recv_conf_req(ccp, (uint8_t*)(hdr + 1), ntohs(hdr->len) - PPP_HDRLEN);
- switch(r) {
- case CCP_OPT_ACK:
- ppp_fsm_recv_conf_req_ack(&ccp->fsm);
- break;
- case CCP_OPT_NAK:
- ppp_fsm_recv_conf_req_nak(&ccp->fsm);
- break;
- case CCP_OPT_REJ:
- ppp_fsm_recv_conf_req_rej(&ccp->fsm);
- break;
+ if (ccp->passive) {
+ ccp->passive = 0;
+ ppp_fsm_lower_up(&ccp->fsm);
+ ppp_fsm_open(&ccp->fsm);
+ }
+ if (ccp->started) {
+ if (r == CCP_OPT_ACK)
+ send_conf_ack(&ccp->fsm);
+ else
+ r = CCP_OPT_FAIL;
+ } else {
+ switch(r) {
+ case CCP_OPT_ACK:
+ ppp_fsm_recv_conf_req_ack(&ccp->fsm);
+ break;
+ case CCP_OPT_NAK:
+ ppp_fsm_recv_conf_req_nak(&ccp->fsm);
+ break;
+ case CCP_OPT_REJ:
+ ppp_fsm_recv_conf_req_rej(&ccp->fsm);
+ break;
+ }
}
ccp_free_conf_req(ccp);
- if (r == CCP_OPT_ACK && ccp->passive) {
+ /*if (r == CCP_OPT_ACK && ccp->passive) {
ccp->passive = 0;
send_conf_req(&ccp->fsm);
- }
+ }*/
if (r == CCP_OPT_FAIL)
ppp_terminate(ccp->ppp, TERM_USER_ERROR, 0);
break;
case CONFACK:
if (ccp_recv_conf_ack(ccp, (uint8_t*)(hdr + 1), ntohs(hdr->len) - PPP_HDRLEN))
ppp_terminate(ccp->ppp, TERM_USER_ERROR, 0);
- else {
+ else
ppp_fsm_recv_conf_ack(&ccp->fsm);
- if (ccp->need_req)
- send_conf_req(&ccp->fsm);
- }
break;
case CONFNAK:
ccp_recv_conf_nak(ccp, (uint8_t*)(hdr + 1), ntohs(hdr->len) - PPP_HDRLEN);
@@ -720,6 +742,10 @@ int ccp_option_register(struct ccp_option_handler_t *h)
return 0;
}
+struct ppp_ccp_t *ccp_find_layer_data(struct ppp_t *ppp)
+{
+ return container_of(ppp_find_layer_data(ppp, &ccp_layer), typeof(struct ppp_ccp_t), ld);
+}
struct ccp_option_t *ccp_find_option(struct ppp_t *ppp, struct ccp_option_handler_t *h)
{
struct ppp_ccp_t *ccp = container_of(ppp_find_layer_data(ppp, &ccp_layer), typeof(*ccp), ld);
@@ -733,6 +759,21 @@ struct ccp_option_t *ccp_find_option(struct ppp_t *ppp, struct ccp_option_handle
abort();
}
+int ccp_ipcp_started(struct ppp_t *ppp)
+{
+ struct ppp_ccp_t *ccp = container_of(ppp_find_layer_data(ppp, &ccp_layer), typeof(*ccp), ld);
+
+ if (ccp->passive) {
+ ccp->fsm.fsm_state = FSM_Closed;
+ ccp->started = 1;
+ ppp_layer_started(ccp->ppp, &ccp->ld);
+
+ return 0;
+ }
+
+ return !ccp->started;
+}
+
static struct ppp_layer_t ccp_layer=
{
.init = ccp_layer_init,
@@ -748,9 +789,13 @@ static void load_config(void)
opt = conf_get_opt("ppp", "ccp");
if (opt && atoi(opt) >= 0)
conf_ccp = atoi(opt);
+
+ opt = conf_get_opt("ppp", "ccp-max-configure");
+ if (opt && atoi(opt) > 0)
+ conf_ccp_max_configure = atoi(opt);
}
-static void __init ccp_init(void)
+static void ccp_init(void)
{
ppp_register_layer("ccp", &ccp_layer);
@@ -758,3 +803,4 @@ static void __init ccp_init(void)
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
}
+DEFINE_INIT(3, ccp_init);
diff --git a/accel-pppd/ppp/ppp_ccp.h b/accel-pppd/ppp/ppp_ccp.h
index 2c2dc6d..3a48816 100644
--- a/accel-pppd/ppp/ppp_ccp.h
+++ b/accel-pppd/ppp/ppp_ccp.h
@@ -84,13 +84,16 @@ struct ppp_ccp_t
int ropt_len;
int conf_req_len;
- int passive;
+ int passive:1;
+ int starting:1;
int started:1;
- int need_req:1;
};
int ccp_option_register(struct ccp_option_handler_t *h);
struct ccp_option_t *ccp_find_option(struct ppp_t *ppp, struct ccp_option_handler_t *h);
+struct ppp_ccp_t *ccp_find_layer_data(struct ppp_t *ppp);
+int ccp_ipcp_started(struct ppp_t *ppp);
+
#endif
diff --git a/accel-pppd/ppp/ppp_fsm.c b/accel-pppd/ppp/ppp_fsm.c
index c6bc430..b43945b 100644
--- a/accel-pppd/ppp/ppp_fsm.c
+++ b/accel-pppd/ppp/ppp_fsm.c
@@ -14,7 +14,7 @@
static int conf_max_terminate = 2;
static int conf_max_configure = 10;
static int conf_max_failure = 10;
-static int conf_timeout = 5;
+static int conf_timeout = 3;
void send_term_req(struct ppp_fsm_t *layer);
void send_term_ack(struct ppp_fsm_t *layer);
@@ -35,7 +35,8 @@ void ppp_fsm_init(struct ppp_fsm_t *layer)
layer->max_terminate = conf_max_terminate;
layer->max_configure = conf_max_configure;
layer->max_failure = conf_max_failure;
- layer->timeout = conf_timeout;
+
+ layer->id = 1;
}
void ppp_fsm_free(struct ppp_fsm_t *layer)
{
@@ -96,7 +97,7 @@ int ppp_fsm_open(struct ppp_fsm_t *layer)
switch(layer->fsm_state)
{
case FSM_Initial:
- if (layer->layer_started) layer->layer_started(layer);
+ //if (layer->layer_started) layer->layer_started(layer);
layer->fsm_state=FSM_Starting;
break;
case FSM_Starting:
@@ -168,7 +169,6 @@ void ppp_fsm_timeout0(struct ppp_fsm_t *layer)
case FSM_Req_Sent:
case FSM_Ack_Sent:
--layer->restart_counter;
- --layer->id;
if (layer->send_conf_req) layer->send_conf_req(layer);
break;
default:
@@ -315,6 +315,7 @@ void ppp_fsm_recv_conf_req_rej(struct ppp_fsm_t *layer)
void ppp_fsm_recv_conf_ack(struct ppp_fsm_t *layer)
{
+ ++layer->id;
switch(layer->fsm_state)
{
case FSM_Closed:
@@ -351,6 +352,7 @@ void ppp_fsm_recv_conf_ack(struct ppp_fsm_t *layer)
void ppp_fsm_recv_conf_rej(struct ppp_fsm_t *layer)
{
+ ++layer->id;
switch(layer->fsm_state)
{
case FSM_Closed:
@@ -373,7 +375,10 @@ void ppp_fsm_recv_conf_rej(struct ppp_fsm_t *layer)
layer->fsm_state=FSM_Req_Sent;
break;
case FSM_Ack_Sent:
- //if (layer->init_req_cnt) layer->init_req_cnt(layer);
+ if (++layer->conf_failure == layer->max_failure) {
+ if (layer->layer_down) layer->layer_down(layer);
+ return;
+ }
init_req_counter(layer,layer->max_configure);
--layer->restart_counter;
if (layer->send_conf_req) layer->send_conf_req(layer);
@@ -536,9 +541,10 @@ static void load_config(void)
conf_timeout = atoi(opt);
}
-void __init fsm_init(void)
+static void fsm_init(void)
{
load_config();
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
}
+DEFINE_INIT(3, fsm_init);
diff --git a/accel-pppd/ppp/ppp_fsm.h b/accel-pppd/ppp/ppp_fsm.h
index 6010240..6d2fb14 100644
--- a/accel-pppd/ppp/ppp_fsm.h
+++ b/accel-pppd/ppp/ppp_fsm.h
@@ -30,7 +30,6 @@ struct ppp_fsm_t
int max_terminate;
int max_configure;
int max_failure;
- int timeout;
int conf_failure;
int id;
diff --git a/accel-pppd/ppp/ppp_ipcp.c b/accel-pppd/ppp/ppp_ipcp.c
index 5d66c9d..bd9f50d 100644
--- a/accel-pppd/ppp/ppp_ipcp.c
+++ b/accel-pppd/ppp/ppp_ipcp.c
@@ -23,6 +23,7 @@ struct recv_opt_t
};
static LIST_HEAD(option_handlers);
+static struct ppp_layer_t ipcp_layer;
static void ipcp_layer_up(struct ppp_fsm_t*);
static void ipcp_layer_down(struct ppp_fsm_t*);
@@ -134,10 +135,8 @@ void ipcp_layer_free(struct ppp_layer_data_t *ld)
_free(ipcp);
}
-static void ipcp_layer_up(struct ppp_fsm_t *fsm)
+static void __ipcp_layer_up(struct ppp_ipcp_t *ipcp)
{
- struct ppp_ipcp_t *ipcp = container_of(fsm, typeof(*ipcp), fsm);
-
log_ppp_debug("ipcp_layer_started\n");
if (!ipcp->started) {
@@ -146,6 +145,14 @@ static void ipcp_layer_up(struct ppp_fsm_t *fsm)
}
}
+static void ipcp_layer_up(struct ppp_fsm_t *fsm)
+{
+ struct ppp_ipcp_t *ipcp = container_of(fsm, typeof(*ipcp), fsm);
+
+ if (!ipcp->delay_ack)
+ __ipcp_layer_up(ipcp);
+}
+
static void ipcp_layer_down(struct ppp_fsm_t *fsm)
{
struct ppp_ipcp_t *ipcp = container_of(fsm, typeof(*ipcp), fsm);
@@ -181,7 +188,7 @@ static int send_conf_req(struct ppp_fsm_t *fsm)
ipcp_hdr->proto = htons(PPP_IPCP);
ipcp_hdr->code = CONFREQ;
- ipcp_hdr->id = ++ipcp->fsm.id;
+ ipcp_hdr->id = ipcp->fsm.id;
ipcp_hdr->len = 0;
ptr += sizeof(*ipcp_hdr);
@@ -221,6 +228,11 @@ static void send_conf_ack(struct ppp_fsm_t *fsm)
struct ppp_ipcp_t *ipcp = container_of(fsm, typeof(*ipcp), fsm);
struct ipcp_hdr_t *hdr = (struct ipcp_hdr_t*)ipcp->ppp->buf;
+ if (ipcp->delay_ack) {
+ send_term_ack(fsm);
+ return;
+ }
+
hdr->code = CONFACK;
if (conf_ppp_verbose)
@@ -409,11 +421,11 @@ static int ipcp_recv_conf_rej(struct ppp_ipcp_t *ipcp, uint8_t *data, int size)
if (conf_ppp_verbose)
log_ppp_info2("recv [IPCP ConfRej id=%x", ipcp->fsm.recv_id);
- if (ipcp->fsm.recv_id != ipcp->fsm.id) {
+ /*if (ipcp->fsm.recv_id != ipcp->fsm.id) {
if (conf_ppp_verbose)
log_ppp_info2(": id mismatch ]\n");
return 0;
- }
+ }*/
while (size > 0) {
hdr = (struct ipcp_opt_hdr_t *)data;
@@ -447,11 +459,11 @@ static int ipcp_recv_conf_nak(struct ppp_ipcp_t *ipcp, uint8_t *data, int size)
if (conf_ppp_verbose)
log_ppp_info2("recv [IPCP ConfNak id=%x", ipcp->fsm.recv_id);
- if (ipcp->fsm.recv_id != ipcp->fsm.id) {
+ /*if (ipcp->fsm.recv_id != ipcp->fsm.id) {
if (conf_ppp_verbose)
log_ppp_info2(": id mismatch ]\n");
return 0;
- }
+ }*/
while (size > 0) {
hdr = (struct ipcp_opt_hdr_t *)data;
@@ -487,11 +499,11 @@ static int ipcp_recv_conf_ack(struct ppp_ipcp_t *ipcp, uint8_t *data, int size)
if (conf_ppp_verbose)
log_ppp_info2("recv [IPCP ConfAck id=%x", ipcp->fsm.recv_id);
- if (ipcp->fsm.recv_id != ipcp->fsm.id) {
+ /*if (ipcp->fsm.recv_id != ipcp->fsm.id) {
if (conf_ppp_verbose)
log_ppp_info2(": id mismatch ]\n");
return 0;
- }
+ }*/
while (size > 0) {
hdr = (struct ipcp_opt_hdr_t *)data;
@@ -557,6 +569,7 @@ static void ipcp_recv(struct ppp_handler_t*h)
struct ipcp_hdr_t *hdr;
struct ppp_ipcp_t *ipcp = container_of(h, typeof(*ipcp), hnd);
int r;
+ int delay_ack = ipcp->delay_ack;
if (ipcp->fsm.fsm_state == FSM_Initial || ipcp->fsm.fsm_state == FSM_Closed || ipcp->ppp->terminating) {
if (conf_ppp_verbose)
@@ -574,8 +587,12 @@ static void ipcp_recv(struct ppp_handler_t*h)
log_ppp_warn("IPCP: short packet received\n");
return;
}
+
+ if ((hdr->code == CONFACK || hdr->code == CONFNAK || hdr->code == CONFREJ) && hdr->id != ipcp->fsm.id)
+ return;
ipcp->fsm.recv_id = hdr->id;
+
switch(hdr->code) {
case CONFREQ:
r = ipcp_recv_conf_req(ipcp,(uint8_t*)(hdr + 1), ntohs(hdr->len) - PPP_HDRLEN);
@@ -583,16 +600,25 @@ static void ipcp_recv(struct ppp_handler_t*h)
ipcp_free_conf_req(ipcp);
return;
}
- switch(r) {
- case IPCP_OPT_ACK:
- ppp_fsm_recv_conf_req_ack(&ipcp->fsm);
- break;
- case IPCP_OPT_NAK:
- ppp_fsm_recv_conf_req_nak(&ipcp->fsm);
- break;
- case IPCP_OPT_REJ:
- ppp_fsm_recv_conf_req_rej(&ipcp->fsm);
- break;
+ if (delay_ack && !ipcp->delay_ack)
+ __ipcp_layer_up(ipcp);
+ if (ipcp->started || delay_ack) {
+ if (r == IPCP_OPT_ACK)
+ send_conf_ack(&ipcp->fsm);
+ else
+ r = IPCP_OPT_FAIL;
+ } else {
+ switch(r) {
+ case IPCP_OPT_ACK:
+ ppp_fsm_recv_conf_req_ack(&ipcp->fsm);
+ break;
+ case IPCP_OPT_NAK:
+ ppp_fsm_recv_conf_req_nak(&ipcp->fsm);
+ break;
+ case IPCP_OPT_REJ:
+ ppp_fsm_recv_conf_req_rej(&ipcp->fsm);
+ break;
+ }
}
ipcp_free_conf_req(ipcp);
if (r == IPCP_OPT_FAIL)
@@ -650,6 +676,19 @@ int ipcp_option_register(struct ipcp_option_handler_t *h)
return 0;
}
+struct ipcp_option_t *ipcp_find_option(struct ppp_t *ppp, struct ipcp_option_handler_t *h)
+{
+ struct ppp_ipcp_t *ipcp = container_of(ppp_find_layer_data(ppp, &ipcp_layer), typeof(*ipcp), ld);
+ struct ipcp_option_t *opt;
+
+ list_for_each_entry(opt, &ipcp->options, entry)
+ if (opt->h == h)
+ return opt;
+
+ log_emerg("ipcp: BUG: option not found\n");
+ abort();
+}
+
static struct ppp_layer_t ipcp_layer =
{
.init = ipcp_layer_init,
@@ -658,8 +697,9 @@ static struct ppp_layer_t ipcp_layer =
.free = ipcp_layer_free,
};
-static void __init ipcp_init(void)
+static void ipcp_init(void)
{
ppp_register_layer("ipcp", &ipcp_layer);
}
+DEFINE_INIT(3, ipcp_init);
diff --git a/accel-pppd/ppp/ppp_ipcp.h b/accel-pppd/ppp/ppp_ipcp.h
index c955987..f955461 100644
--- a/accel-pppd/ppp/ppp_ipcp.h
+++ b/accel-pppd/ppp/ppp_ipcp.h
@@ -88,9 +88,11 @@ struct ppp_ipcp_t
int conf_req_len;
int started:1;
+ int delay_ack:1;
};
int ipcp_option_register(struct ipcp_option_handler_t *h);
+struct ipcp_option_t *ipcp_find_option(struct ppp_t *ppp, struct ipcp_option_handler_t *h);
#endif
diff --git a/accel-pppd/ppp/ppp_lcp.c b/accel-pppd/ppp/ppp_lcp.c
index c46c5a4..fa23436 100644
--- a/accel-pppd/ppp/ppp_lcp.c
+++ b/accel-pppd/ppp/ppp_lcp.c
@@ -171,7 +171,7 @@ static void lcp_layer_down(struct ppp_fsm_t *fsm)
{
struct ppp_lcp_t *lcp = container_of(fsm, typeof(*lcp), fsm);
//ppp_fsm_close(&lcp->fsm);
- stop_echo(lcp);
+ //stop_echo(lcp);
//ppp_layer_finished(lcp->ppp,&lcp->ld);
}
@@ -214,7 +214,7 @@ static int send_conf_req(struct ppp_fsm_t *fsm)
lcp_hdr->proto = htons(PPP_LCP);
lcp_hdr->code = CONFREQ;
- lcp_hdr->id = ++lcp->fsm.id;
+ lcp_hdr->id = lcp->fsm.id;
lcp_hdr->len = 0;
ptr += sizeof(*lcp_hdr);
@@ -569,34 +569,39 @@ static int lcp_recv_conf_ack(struct ppp_lcp_t *lcp, uint8_t *data, int size)
static void lcp_recv_echo_repl(struct ppp_lcp_t *lcp, uint8_t *data, int size)
{
- uint32_t magic = *(uint32_t *)data;
+ uint32_t magic;
if (size != 4) {
- log_ppp_error("lcp:echo: magic number size mismatch\n");
- ppp_terminate(lcp->ppp, TERM_USER_ERROR, 0);
- }
+ if (conf_ppp_verbose)
+ log_ppp_debug("recv [LCP EchoRep id=%x]\n", lcp->fsm.recv_id);
+ } else {
+ magic = *(uint32_t *)data;
- if (conf_ppp_verbose)
- log_ppp_debug("recv [LCP EchoRep id=%x <magic %x>]\n", lcp->fsm.recv_id, magic);
+ if (conf_ppp_verbose)
+ log_ppp_debug("recv [LCP EchoRep id=%x <magic %x>]\n", lcp->fsm.recv_id, magic);
- if (magic == lcp->magic) {
- log_ppp_error("lcp: echo: loop-back detected\n");
- ppp_terminate(lcp->ppp, TERM_NAS_ERROR, 0);
+ if (magic == lcp->magic) {
+ log_ppp_error("lcp: echo: loop-back detected\n");
+ ppp_terminate(lcp->ppp, TERM_NAS_ERROR, 0);
+ }
}
+ lcp->fsm.id++;
lcp->echo_sent = 0;
}
static void send_echo_reply(struct ppp_lcp_t *lcp)
{
struct lcp_hdr_t *hdr = (struct lcp_hdr_t*)lcp->ppp->buf;
- uint32_t magic = *(uint32_t *)(hdr + 1);
+ //uint32_t magic = *(uint32_t *)(hdr + 1);
+
+ lcp->echo_sent = 0;
hdr->code = ECHOREP;
- *(uint32_t *)(hdr + 1) = lcp->magic;
+ *(uint32_t *)(hdr + 1) = htonl(lcp->magic);
if (conf_ppp_verbose)
- log_ppp_debug("send [LCP EchoRep id=%x <magic %x>]\n", hdr->id, magic);
+ log_ppp_debug("send [LCP EchoRep id=%x <magic %x>]\n", hdr->id, htonl(lcp->magic));
ppp_chan_send(lcp->ppp, hdr, ntohs(hdr->len) + 2);
}
@@ -611,7 +616,7 @@ static void send_echo_request(struct triton_timer_t *t)
} __attribute__((packed)) msg = {
.hdr.proto = htons(PPP_LCP),
.hdr.code = ECHOREQ,
- .hdr.id = ++lcp->fsm.id,
+ .hdr.id = lcp->fsm.id,
.hdr.len = htons(8),
.magic = lcp->magic,
};
@@ -702,25 +707,29 @@ static void lcp_recv(struct ppp_handler_t*h)
int r;
char *term_msg;
- if (lcp->fsm.fsm_state == FSM_Initial || lcp->fsm.fsm_state == FSM_Closed || lcp->ppp->terminating) {
- /*if (conf_ppp_verbose)
- log_ppp_warn("LCP: discaring packet\n");
- lcp_send_proto_rej(ccp->ppp, htons(PPP_CCP));*/
- return;
- }
-
if (lcp->ppp->buf_size < PPP_HEADERLEN + 2) {
log_ppp_warn("LCP: short packet received\n");
return;
}
- hdr = (struct lcp_hdr_t *)lcp->ppp->buf;
+ hdr = (struct lcp_hdr_t *)lcp->ppp->buf;
if (ntohs(hdr->len) < PPP_HEADERLEN) {
log_ppp_warn("LCP: short packet received\n");
return;
}
+ if ((hdr->code == CONFACK || hdr->code == CONFNAK || hdr->code == CONFREJ) && hdr->id != lcp->fsm.id)
+ return;
+
+ if (lcp->fsm.fsm_state == FSM_Initial || lcp->fsm.fsm_state == FSM_Closed || (lcp->ppp->terminating && (hdr->code != TERMACK && hdr->code != TERMREQ))) {
+ /*if (conf_ppp_verbose)
+ log_ppp_warn("LCP: discaring packet\n");
+ lcp_send_proto_rej(ccp->ppp, htons(PPP_CCP));*/
+ return;
+ }
+
lcp->fsm.recv_id = hdr->id;
+
switch(hdr->code) {
case CONFREQ:
r = lcp_recv_conf_req(lcp, (uint8_t*)(hdr + 1), ntohs(hdr->len) - PPP_HDRLEN);
@@ -839,7 +848,7 @@ static void load_config(void)
conf_echo_failure = atoi(opt);
}
-static void __init lcp_init(void)
+static void lcp_init(void)
{
load_config();
@@ -848,3 +857,4 @@ static void __init lcp_init(void)
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
}
+DEFINE_INIT(3, lcp_init);
diff --git a/accel-pppd/radius/CMakeLists.txt b/accel-pppd/radius/CMakeLists.txt
index d85d60c..0c1789e 100644
--- a/accel-pppd/radius/CMakeLists.txt
+++ b/accel-pppd/radius/CMakeLists.txt
@@ -5,6 +5,7 @@ SET(sources
packet.c
auth.c
acct.c
+ serv.c
dm_coa.c
radius.c
)
diff --git a/accel-pppd/radius/acct.c b/accel-pppd/radius/acct.c
index 6238793..4f1d901 100644
--- a/accel-pppd/radius/acct.c
+++ b/accel-pppd/radius/acct.c
@@ -116,6 +116,30 @@ static int rad_acct_read(struct triton_md_handler_t *h)
return 0;
}
+static void __rad_req_send(struct rad_req_t *req)
+{
+ while (1) {
+
+ if (rad_server_req_enter(req)) {
+ if (rad_server_realloc(req, 1)) {
+ log_ppp_warn("radius:acct: no servers available, terminating session...\n");
+ if (conf_acct_timeout) {
+ ppp_terminate(req->rpd->ppp, TERM_NAS_ERROR, 0);
+ return;
+ }
+ break;
+ }
+ continue;
+ }
+
+ rad_req_send(req, conf_interim_verbose);
+
+ rad_server_req_exit(req);
+
+ break;
+ }
+}
+
static void rad_acct_timeout(struct triton_timer_t *t)
{
struct rad_req_t *req = container_of(t, typeof(*req), timeout);
@@ -130,9 +154,13 @@ static void rad_acct_timeout(struct triton_timer_t *t)
dt = ts - req->rpd->acct_timestamp;
if (dt > conf_acct_timeout) {
- log_ppp_warn("radius:acct: no response, terminating session...\n");
- ppp_terminate(req->rpd->ppp, TERM_NAS_ERROR, 0);
- return;
+ rad_server_fail(req->serv);
+ if (rad_server_realloc(req, 1)) {
+ log_ppp_warn("radius:acct: no servers available, terminating session...\n");
+ ppp_terminate(req->rpd->ppp, TERM_NAS_ERROR, 0);
+ return;
+ }
+ time(&req->rpd->acct_timestamp);
}
if (dt > conf_acct_timeout / 2) {
req->timeout.period += 1000;
@@ -144,11 +172,14 @@ static void rad_acct_timeout(struct triton_timer_t *t)
}
}
- req->pack->id++;
-
- rad_packet_change_int(req->pack, NULL, "Acct-Delay-Time", dt);
- req_set_RA(req, conf_acct_secret);
- rad_req_send(req, conf_interim_verbose);
+ if (conf_acct_delay_time) {
+ req->pack->id++;
+ rad_packet_change_int(req->pack, NULL, "Acct-Delay-Time", dt);
+ req_set_RA(req, req->serv->acct_secret);
+ }
+
+ __rad_req_send(req);
+
__sync_add_and_fetch(&stat_interim_sent, 1);
}
@@ -171,9 +202,12 @@ static void rad_acct_interim_update(struct triton_timer_t *t)
rpd->acct_req->pack->id++;
rad_packet_change_val(rpd->acct_req->pack, NULL, "Acct-Status-Type", "Interim-Update");
- rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", 0);
- req_set_RA(rpd->acct_req, conf_acct_secret);
- rad_req_send(rpd->acct_req, conf_interim_verbose);
+ if (conf_acct_delay_time)
+ rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", 0);
+ req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret);
+
+ __rad_req_send(rpd->acct_req);
+
__sync_add_and_fetch(&stat_interim_sent, 1);
if (conf_acct_timeout) {
rpd->acct_req->timeout.period = conf_timeout * 1000;
@@ -186,6 +220,9 @@ int rad_acct_start(struct radius_pd_t *rpd)
int i;
time_t ts;
unsigned int dt;
+
+ if (!conf_accounting)
+ return 0;
rpd->acct_req = rad_req_alloc(rpd, CODE_ACCOUNTING_REQUEST, rpd->ppp->username);
if (!rpd->acct_req) {
@@ -210,44 +247,75 @@ int rad_acct_start(struct radius_pd_t *rpd)
time(&rpd->acct_timestamp);
- for (i = 0; i < conf_max_try; i++) {
- time(&ts);
- rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", ts - rpd->acct_timestamp);
- if (req_set_RA(rpd->acct_req, conf_acct_secret))
- goto out_err;
- if (rad_req_send(rpd->acct_req, conf_verbose))
- goto out_err;
- __sync_add_and_fetch(&stat_acct_sent, 1);
- rad_req_wait(rpd->acct_req, conf_timeout);
- if (!rpd->acct_req->reply) {
- rpd->acct_req->pack->id++;
- __sync_add_and_fetch(&stat_acct_lost, 1);
- stat_accm_add(stat_acct_lost_1m, 1);
- stat_accm_add(stat_acct_lost_5m, 1);
+ if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret))
+ goto out_err;
+
+ while (1) {
+
+ if (rad_server_req_enter(rpd->acct_req)) {
+ if (rad_server_realloc(rpd->acct_req, 1)) {
+ log_ppp_warn("radius:acct_start: no servers available\n");
+ goto out_err;
+ }
+ if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret))
+ goto out_err;
continue;
}
- dt = (rpd->acct_req->reply->tv.tv_sec - rpd->acct_req->pack->tv.tv_sec) * 1000 +
- (rpd->acct_req->reply->tv.tv_usec - rpd->acct_req->pack->tv.tv_usec) / 1000;
- stat_accm_add(stat_acct_query_1m, dt);
- stat_accm_add(stat_acct_query_5m, dt);
+ for (i = 0; i < conf_max_try; i++) {
+ if (conf_acct_delay_time) {
+ time(&ts);
+ rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", ts - rpd->acct_timestamp);
+ if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret))
+ goto out_err;
+ }
- if (rpd->acct_req->reply->id != rpd->acct_req->pack->id || rpd->acct_req->reply->code != CODE_ACCOUNTING_RESPONSE) {
- rad_packet_free(rpd->acct_req->reply);
- rpd->acct_req->reply = NULL;
- rpd->acct_req->pack->id++;
- __sync_add_and_fetch(&stat_acct_lost, 1);
- stat_accm_add(stat_acct_lost_1m, 1);
- stat_accm_add(stat_acct_lost_5m, 1);
- } else
+ if (rad_req_send(rpd->acct_req, conf_verbose))
+ goto out_err;
+
+ __sync_add_and_fetch(&stat_acct_sent, 1);
+
+ rad_req_wait(rpd->acct_req, conf_timeout);
+
+ if (!rpd->acct_req->reply) {
+ if (conf_acct_delay_time)
+ rpd->acct_req->pack->id++;
+ __sync_add_and_fetch(&stat_acct_lost, 1);
+ stat_accm_add(stat_acct_lost_1m, 1);
+ stat_accm_add(stat_acct_lost_5m, 1);
+ continue;
+ }
+
+ dt = (rpd->acct_req->reply->tv.tv_sec - rpd->acct_req->pack->tv.tv_sec) * 1000 +
+ (rpd->acct_req->reply->tv.tv_usec - rpd->acct_req->pack->tv.tv_usec) / 1000;
+ stat_accm_add(stat_acct_query_1m, dt);
+ stat_accm_add(stat_acct_query_5m, dt);
+
+ if (rpd->acct_req->reply->id != rpd->acct_req->pack->id || rpd->acct_req->reply->code != CODE_ACCOUNTING_RESPONSE) {
+ rad_packet_free(rpd->acct_req->reply);
+ rpd->acct_req->reply = NULL;
+ rpd->acct_req->pack->id++;
+ __sync_add_and_fetch(&stat_acct_lost, 1);
+ stat_accm_add(stat_acct_lost_1m, 1);
+ stat_accm_add(stat_acct_lost_5m, 1);
+ } else
+ break;
+ }
+
+ rad_server_req_exit(rpd->acct_req);
+
+ if (rpd->acct_req->reply)
break;
- }
- if (!rpd->acct_req->reply) {
- log_ppp_warn("radius:acct_start: no response\n");
- goto out_err;
+ rad_server_fail(rpd->acct_req->serv);
+ if (rad_server_realloc(rpd->acct_req, 1)) {
+ log_ppp_warn("radius:acct_start: no servers available\n");
+ goto out_err;
+ }
+ if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret))
+ goto out_err;
}
-
+
rpd->acct_req->hnd.read = rad_acct_read;
triton_md_register_handler(rpd->ppp->ctrl->ctx, &rpd->acct_req->hnd);
@@ -278,6 +346,9 @@ void rad_acct_stop(struct radius_pd_t *rpd)
time_t ts;
unsigned int dt;
+ if (!rpd->acct_req || !rpd->acct_req->serv)
+ return;
+
if (rpd->acct_interim_timer.tpd)
triton_timer_del(&rpd->acct_interim_timer);
@@ -315,7 +386,7 @@ void rad_acct_stop(struct radius_pd_t *rpd)
}
rad_packet_change_val(rpd->acct_req->pack, NULL, "Acct-Status-Type", "Stop");
req_set_stat(rpd->acct_req, rpd->ppp);
- req_set_RA(rpd->acct_req, conf_acct_secret);
+ req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret);
/// !!! rad_req_add_val(rpd->acct_req, "Acct-Terminate-Cause", "");
if (rpd->acct_req->reply) {
@@ -325,39 +396,63 @@ void rad_acct_stop(struct radius_pd_t *rpd)
time(&rpd->acct_timestamp);
- for(i = 0; i < conf_max_try; i++) {
- time(&ts);
- rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", ts - rpd->acct_timestamp);
- rpd->acct_req->pack->id++;
- if (req_set_RA(rpd->acct_req, conf_acct_secret))
- break;
- if (rad_req_send(rpd->acct_req, conf_verbose))
- break;
- __sync_add_and_fetch(&stat_acct_sent, 1);
- rad_req_wait(rpd->acct_req, conf_timeout);
- if (!rpd->acct_req->reply) {
- __sync_add_and_fetch(&stat_acct_lost, 1);
- stat_accm_add(stat_acct_lost_1m, 1);
- stat_accm_add(stat_acct_lost_5m, 1);
+ while (1) {
+
+ if (rad_server_req_enter(rpd->acct_req)) {
+ if (rad_server_realloc(rpd->acct_req, 1)) {
+ log_ppp_warn("radius:acct_stop: no servers available\n");
+ break;
+ }
+ req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret);
continue;
}
- dt = (rpd->acct_req->reply->tv.tv_sec - rpd->acct_req->pack->tv.tv_sec) * 1000 +
- (rpd->acct_req->reply->tv.tv_usec - rpd->acct_req->pack->tv.tv_usec) / 1000;
- stat_accm_add(stat_acct_query_1m, dt);
- stat_accm_add(stat_acct_query_5m, dt);
+ for(i = 0; i < conf_max_try; i++) {
+ if (conf_acct_delay_time) {
+ time(&ts);
+ rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", ts - rpd->acct_timestamp);
+ rpd->acct_req->pack->id++;
+ if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret))
+ break;
+ }
+ if (rad_req_send(rpd->acct_req, conf_verbose))
+ break;
+ __sync_add_and_fetch(&stat_acct_sent, 1);
+ rad_req_wait(rpd->acct_req, conf_timeout);
+ if (!rpd->acct_req->reply) {
+ __sync_add_and_fetch(&stat_acct_lost, 1);
+ stat_accm_add(stat_acct_lost_1m, 1);
+ stat_accm_add(stat_acct_lost_5m, 1);
+ continue;
+ }
+
+ dt = (rpd->acct_req->reply->tv.tv_sec - rpd->acct_req->pack->tv.tv_sec) * 1000 +
+ (rpd->acct_req->reply->tv.tv_usec - rpd->acct_req->pack->tv.tv_usec) / 1000;
+ stat_accm_add(stat_acct_query_1m, dt);
+ stat_accm_add(stat_acct_query_5m, dt);
+
+ if (rpd->acct_req->reply->id != rpd->acct_req->pack->id || rpd->acct_req->reply->code != CODE_ACCOUNTING_RESPONSE) {
+ rad_packet_free(rpd->acct_req->reply);
+ rpd->acct_req->reply = NULL;
+ __sync_add_and_fetch(&stat_acct_lost, 1);
+ stat_accm_add(stat_acct_lost_1m, 1);
+ stat_accm_add(stat_acct_lost_5m, 1);
+ } else
+ break;
+ }
- if (rpd->acct_req->reply->id != rpd->acct_req->pack->id || rpd->acct_req->reply->code != CODE_ACCOUNTING_RESPONSE) {
- rad_packet_free(rpd->acct_req->reply);
- rpd->acct_req->reply = NULL;
- __sync_add_and_fetch(&stat_acct_lost, 1);
- stat_accm_add(stat_acct_lost_1m, 1);
- stat_accm_add(stat_acct_lost_5m, 1);
- } else
+ rad_server_req_exit(rpd->acct_req);
+
+ if (rpd->acct_req->reply)
break;
+
+ rad_server_fail(rpd->acct_req->serv);
+ if (rad_server_realloc(rpd->acct_req, 1)) {
+ log_ppp_warn("radius:acct_stop: no servers available\n");
+ break;
+ }
+ req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret);
}
- if (!rpd->acct_req->reply)
- log_ppp_warn("radius:acct_stop: no response\n");
rad_req_free(rpd->acct_req);
rpd->acct_req = NULL;
diff --git a/accel-pppd/radius/auth.c b/accel-pppd/radius/auth.c
index 70ecbbe..e4810fa 100644
--- a/accel-pppd/radius/auth.c
+++ b/accel-pppd/radius/auth.c
@@ -30,7 +30,7 @@ static int decrypt_chap_mppe_keys(struct rad_req_t *req, struct rad_attr_t *attr
memcpy(plain, attr->val.octets, 32);
MD5_Init(&md5_ctx);
- MD5_Update(&md5_ctx, conf_auth_secret, strlen(conf_auth_secret));
+ MD5_Update(&md5_ctx, req->serv->auth_secret, strlen(req->serv->auth_secret));
MD5_Update(&md5_ctx, req->pack->buf + 4, 16);
MD5_Final(md5, &md5_ctx);
@@ -38,7 +38,7 @@ static int decrypt_chap_mppe_keys(struct rad_req_t *req, struct rad_attr_t *attr
plain[i] ^= md5[i];
MD5_Init(&md5_ctx);
- MD5_Update(&md5_ctx, conf_auth_secret, strlen(conf_auth_secret));
+ MD5_Update(&md5_ctx, req->serv->auth_secret, strlen(req->serv->auth_secret));
MD5_Update(&md5_ctx, attr->val.octets, 16);
MD5_Final(md5, &md5_ctx);
@@ -74,7 +74,7 @@ static int decrypt_mppe_key(struct rad_req_t *req, struct rad_attr_t *attr, uint
}
MD5_Init(&md5_ctx);
- MD5_Update(&md5_ctx, conf_auth_secret, strlen(conf_auth_secret));
+ MD5_Update(&md5_ctx, req->serv->auth_secret, strlen(req->serv->auth_secret));
MD5_Update(&md5_ctx, req->pack->buf + 4, 16);
MD5_Update(&md5_ctx, attr->val.octets, 2);
MD5_Final(md5, &md5_ctx);
@@ -90,7 +90,7 @@ static int decrypt_mppe_key(struct rad_req_t *req, struct rad_attr_t *attr, uint
}
MD5_Init(&md5_ctx);
- MD5_Update(&md5_ctx, conf_auth_secret, strlen(conf_auth_secret));
+ MD5_Update(&md5_ctx, req->serv->auth_secret, strlen(req->serv->auth_secret));
MD5_Update(&md5_ctx, attr->val.octets + 2, 16);
MD5_Final(md5, &md5_ctx);
@@ -145,42 +145,71 @@ static uint8_t* encrypt_password(const char *passwd, const char *secret, const u
static int rad_auth_send(struct rad_req_t *req)
{
int i;
- struct timeval tv;
+ struct timeval tv, tv2;
unsigned int dt;
+ int timeout;
- for(i = 0; i < conf_max_try; i++) {
- __sync_add_and_fetch(&stat_auth_sent, 1);
- gettimeofday(&tv, NULL);
- if (rad_req_send(req, conf_verbose))
- goto out;
+ while (1) {
+ if (rad_server_req_enter(req)) {
+ if (rad_server_realloc(req, 0)) {
+ log_ppp_warn("radius: no available servers\n");
+ break;
+ }
+ continue;
+ }
- rad_req_wait(req, conf_timeout);
+ for(i = 0; i < conf_max_try; i++) {
+ __sync_add_and_fetch(&stat_auth_sent, 1);
+ gettimeofday(&tv, NULL);
+ if (rad_req_send(req, conf_verbose))
+ goto out;
- if (req->reply) {
- if (req->reply->id != req->pack->id) {
- __sync_add_and_fetch(&stat_auth_lost, 1);
- stat_accm_add(stat_auth_lost_1m, 1);
- stat_accm_add(stat_auth_lost_5m, 1);
- rad_packet_free(req->reply);
- req->reply = NULL;
- } else {
+ timeout = conf_timeout;
+
+ while (timeout > 0) {
+
+ rad_req_wait(req, timeout);
+
+ if (req->reply) {
+ if (req->reply->id != req->pack->id) {
+ rad_packet_free(req->reply);
+ req->reply = NULL;
+ gettimeofday(&tv2, NULL);
+ timeout = conf_timeout - ((tv2.tv_sec - tv.tv_sec) * 1000 + (tv2.tv_usec - tv.tv_usec) / 1000);
+ } else
+ break;
+ } else
+ break;
+ }
+
+ if (req->reply) {
dt = (req->reply->tv.tv_sec - tv.tv_sec) * 1000 + (req->reply->tv.tv_usec - tv.tv_usec) / 1000;
stat_accm_add(stat_auth_query_1m, dt);
stat_accm_add(stat_auth_query_5m, dt);
break;
+ } else {
+ __sync_add_and_fetch(&stat_auth_lost, 1);
+ stat_accm_add(stat_auth_lost_1m, 1);
+ stat_accm_add(stat_auth_lost_5m, 1);
}
- } else
- __sync_add_and_fetch(&stat_auth_lost, 1);
- stat_accm_add(stat_auth_lost_1m, 1);
- stat_accm_add(stat_auth_lost_5m, 1);
- }
+ }
+
+ rad_server_req_exit(req);
- if (!req->reply)
- log_ppp_warn("radius:auth: no response\n");
- else if (req->reply->code == CODE_ACCESS_ACCEPT) {
- if (rad_proc_attrs(req))
- return PWDB_DENIED;
- return PWDB_SUCCESS;
+ if (!req->reply) {
+ rad_server_fail(req->serv);
+ if (rad_server_realloc(req, 0)) {
+ log_ppp_warn("radius: no available servers\n");
+ break;
+ }
+ } else {
+ if (req->reply->code == CODE_ACCESS_ACCEPT) {
+ if (rad_proc_attrs(req))
+ return PWDB_DENIED;
+ return PWDB_SUCCESS;
+ } else
+ break;
+ }
}
out:
@@ -200,7 +229,7 @@ int rad_auth_pap(struct radius_pd_t *rpd, const char *username, va_list args)
if (!req)
return PWDB_DENIED;
- epasswd = encrypt_password(passwd, conf_auth_secret, req->RA, &epasswd_len);
+ epasswd = encrypt_password(passwd, req->serv->auth_secret, req->RA, &epasswd_len);
if (!epasswd)
goto out;
@@ -253,20 +282,16 @@ int rad_auth_chap_md5(struct radius_pd_t *rpd, const char *username, va_list arg
if (challenge_len == 16)
memcpy(rpd->auth_req->RA, challenge, 16);
- else {
- if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "CHAP-Challenge", challenge, challenge_len))
+ if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "CHAP-Challenge", challenge, challenge_len))
goto out;
- }
if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "CHAP-Password", chap_password, 17))
goto out;
} else {
if (challenge_len == 16)
memcpy(rpd->auth_req->RA, challenge, 16);
- else {
- if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "CHAP-Challenge", challenge, challenge_len))
+ if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "CHAP-Challenge", challenge, challenge_len))
goto out;
- }
if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "CHAP-Password", chap_password, 17))
goto out;
@@ -354,6 +379,7 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar
{
int r = PWDB_DENIED;
uint8_t response[50];
+ struct rad_attr_t *ra;
int id = va_arg(args, int);
const uint8_t *challenge = va_arg(args, const uint8_t *);
@@ -361,6 +387,7 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar
const uint8_t *lm_response = va_arg(args, const uint8_t *);
const uint8_t *nt_response = va_arg(args, const uint8_t *);
int flags = va_arg(args, int);
+ char **mschap_error = va_arg(args, char **);
response[0] = id;
response[1] = flags;
@@ -402,6 +429,7 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar
if (rad_packet_add_str(rpd->auth_req->pack, NULL, "Acct-Session-Id", rpd->ppp->sessionid))
goto out;
+
r = rad_auth_send(rpd->auth_req);
if (r == PWDB_SUCCESS) {
struct ev_radius_t ev = {
@@ -412,6 +440,10 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar
triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev);
setup_mppe(rpd->auth_req, challenge);
rpd->auth_req->pack->id++;
+ } else if (rpd->auth_req->reply) {
+ ra = rad_packet_find_attr(rpd->auth_req->reply, "Microsoft", "MS-CHAP-Error");
+ if (ra)
+ *mschap_error = ra->val.string;
}
return r;
@@ -435,6 +467,8 @@ int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list ar
const uint8_t *response = va_arg(args, const uint8_t *);
int flags = va_arg(args, int);
uint8_t *authenticator = va_arg(args, uint8_t *);
+ char **mschap_error = va_arg(args, char **);
+ char **reply_msg = va_arg(args, char **);
mschap_response[0] = id;
mschap_response[1] = flags;
@@ -495,8 +529,17 @@ int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list ar
triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev);
setup_mppe(rpd->auth_req, NULL);
rpd->auth_req->pack->id++;
+ } else if (rpd->auth_req->reply) {
+ ra = rad_packet_find_attr(rpd->auth_req->reply, "Microsoft", "MS-CHAP-Error");
+ if (ra)
+ *mschap_error = ra->val.string;
+ ra = rad_packet_find_attr(rpd->auth_req->reply, NULL, "Reply-Message");
+ if (ra)
+ *reply_msg = ra->val.string;
}
+
+
return r;
out:
rad_req_free(rpd->auth_req);
diff --git a/accel-pppd/radius/dm_coa.c b/accel-pppd/radius/dm_coa.c
index 366bb41..481f2f5 100644
--- a/accel-pppd/radius/dm_coa.c
+++ b/accel-pppd/radius/dm_coa.c
@@ -256,7 +256,7 @@ static struct dm_coa_serv_t serv = {
.hnd.read = dm_coa_read,
};
-static void __init init(void)
+static void init(void)
{
struct sockaddr_in addr;
@@ -293,3 +293,5 @@ static void __init init(void)
triton_md_enable_handler(&serv.hnd, MD_MODE_READ);
triton_context_wakeup(&serv.ctx);
}
+
+DEFINE_INIT(52, init);
diff --git a/accel-pppd/radius/packet.c b/accel-pppd/radius/packet.c
index b6230d6..892cc49 100644
--- a/accel-pppd/radius/packet.c
+++ b/accel-pppd/radius/packet.c
@@ -648,9 +648,11 @@ int rad_packet_send(struct rad_packet_t *pack, int fd, struct sockaddr_in *addr)
return 0;
}
-static void __init init(void)
+static void init(void)
{
attr_pool = mempool_create(sizeof(struct rad_attr_t));
packet_pool = mempool_create(sizeof(struct rad_packet_t));
buf_pool = mempool_create(REQ_LENGTH_MAX);
}
+
+DEFINE_INIT(50, init);
diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c
index 64ce90f..5f507cb 100644
--- a/accel-pppd/radius/radius.c
+++ b/accel-pppd/radius/radius.c
@@ -25,7 +25,8 @@
int conf_max_try = 3;
int conf_timeout = 3;
-int conf_acct_timeout = 600;
+int conf_acct_timeout = 3;
+int conf_acct_delay_time;
char *conf_nas_identifier;
in_addr_t conf_nas_ip_address;
in_addr_t conf_gw_ip_address;
@@ -33,14 +34,6 @@ in_addr_t conf_bind;
int conf_verbose;
int conf_interim_verbose;
-in_addr_t conf_auth_server;
-int conf_auth_server_port = 1812;
-char *conf_auth_secret;
-
-in_addr_t conf_acct_server;
-int conf_acct_server_port = 1813;
-char *conf_acct_secret;
-
in_addr_t conf_dm_coa_server;
int conf_dm_coa_port = 3799;
char *conf_dm_coa_secret;
@@ -49,6 +42,9 @@ int conf_sid_in_auth;
int conf_require_nas_ident;
int conf_acct_interim_interval;
+int conf_accounting;
+int conf_fail_time = 60;
+
unsigned long stat_auth_sent;
unsigned long stat_auth_lost;
unsigned long stat_acct_sent;
@@ -471,7 +467,7 @@ static int load_config(void)
conf_timeout = atoi(opt);
opt = conf_get_opt("radius", "acct-timeout");
- if (opt && atoi(opt) > 0)
+ if (opt && atoi(opt) >= 0)
conf_acct_timeout = atoi(opt);
opt = conf_get_opt("radius", "verbose");
@@ -504,27 +500,6 @@ static int load_config(void)
else if (conf_nas_ip_address)
conf_bind = conf_nas_ip_address;
- opt = conf_get_opt("radius", "auth-server");
- if (!opt)
- opt = conf_get_opt("radius", "auth_server");
- if (!opt) {
- log_emerg("radius: auth-server not specified\n");
- return -1;
- } else if (parse_server(opt, &conf_auth_server, &conf_auth_server_port, &conf_auth_secret)) {
- log_emerg("radius: failed to parse auth_server\n");
- return -1;
- }
-
- opt = conf_get_opt("radius", "acct-server");
- if (!opt)
- opt = conf_get_opt("radius", "acct_server");
- if (!opt)
- log_emerg("radius: acct-server not specified\n");
- if (opt && parse_server(opt, &conf_acct_server, &conf_acct_server_port, &conf_acct_secret)) {
- log_emerg("radius: failed to parse acct_server\n");
- return -1;
- }
-
opt = conf_get_opt("radius", "dae-server");
if (opt && parse_server(opt, &conf_dm_coa_server, &conf_dm_coa_port, &conf_dm_coa_secret)) {
log_emerg("radius: failed to parse dae-server\n");
@@ -532,21 +507,29 @@ static int load_config(void)
}
opt = conf_get_opt("radius", "sid_in_auth");
- if (opt && atoi(opt) > 0)
- conf_sid_in_auth = 1;
+ if (opt)
+ conf_sid_in_auth = atoi(opt);
opt = conf_get_opt("radius", "require-nas-identification");
- if (opt && atoi(opt) > 0)
- conf_require_nas_ident = 1;
+ if (opt)
+ conf_require_nas_ident = atoi(opt);
opt = conf_get_opt("radius", "acct-interim-interval");
if (opt && atoi(opt) > 0)
conf_acct_interim_interval = atoi(opt);
+ opt = conf_get_opt("radius", "acct-delay-time");
+ if (opt)
+ conf_acct_delay_time = atoi(opt);
+
+ opt = conf_get_opt("radius", "fail-time");
+ if (opt)
+ conf_fail_time = atoi(opt);
+
return 0;
}
-static void __init radius_init(void)
+static void radius_init(void)
{
char *opt;
char *dict = DICTIONARY;
@@ -590,3 +573,4 @@ static void __init radius_init(void)
stat_interim_query_5m = stat_accm_create(5 * 60);
}
+DEFINE_INIT(51, radius_init);
diff --git a/accel-pppd/radius/radius_p.h b/accel-pppd/radius/radius_p.h
index 5450b7d..578c777 100644
--- a/accel-pppd/radius/radius_p.h
+++ b/accel-pppd/radius/radius_p.h
@@ -10,6 +10,8 @@
#include "ppp.h"
#include "ipdb.h"
+struct rad_server_t;
+
struct radius_pd_t
{
struct list_head entry;
@@ -47,22 +49,44 @@ struct radius_pd_t
struct rad_req_t
{
+ struct list_head entry;
struct triton_context_t ctx;
struct triton_md_handler_t hnd;
struct triton_timer_t timeout;
uint8_t RA[16];
struct rad_packet_t *pack;
struct rad_packet_t *reply;
+
+ struct radius_pd_t *rpd;
+ struct rad_server_t *serv;
+
in_addr_t server_addr;
int server_port;
+};
- struct radius_pd_t *rpd;
+struct rad_server_t
+{
+ struct list_head entry;
+ in_addr_t auth_addr;
+ int auth_port;
+ char *auth_secret;
+ in_addr_t acct_addr;
+ int acct_port;
+ char *acct_secret;
+ int max_req_cnt;
+ int req_cnt;
+ struct list_head req_queue;
+ int client_cnt;
+ time_t fail_time;
+ int conf_fail_time;
+ pthread_mutex_t lock;
};
extern int conf_max_try;
extern int conf_timeout;
extern int conf_acct_timeout;
+extern int conf_acct_delay_time;
extern int conf_verbose;
extern int conf_interim_verbose;
extern char *conf_nas_identifier;
@@ -70,17 +94,14 @@ extern in_addr_t conf_nas_ip_address;
extern in_addr_t conf_bind;
extern in_addr_t conf_gw_ip_address;
extern in_addr_t conf_auth_server;
-extern char *conf_auth_secret;
-extern int conf_auth_server_port;
-extern in_addr_t conf_acct_server;
-extern char *conf_acct_secret;
-extern int conf_acct_server_port;
extern char *conf_dm_coa_secret;
extern int conf_sid_in_auth;
extern int conf_require_nas_ident;
extern in_addr_t conf_dm_coa_server;
extern int conf_dm_coa_port;
extern int conf_acct_interim_interval;
+extern int conf_accounting;
+extern int conf_fail_time;
extern unsigned long stat_auth_sent;
extern unsigned long stat_auth_lost;
@@ -122,6 +143,13 @@ int rad_packet_send(struct rad_packet_t *pck, int fd, struct sockaddr_in *addr);
void dm_coa_cancel(struct radius_pd_t *pd);
+struct rad_server_t *rad_server_get(int);
+void rad_server_put(struct rad_server_t *);
+int rad_server_req_enter(struct rad_req_t *);
+void rad_server_req_exit(struct rad_req_t *);
+int rad_server_realloc(struct rad_req_t *, int);
+void rad_server_fail(struct rad_server_t *);
+
struct stat_accm_t;
struct stat_accm_t *stat_accm_create(unsigned int time);
void stat_accm_add(struct stat_accm_t *, unsigned int);
diff --git a/accel-pppd/radius/req.c b/accel-pppd/radius/req.c
index a384f23..b45a601 100644
--- a/accel-pppd/radius/req.c
+++ b/accel-pppd/radius/req.c
@@ -32,8 +32,12 @@ struct rad_req_t *rad_req_alloc(struct radius_pd_t *rpd, int code, const char *u
req->hnd.fd = -1;
req->ctx.before_switch = log_switch;
- req->server_addr = conf_auth_server;
- req->server_port = conf_auth_server_port;
+ req->serv = rad_server_get(code == CODE_ACCOUNTING_REQUEST);
+ if (!req->serv)
+ goto out_err;
+
+ req->server_addr = req->serv->auth_addr;
+ req->server_port = req->serv->auth_port;
while (1) {
if (read(urandom_fd, req->RA, 16) != 16) {
@@ -97,8 +101,8 @@ out_err:
int rad_req_acct_fill(struct rad_req_t *req)
{
- req->server_addr = conf_acct_server;
- req->server_port = conf_acct_server_port;
+ req->server_addr = req->serv->acct_addr;
+ req->server_port = req->serv->acct_port;
memset(req->RA, 0, sizeof(req->RA));
@@ -122,8 +126,10 @@ int rad_req_acct_fill(struct rad_req_t *req)
return -1;
if (rad_packet_add_int(req->pack, NULL, "Acct-Output-Gigawords", 0))
return -1;
- if (rad_packet_add_int(req->pack, NULL, "Acct-Delay-Time", 0))
- return -1;
+ if (conf_acct_delay_time) {
+ if (rad_packet_add_int(req->pack, NULL, "Acct-Delay-Time", 0))
+ return -1;
+ }
if (rad_packet_add_ipaddr(req->pack, NULL, "Framed-IP-Address", req->rpd->ppp->peer_ipaddr))
return -1;
@@ -132,6 +138,8 @@ int rad_req_acct_fill(struct rad_req_t *req)
void rad_req_free(struct rad_req_t *req)
{
+ if (req->serv)
+ rad_server_put(req->serv);
if (req->hnd.fd >= 0 )
close(req->hnd.fd);
if (req->pack)
@@ -209,7 +217,8 @@ out_err:
static void req_wakeup(struct rad_req_t *req)
{
struct triton_context_t *ctx = req->rpd->ppp->ctrl->ctx;
- triton_timer_del(&req->timeout);
+ if (req->timeout.tpd)
+ triton_timer_del(&req->timeout);
triton_md_unregister_handler(&req->hnd);
triton_context_unregister(&req->ctx);
triton_context_wakeup(ctx);
@@ -267,7 +276,7 @@ int rad_req_wait(struct rad_req_t *req, int timeout)
return 0;
}
-void __init req_init(void)
+static void req_init(void)
{
urandom_fd = open("/dev/urandom", O_RDONLY);
if (!urandom_fd) {
@@ -275,3 +284,5 @@ void __init req_init(void)
_exit(EXIT_FAILURE);
}
}
+
+DEFINE_INIT(50, req_init);
diff --git a/accel-pppd/radius/serv.c b/accel-pppd/radius/serv.c
new file mode 100644
index 0000000..bcdce14
--- /dev/null
+++ b/accel-pppd/radius/serv.c
@@ -0,0 +1,331 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sched.h>
+#include <time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "log.h"
+#include "triton.h"
+#include "radius_p.h"
+
+#include "memdebug.h"
+
+static LIST_HEAD(serv_list);
+
+struct rad_server_t *rad_server_get(int type)
+{
+ struct rad_server_t *s, *s0 = NULL;
+ struct timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ list_for_each_entry(s, &serv_list, entry) {
+ if (s->fail_time && ts.tv_sec < s->fail_time)
+ continue;
+
+ if (type == 0 && !s->auth_addr)
+ continue;
+ else if (type == 1 && !s->acct_addr)
+ continue;
+
+ if (!s0) {
+ s0 = s;
+ continue;
+ }
+
+ if (s->client_cnt < s0->client_cnt)
+ s0 = s;
+ }
+
+ if (!s0)
+ return NULL;
+
+ __sync_add_and_fetch(&s0->client_cnt, 1);
+
+ return s0;
+}
+
+void rad_server_put(struct rad_server_t *s)
+{
+ __sync_sub_and_fetch(&s->client_cnt, 1);
+}
+
+int rad_server_req_enter(struct rad_req_t *req)
+{
+ struct timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ if (!req->serv->max_req_cnt)
+ return 0;
+
+ pthread_mutex_lock(&req->serv->lock);
+
+ if (ts.tv_sec < req->serv->fail_time) {
+ pthread_mutex_unlock(&req->serv->lock);
+ return -1;
+ }
+
+ if (req->serv->req_cnt >= req->serv->max_req_cnt) {
+ list_add_tail(&req->entry, &req->serv->req_queue);
+ pthread_mutex_unlock(&req->serv->lock);
+ triton_context_schedule();
+ pthread_mutex_lock(&req->serv->lock);
+
+ if (ts.tv_sec < req->serv->fail_time) {
+ pthread_mutex_unlock(&req->serv->lock);
+ return -1;
+ }
+ }
+
+ req->serv->req_cnt++;
+ pthread_mutex_unlock(&req->serv->lock);
+
+ return 0;
+}
+
+void rad_server_req_exit(struct rad_req_t *req)
+{
+ struct rad_req_t *r = NULL;
+
+ if (!req->serv->max_req_cnt)
+ return;
+
+ pthread_mutex_lock(&req->serv->lock);
+ req->serv->req_cnt--;
+ if (req->serv->req_cnt < req->serv->max_req_cnt && !list_empty(&req->serv->req_queue)) {
+ r = list_entry(req->serv->req_queue.next, typeof(*r), entry);
+ list_del(&r->entry);
+ }
+ pthread_mutex_unlock(&req->serv->lock);
+
+ if (r)
+ triton_context_wakeup(r->rpd->ppp->ctrl->ctx);
+}
+
+int rad_server_realloc(struct rad_req_t *req, int type)
+{
+ if (req->hnd.fd != -1) {
+ close(req->hnd.fd);
+ req->hnd.fd = -1;
+ }
+
+ if (req->serv)
+ rad_server_put(req->serv);
+
+ req->serv = rad_server_get(type);
+
+ if (!req->serv)
+ return -1;
+
+ if (type) {
+ req->server_addr = req->serv->acct_addr;
+ req->server_port = req->serv->acct_port;
+ } else {
+ req->server_addr = req->serv->auth_addr;
+ req->server_port = req->serv->auth_port;
+ }
+
+ return 0;
+}
+
+void rad_server_fail(struct rad_server_t *s)
+{
+ struct rad_req_t *r;
+ struct timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ pthread_mutex_lock(&s->lock);
+
+ if (ts.tv_sec > s->fail_time) {
+ s->fail_time = ts.tv_sec + s->conf_fail_time;
+ log_ppp_warn("radius: server not responding\n");
+ log_warn("radius: server noy responding\n");
+ }
+
+ while (!list_empty(&s->req_queue)) {
+ r = list_entry(s->req_queue.next, typeof(*r), entry);
+ list_del(&r->entry);
+ triton_context_wakeup(r->rpd->ppp->ctrl->ctx);
+ }
+ pthread_mutex_unlock(&s->lock);
+}
+
+static void __add_server(struct rad_server_t *s)
+{
+ INIT_LIST_HEAD(&s->req_queue);
+ pthread_mutex_init(&s->lock, NULL);
+ s->conf_fail_time = conf_fail_time;
+ list_add_tail(&s->entry, &serv_list);
+}
+
+static int parse_server_old(const char *opt, in_addr_t *addr, int *port, char **secret)
+{
+ char *str = _strdup(opt);
+ char *p1, *p2;
+
+ p1 = strstr(str, ":");
+ p2 = strstr(str, ",");
+
+ if (p1)
+ *p1 = 0;
+ if (p2)
+ *p2 = 0;
+ else
+ return -1;
+
+ *addr = inet_addr(str);
+
+ if (p1) {
+ *port = atoi(p1 + 1);
+ if (*port <=0 )
+ return -1;
+ }
+
+ p1 = _strdup(p2 + 1);
+ p2 = *secret;
+ *secret = p1;
+ if (p2)
+ _free(p2);
+
+ _free(str);
+
+ return 0;
+}
+
+static void add_server_old(void)
+{
+ const char *opt;
+ struct rad_server_t *s = _malloc(sizeof(*s));
+
+ memset(s, 0, sizeof(*s));
+
+ opt = conf_get_opt("radius", "auth-server");
+ if (opt) {
+ if (parse_server_old(opt, &s->auth_addr, &s->auth_port, &s->auth_secret)) {
+ log_emerg("radius: failed to parse 'auth-server'\n");
+ goto out;
+ }
+ }
+
+ opt = conf_get_opt("radius", "acct-server");
+ if (opt) {
+ if (parse_server_old(opt, &s->acct_addr, &s->acct_port, &s->acct_secret)) {
+ log_emerg("radius: failed to parse 'acct-server'\n");
+ goto out;
+ }
+ conf_accounting = 1;
+ }
+
+ if (s->auth_addr || s->acct_addr) {
+ __add_server(s);
+ return;
+ }
+
+out:
+ _free(s);
+}
+
+static int parse_server(const char *_opt, struct rad_server_t *s)
+{
+ char *opt = _strdup(_opt);
+ char *ptr1, *ptr2, *ptr3, *endptr;
+
+ ptr1 = strchr(opt, ',');
+ if (!ptr1)
+ goto out;
+
+ ptr2 = strchr(ptr1 + 1, ',');
+
+ if (ptr2)
+ ptr3 = strchr(ptr2 + 1, ',');
+ else
+ ptr3 = NULL;
+
+ *ptr1 = 0;
+ if (ptr2)
+ *ptr2 = 0;
+ if (ptr3)
+ *ptr3 = 0;
+
+ s->auth_addr = s->acct_addr = inet_addr(opt);
+
+ if (ptr2) {
+ if (ptr2[1]) {
+ s->auth_port = strtol(ptr2 + 1, &endptr, 10);
+ if (*endptr)
+ goto out;
+ }
+ if (!s->auth_port)
+ s->auth_addr = 0;
+ } else
+ s->auth_port = 1812;
+
+ if (ptr3) {
+ if (ptr3[1]) {
+ s->acct_port = strtol(ptr3 + 1, &endptr, 10);
+ if (*endptr)
+ goto out;
+ }
+ if (!s->acct_port)
+ s->acct_addr = 0;
+ } else
+ s->acct_port = 1813;
+
+ if (!s->auth_addr && !s->acct_addr)
+ goto out;
+
+ if (s->auth_addr)
+ s->auth_secret = _strdup(ptr1 + 1);
+
+ if (s->acct_addr) {
+ s->acct_secret = _strdup(ptr1 + 1);
+ conf_accounting = 1;
+ }
+
+ return 0;
+
+out:
+ _free(opt);
+
+ return -1;
+}
+
+static void add_server(const char *opt)
+{
+ struct rad_server_t *s = _malloc(sizeof(*s));
+
+ memset(s, 0, sizeof(*s));
+
+ if (parse_server(opt, s)) {
+ log_emerg("radius: failed to parse '%s'\n", opt);
+ _free(s);
+ return;
+ }
+
+ __add_server(s);
+}
+
+static void init(void)
+{
+ struct conf_sect_t *s = conf_get_section("radius");
+ struct conf_option_t *opt;
+
+ add_server_old();
+
+
+ list_for_each_entry(opt, &s->items, entry) {
+ if (strcmp(opt->name, "server"))
+ continue;
+ add_server(opt->val);
+ }
+}
+
+DEFINE_INIT(21, init);
diff --git a/accel-pppd/radius/stat_accm.c b/accel-pppd/radius/stat_accm.c
index 8d4ad3d..34935a1 100644
--- a/accel-pppd/radius/stat_accm.c
+++ b/accel-pppd/radius/stat_accm.c
@@ -38,11 +38,13 @@ struct stat_accm_t *stat_accm_create(unsigned int time)
static void stat_accm_clean(struct stat_accm_t *s)
{
struct item_t *it;
- time_t ts = time(NULL);
+ struct timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
while (!list_empty(&s->items)) {
it = list_entry(s->items.next, typeof(*it), entry);
- if (ts - it->ts > s->time) {
+ if (ts.tv_sec - it->ts > s->time) {
list_del(&it->entry);
--s->items_cnt;
s->total -= it->val;
@@ -55,13 +57,16 @@ static void stat_accm_clean(struct stat_accm_t *s)
void stat_accm_add(struct stat_accm_t *s, unsigned int val)
{
struct item_t *it;
+ struct timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
pthread_mutex_lock(&s->lock);
stat_accm_clean(s);
it = mempool_alloc(item_pool);
- it->ts = time(NULL);
+ it->ts = ts.tv_sec;
it->val = val;
list_add_tail(&it->entry, &s->items);
++s->items_cnt;
@@ -90,8 +95,9 @@ unsigned long stat_accm_get_avg(struct stat_accm_t *s)
return val;
}
-static void __init init(void)
+static void init(void)
{
item_pool = mempool_create(sizeof(struct item_t));
}
+DEFINE_INIT(50, init);
diff --git a/accel-pppd/triton/triton.c b/accel-pppd/triton/triton.c
index 0740591..aa2183e 100644
--- a/accel-pppd/triton/triton.c
+++ b/accel-pppd/triton/triton.c
@@ -4,6 +4,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <limits.h>
#include <sys/resource.h>
#include "triton_p.h"
@@ -21,6 +22,8 @@ static LIST_HEAD(ctx_queue);
static spinlock_t ctx_list_lock = SPINLOCK_INITIALIZER;
static LIST_HEAD(ctx_list);
+static LIST_HEAD(init_list);
+
static int terminate;
static int need_terminate;
@@ -121,8 +124,12 @@ static void* triton_thread(struct _triton_thread_t *thread)
} else
spin_unlock(&threads_lock);
- if (terminate)
+ if (terminate) {
+ spin_lock(&threads_lock);
+ list_del(&thread->entry);
+ spin_unlock(&threads_lock);
return NULL;
+ }
//printf("thread %p: enter sigwait\n", thread);
sigwait(&set, &sig);
@@ -188,7 +195,8 @@ static void ctx_thread(struct _triton_context_t *ctx)
spin_unlock(&ctx->lock);
__sync_sub_and_fetch(&triton_stat.timer_pending, 1);
read(t->fd, &tt, sizeof(tt));
- t->ud->expire(t->ud);
+ if (t->ud)
+ t->ud->expire(t->ud);
continue;
}
if (!list_empty(&ctx->pending_handlers)) {
@@ -226,17 +234,21 @@ static void ctx_thread(struct _triton_context_t *ctx)
struct _triton_thread_t *create_thread()
{
+ pthread_attr_t attr;
struct _triton_thread_t *thread = _malloc(sizeof(*thread));
if (!thread) {
triton_log_error("out of memory");
return NULL;
}
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN);
+
memset(thread, 0, sizeof(*thread));
pthread_mutex_init(&thread->sleep_lock, NULL);
pthread_cond_init(&thread->sleep_cond, NULL);
pthread_mutex_lock(&thread->sleep_lock);
- if (pthread_create(&thread->thread, NULL, (void*(*)(void*))triton_thread, thread)) {
+ if (pthread_create(&thread->thread, &attr, (void*(*)(void*))triton_thread, thread)) {
triton_log_error("pthread_create: %s", strerror(errno));
return NULL;
}
@@ -505,14 +517,31 @@ static void ru_update(struct triton_timer_t *t)
val = (double)((rusage.ru_utime.tv_sec - ru_utime.tv_sec) * 1000000 + (rusage.ru_utime.tv_usec - ru_utime.tv_usec) +
(rusage.ru_stime.tv_sec - ru_stime.tv_sec) * 1000000 + (rusage.ru_stime.tv_usec - ru_stime.tv_usec)) / dt * 100;
- if (val <= 100)
- triton_stat.cpu = val;
+ triton_stat.cpu = val;
ru_timestamp = ts;
ru_utime = rusage.ru_utime;
ru_stime = rusage.ru_stime;
}
+void __export triton_register_init(int order, void (*func)(void))
+{
+ struct _triton_init_t *i1, *i = _malloc(sizeof(*i));
+ struct list_head *p = init_list.prev;
+
+
+ i->order = order;
+ i->func = func;
+
+ while (p != &init_list) {
+ i1 = list_entry(p, typeof(*i1), entry);
+ if (order > i1->order)
+ break;
+ p = p->prev;
+ }
+ list_add(&i->entry, p);
+}
+
int __export triton_init(const char *conf_file)
{
ctx_pool = mempool_create(sizeof(struct _triton_context_t));
@@ -533,13 +562,24 @@ int __export triton_init(const char *conf_file)
if (event_init())
return -1;
+ triton_context_register(&default_ctx, NULL);
+
return 0;
}
int __export triton_load_modules(const char *mod_sect)
{
+ struct _triton_init_t *i;
+
if (load_modules(mod_sect))
return -1;
+
+ while (!list_empty(&init_list)) {
+ i = list_entry(init_list.next, typeof(*i), entry);
+ i->func();
+ list_del(&i->entry);
+ _free(i);
+ }
return 0;
}
@@ -561,6 +601,7 @@ void __export triton_run()
struct _triton_thread_t *t;
int i;
char *opt;
+ struct timespec ts;
opt = conf_get_opt("core", "thread-count");
if (opt && atoi(opt) > 0)
@@ -575,19 +616,18 @@ void __export triton_run()
pthread_mutex_unlock(&t->sleep_lock);
}
- time(&triton_stat.start_time);
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ triton_stat.start_time = ts.tv_sec;
md_run();
timer_run();
- triton_context_register(&default_ctx, NULL);
triton_context_wakeup(&default_ctx);
}
void __export triton_terminate()
{
struct _triton_context_t *ctx;
- struct _triton_thread_t *t;
int r;
need_terminate = 1;
@@ -603,8 +643,15 @@ void __export triton_terminate()
}
spin_unlock(&ctx_list_lock);
- list_for_each_entry(t, &threads, entry)
- pthread_join(t->thread, NULL);
+ while (1) {
+ spin_lock(&threads_lock);
+ if (list_empty(&threads)) {
+ spin_unlock(&threads_lock);
+ break;
+ }
+ spin_unlock(&threads_lock);
+ sleep(1);
+ }
md_terminate();
timer_terminate();
diff --git a/accel-pppd/triton/triton.h b/accel-pppd/triton/triton.h
index 98ef111..95851c2 100644
--- a/accel-pppd/triton/triton.h
+++ b/accel-pppd/triton/triton.h
@@ -106,6 +106,8 @@ void triton_stop_collect_cpu_usage(void);
int triton_module_loaded(const char *name);
+void triton_register_init(int order, void (*func)(void));
+
#define TRITON_OK 0
#define TRITON_ERR_NOCOMP -1
@@ -137,4 +139,6 @@ void triton_terminate(void);
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
+#define DEFINE_INIT(o, func) static void __init __init__(void){triton_register_init(o,func);}
+
#endif
diff --git a/accel-pppd/triton/triton_p.h b/accel-pppd/triton/triton_p.h
index 235eb70..2eb2e62 100644
--- a/accel-pppd/triton/triton_p.h
+++ b/accel-pppd/triton/triton_p.h
@@ -82,6 +82,14 @@ struct _triton_ctx_call_t
void (*func)(void *);
};
+struct _triton_init_t
+{
+ struct list_head entry;
+
+ int order;
+ void (*func)(void);
+};
+
int log_init(void);
int md_init();
int timer_init();
diff --git a/cmake/cpack.cmake b/cmake/cpack.cmake
index 3de94d7..a8804dc 100644
--- a/cmake/cpack.cmake
+++ b/cmake/cpack.cmake
@@ -2,7 +2,7 @@ INCLUDE(InstallRequiredSystemLibraries)
SET(CPACK_PACKAGE_VERSION_MAJOR "1")
SET(CPACK_PACKAGE_VERSION_MINOR "3")
-SET(CPACK_PACKAGE_VERSION_PATCH "4")
+SET(CPACK_PACKAGE_VERSION_PATCH "7")
SET(CPACK_PACKAGE_NAME "accel-ppp")
SET(CPACK_PACKAGE_CONTACT "Dmitry Kozlov <xeb@mail.ru>")
@@ -12,14 +12,14 @@ SET(CPACK_PACKAGE_VENDOR "Dmitry Kozlov")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
-IF(CPACK_TYPE STREQUAL Debian)
+IF(CPACK_TYPE STREQUAL Debian5)
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.7), libssl0.9.8 (>= 0.9.8), libpcre3 (>= 7.6)")
INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake)
-ENDIF(CPACK_TYPE STREQUAL Debian)
+ENDIF(CPACK_TYPE STREQUAL Debian5)
-IF(CPACK_TYPE STREQUAL Ubuntu)
- SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.12.1), libssl0.9.8 (>= 0.9.8), libpcre3 (>= 8.02), libnl2 (>= 1.99)")
+IF(CPACK_TYPE STREQUAL Debian6)
+ SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libssl0.9.8 (>= 0.9.8), libpcre3 (>= 8.02), libnl2 (>= 1.99)")
INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake)
-ENDIF(CPACK_TYPE STREQUAL Ubuntu)
+ENDIF(CPACK_TYPE STREQUAL Debian6)
INCLUDE(CPack)
diff --git a/cmake/debian/debian.cmake b/cmake/debian/debian.cmake
index b7bd029..0fcc2d5 100644
--- a/cmake/debian/debian.cmake
+++ b/cmake/debian/debian.cmake
@@ -10,7 +10,7 @@ if (BUILD_DRIVER_ONLY)
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "accel-pptp kernel module")
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "")
SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian-kmod/postinst")
- INSTALL(DIRECTORY lib/modules/${DEBIAN_KDIR}/extra)
+ #INSTALL(DIRECTORY lib/modules/${DEBIAN_KDIR}/extra)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/driver/driver/pptp.ko DESTINATION lib/modules/${DEBIAN_KDIR}/extra)
#SET(CPACK_DEBIAN_PACKAGE_DEPENDS "linux-image (= ${LINUX_IMAGE})")
else (BUILD_DRIVER_ONLY)
@@ -21,4 +21,5 @@ else (BUILD_DRIVER_ONLY)
INSTALL(FILES ${CMAKE_HOME_DIRECTORY}/accel-pppd/accel-ppp.conf DESTINATION ${CMAKE_BINARY_DIR}/_CPack_Packages/Linux/DEB/${CPACK_PACKAGE_FILE_NAME}/etc RENAME accel-ppp.conf.dist)
INSTALL(FILES ${CMAKE_HOME_DIRECTORY}/contrib/debian/accel-ppp-init DESTINATION ${CMAKE_BINARY_DIR}/_CPack_Packages/Linux/DEB/${CPACK_PACKAGE_FILE_NAME}/etc/init.d RENAME accel-ppp)
INSTALL(FILES ${CMAKE_HOME_DIRECTORY}/contrib/debian/accel-ppp-default DESTINATION ${CMAKE_BINARY_DIR}/_CPack_Packages/Linux/DEB/${CPACK_PACKAGE_FILE_NAME}/etc/default RENAME accel-ppp)
+
endif (BUILD_DRIVER_ONLY)
diff --git a/cmake/debian/postinst b/cmake/debian/postinst
index a039b4f..5d516cd 100755
--- a/cmake/debian/postinst
+++ b/cmake/debian/postinst
@@ -2,7 +2,7 @@
chmod +x /etc/init.d/accel-ppp
-mkdir /var/log/accel-ppp &> /dev/null
-mkdir /var/run/accel-ppp &> /dev/null
+mkdir /var/log/accel-ppp > /dev/null 2>&1
+mkdir /var/run/accel-ppp > /dev/null 2>&1
exit 0
diff --git a/contrib/gentoo/net-dialup/accel-ppp/accel-ppp-1.3.3.ebuild b/contrib/gentoo/net-dialup/accel-ppp/accel-ppp-1.3.5.ebuild
index 395dd6b..395dd6b 100644
--- a/contrib/gentoo/net-dialup/accel-ppp/accel-ppp-1.3.3.ebuild
+++ b/contrib/gentoo/net-dialup/accel-ppp/accel-ppp-1.3.5.ebuild