A lightweight L2TP protocol client for connecting to L2TP servers and implementing reverse port forwarding (NAT traversal). Pure C implementation with no external dependencies.
- SCCRQ/SCCRP/SCCCN tunnel establishment
- ICRQ/ICRP/ICCN session establishment
- Ns/Nr sequence number management and message retransmission
- Hello heartbeat mechanism
- ZLB ACK acknowledgment
- LCP (Link Control Protocol)
- PAP / CHAP authentication
- IPCP IP address assignment
- SSH-style
-Rparameter:-R [PROTO:]VPN_PORT:[TARGET:]LOCAL_PORT - Protocol selection: TCP (default) or UDP (case-insensitive), e.g.
-R UDP:53:53 - TCP full state machine (SYN/ESTABLISHED/FIN/CLOSE_WAIT/RST)
- TCP retransmit buffer (16KB) with fast retransmit (3 duplicate ACKs) and timeout retransmit
- TCP send window control (16KB)
- Half-close state support (FIN_SENT/CLOSE_WAIT)
- Connection hash lookup, O(1) fast positioning
- Multiple forwarding rules (up to 10)
- IKEv2 key exchange
- ESP AES-256-CBC encryption
- HMAC-SHA-256-128 authentication
- Pure C implementation (no OpenSSL dependency)
- Auto-enabled when PSK is provided via
-k
- Linux / macOS / Windows / Android
- Pure C crypto implementation, no external dependencies
- Windows cross-compiled with MinGW
- Heap-allocated context (avoids Windows stack overflow)
- GCC (Linux/macOS) / MinGW (Windows cross-compile)
- No external library dependencies (crypto algorithms are pure C)
# Linux/macOS
make
# Linux static build
make static
# Windows cross-compile (requires x86_64-w64-mingw32-gcc)
make win64
# Windows static build
make win64-static
# Clean
make clean./l2tp_transfer -s server.com -u username -P password# Forward server port 8080 to local port 80 (TCP)
./l2tp_transfer -s server.com -u user -P pass -R 8080:80
# Specify target address (not 127.0.0.1)
./l2tp_transfer -s server.com -u user -P pass -R 8080:192.168.1.100:80
# Multiple forwarding rules
./l2tp_transfer -s server.com -u user -P pass -R 8080:80 -R 3306:3306
# UDP forwarding
./l2tp_transfer -s server.com -u user -P pass -R UDP:53:53
# Mixed TCP and UDP forwarding
./l2tp_transfer -s server.com -u user -P pass -R 8080:80 -R UDP:53:53IPSec is automatically enabled when a pre-shared key is provided:
./l2tp_transfer -s server.com -u user -P pass -k mypresharedkeyOptions:
-s, --server <IP/hostname> L2TP server address (required)
-u, --username <username> Username for authentication
-P, --password <password> Password for authentication
-k, --psk <pre-shared-key> IPSec pre-shared key (enables IPSec)
-p, --port <port> L2TP server port (default: 1701)
Reverse Port Forwarding (NAT Traversal):
-R, --reverse <spec> Reverse forward: [PROTO:]VPN_PORT:[TARGET:]LOCAL_PORT
PROTO - TCP or UDP (default: TCP, case-insensitive)
VPN_PORT - port on server forwarded to VPN IP
TARGET - local target address (default: 127.0.0.1)
LOCAL_PORT - local service port to forward to
Miscellaneous:
-d, --debug Enable debug output
-h, --help Show this help message
Internet
|
L2TP Server (cts11.ros6.com)
VPN IP: 172.x.x.x
Port: 8080 <--- external access entry
|
L2TP Tunnel (UDP)
|
L2TP Client (this tool)
VPN IP: 172.x.y.z
|
Local Service
127.0.0.1:80 <--- local web service
- The tool connects to the server via L2TP/PPP and obtains a VPN IP address
- The server forwards traffic on the specified port to the client's VPN IP
- Upon receiving a TCP SYN, the client establishes a local connection to the target service
- Bidirectional data is forwarded through the L2TP tunnel, enabling NAT traversal
├── l2tp.h # Core header file and data structures
├── l2tp_main.c # Main loop, message processing
├── l2tp_control.c # L2TP control messages
├── l2tp_ppp.c # PPP protocol implementation
├── l2tp_port_forward.c # Reverse port forwarding (TCP/IP stack)
├── l2tp_ipsec.c/h # IPSec/IKEv2 implementation
├── l2tp_crypto.c/h # Pure C crypto implementation (cross-platform)
├── main.c # Entry point, signal handling
├── getopt_compat.h # Windows getopt_long implementation
└── Makefile # Build configuration
| Platform | Status | Notes |
|---|---|---|
| Linux | ✅ | Native support |
| Windows | ✅ | MinGW cross-compile, pure C crypto |
| macOS | ✅ | POSIX compatible |
| Android | ✅ | NDK build, POSIX compatible |
Cross-compile with Android NDK:
# Set NDK path
export NDK=/path/to/android-ndk
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
# ARM64 build
$TOOLCHAIN/bin/aarch64-linux-android21-clang \
-O2 -I. -o l2tp_transfer_android \
main.c l2tp_main.c l2tp_control.c l2tp_ppp.c \
l2tp_port_forward.c l2tp_crypto.c l2tp_ipsec.c
# ARM32 build
$TOOLCHAIN/bin/armv7a-linux-androideabi21-clang \
-O2 -I. -o l2tp_transfer_android_arm \
main.c l2tp_main.c l2tp_control.c l2tp_ppp.c \
l2tp_port_forward.c l2tp_crypto.c l2tp_ipsec.cAndroid compatibility notes:
- Code uses
_WIN32/ POSIX conditional compilation; Android uses Linux kernel, follows POSIX path - All POSIX APIs used (socket, fcntl, signal, select, etc.) are supported on Android
- Crypto algorithms are pure C, no external libraries required
- TCP checksum combined calculation (IP pseudo-header + TCP in one pass)
- Connection hash lookup (O(1) fast positioning, avoids linear scan of 64 connections)
- Timestamp caching (one
gettimeofdaycall reuse on hot path) - Direct L2TP packet construction (reduces one memcpy)
- TCP send window control (16KB, avoids UDP packet loss)
- TCP retransmit buffer (fast retransmit + timeout retransmit)
- Non-blocking local socket + TCP_NODELAY
This project is developed for learning and research purposes.