Android 虚拟专用网 code
1. UI setting part:
packages/apps/Settings/src/com/android/settings/vpn2/VpnSettings.java
packages/apps/Settings/src/com/android/settings/vpn2/VpnDialog.java
packages/apps/Settings/src/com/android/settings/vpn2/VpnProfile.java
6 typtes of 虚拟专用网 defined in VpnProfile.java
static final int TYPE_PPTP = 0;
static final int TYPE_L2TP_IPSEC_PSK = 1;
static final int TYPE_L2TP_IPSEC_RSA = 2;
static final int TYPE_IPSEC_XAUTH_PSK = 3;
static final int TYPE_IPSEC_XAUTH_RSA = 4;
static final int TYPE_IPSEC_HYBRID_RSA = 5
VpnSettings.java
connect(VpnProfile profile)
mService.startLegacyVpn(config, racoon, mtpd);
disconnect(String key)
mService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN);
private final IConnectivityManager mService = IConnectivityManager.Stub
.asInterface(ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
2. frameworks/base part
frameworks/base/core/java/android/net/IConnectivityManager.aidl
frameworks/base/core/java/android/net/VpnService.java
frameworks/base/services/java/com/android/server/ConnectivityService.java
frameworks/base/services/java/com/android/server/connectivity/Vpn.java
frameworks/base/services/jni/com_android_server_connectivity_Vpn.cpp
ConnectivityService.java
public ParcelFileDescriptor establishVpn(VpnConfig config) used by VpnBuilder
public void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd)
public void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd)
Vpn.java
public synchronized boolean prepare(String oldPackage, String newPackage)
Prepare for a VPN application. This method is designed to solve
race conditions. It first compares the current prepared package
with {@code oldPackage}. If they are the same, the prepared
package is revoked and replaced with {@code newPackage}. If
{@code oldPackage} is {@code null}, the comparison is omitted.
If {@code newPackage} is the same package or {@code null}, the
revocation is omitted. This method returns {@code true} if the
operation is succeeded
public synchronized ParcelFileDescriptor establish(VpnConfig config)
Establish a VPN network and return the file descriptor of the VPN interface
public synchronized void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd)
Start legacy VPN. This method stops the daemons and restart them
arguments are not null.
private class LegacyVpnRunner extends Thread
mSockets LocalSocket used to communicate with Native racoon & mtpd
mDaemons = new String[] {"racoon", "mtpd"};
mSockets = new LocalSocket[mDaemons.length];
system prop:
init.svc.racoon & init.svc.mtpd
stopped, running
Typical log for Vpn in Java part
12-26 10:20:54.697 I/Vpn ( 627): Switched from [Legacy VPN] to [Legacy VPN]
12-26 10:20:54.727 V/LegacyVpnRunner( 627): Waiting
12-26 10:20:54.727 V/LegacyVpnRunner( 627): Executing
12-26 10:21:02.956 I/LegacyVpnRunner( 627): Connected!
com_android_server_connectivity_Vpn.cpp
static JNINativeMethod gMethods[] = {
{"jniCreate", "(I)I", (void *)create},
{"jniGetName", "(I)Ljava/lang/String;", (void *)getName},
{"jniSetAddresses", "(Ljava/lang/String;Ljava/lang/String;)I", (void *)setAddresses},
{"jniSetRoutes", "(Ljava/lang/String;Ljava/lang/String;)I", (void *)setRoutes},
{"jniReset", "(Ljava/lang/String;)V", (void *)reset},
{"jniCheck", "(Ljava/lang/String;)I", (void *)check},
{"jniProtect", "(ILjava/lang/String;)V", (void *)protect},
3. Native C part
external/mtpd
external/ipsec-tools
external/ppp
3.1 external/mtpd
support PPTP & L2TP
mtpd.c prcoess entry
l2tp.c support L2TP
pptp.c support PPTP
local ------------ remote
send SCCRQ --->
<--- send SCCRP
Send SCCCN --->
<--- ACK
Send ICRQ --->
<--- ACK
<--- send ICRP
Sending ICCN--->
<--- ACK
typical logs for L2TP
12-26 10:20:55.078 D/mtpd (12380): Waiting for control socket
12-26 10:20:55.318 D/mtpd (12380): Received 20 arguments
12-26 10:20:55.318 I/mtpd (12380): Using protocol l2tp
12-26 10:20:55.318 I/mtpd (12380): Connecting to *.*.*.* port 1701 via wlan0
12-26 10:20:55.318 I/mtpd (12380): Connection established (socket = 15)
12-26 10:20:55.318 D/mtpd (12380): Sending SCCRQ (local_tunnel = 22083)
12-26 10:20:57.320 D/mtpd (12380): Timeout -> Sending SCCRQ
12-26 10:20:59.322 D/mtpd (12380): Timeout -> Sending SCCRQ
12-26 10:20:59.713 D/mtpd (12380): Received SCCRP (remote_tunnel = 39438) -> Sending SCCCN
12-26 10:21:00.023 D/mtpd (12380): Received ACK -> Sending ICRQ (local_session = 51624)
12-26 10:21:00.023 I/mtpd (12380): Tunnel established
12-26 10:21:00.323 D/mtpd (12380): Received ACK
12-26 10:21:00.323 D/mtpd (12380): Received ICRP (remote_session = 256) -> Sending ICCN
12-26 10:21:00.634 D/mtpd (12380): Received ACK
12-26 10:21:00.634 I/mtpd (12380): Session established
12-26 10:21:00.634 I/mtpd (12380): Creating PPPoX socket
12-26 10:21:00.634 I/mtpd (12380): Starting pppd (pppox = 16)
12-26 10:21:00.634 I/mtpd (12380): Pppd started (pid = 12386)
12-26 10:21:08.212 I/mtpd (12380): Received signal 15
12-26 10:21:08.212 I/mtpd (12380): Sending signal to pppd (pid = 12386)
12-26 10:21:08.642 D/mtpd (12380): Sending STOPCCN
12-26 10:21:08.642 I/mtpd (12380): Mtpd is terminated (status = 5)
3.2 external/ppp
support PPP
typical log
12-26 10:21:00.634 I/mtpd (12380): Starting pppd (pppox = 16)
12-26 10:21:00.634 I/mtpd (12380): Pppd started (pid = 12386)
12-26 10:21:00.654 I/pppd (12386): Using PPPoX (socket = 16)
12-26 10:21:00.664 D/pppd (12386): using channel 2
12-26 10:21:00.674 I/pppd (12386): Using interface ppp0
12-26 10:21:00.674 I/pppd (12386): Connect: ppp0 <-->
12-26 10:21:02.896 I/pppd (12386): local IP address *.*.*.*
12-26 10:21:02.896 I/pppd (12386): remote IP address *.*.*.*
12-26 10:21:08.212 I/mtpd (12380): Sending signal to pppd (pid = 12386)
12-26 10:21:08.212 I/pppd (12386): Terminating on signal 15
12-26 10:21:08.212 I/pppd (12386): Connect time 0.1 minutes.
12-26 10:21:08.212 I/pppd (12386): Sent 33 bytes, received 33 bytes.
12-26 10:21:08.622 I/pppd (12386): Connection terminated.
3.3 external/ipsec-tools
support IPSEC
external/ipsec-tools/src/racoon/main.c process entry
external/ipsec-tools/src/racoon/plog.h
display more logs by changing
#define loglevel LLV_DEBUG2
if ((level) >= LLV_ERROR && (level) <= LLV_DEBUG2) {
if you want to print buf, you can use
plogdump(pri, data, len) in plog.c
isakmp.c
isakmp_main(msg, remote, local) main processing to handle isakmp payload
ph1_main(iph1, msg) main function of phase 1
quick_main(iph2, msg) main function of quick mode.
isakmp_send(iph1, sbuf) send isakmp packet
isakmp_handler(so_isakmp) isakmp packet handler
isakmp_agg.c Aggressive mode
isakmp_base.c base mode
isakmp_ident.c main/identity mode
isakmp_quick.c quick mode (phase 2)
isakmp_xauth.c xauth mode
pfkey.c pfkey
two phase negotiation
external/ipsec-tools/src/racoon/handler.h
/* Phase 1 handler */
/*
* main mode:
* initiator responder
* 0 (---) (---)
* 1 start start (1st msg received)
* 2 (---) 1st valid msg received
* 3 1st msg sent 1st msg sent
* 4 1st valid msg received 2st valid msg received
* 5 2nd msg sent 2nd msg sent
* 6 2nd valid msg received 3rd valid msg received
* 7 3rd msg sent 3rd msg sent
* 8 3rd valid msg received (---)
* 9 SA established SA established
/* Phase 2 handler */
/* allocated per a SA or SA bundles of a pair of peer's IP addresses. */
/*
* initiator responder
* 0 (---) (---)
* 1 start start (1st msg received)
* 2 acquire msg get 1st valid msg received
* 3 getspi request sent getspi request sent
* 4 getspi done getspi done
* 5 1st msg sent 1st msg sent
* 6 1st valid msg received 2nd valid msg received
* 7 (commit bit) (commit bit)
* 8 SAs added SAs added
* 9 SAs established SAs established
* 10 SAs expired SAs expired
typical logs
01-02 09:27:16.654 D/racoon ( 6187): Waiting for control socket
01-02 09:27:16.854 D/racoon ( 6187): Received 6 arguments
01-02 09:27:16.854 I/racoon ( 6187): ipsec-tools 0.7.3 ([PROJECT ABANDONED] IPsec-Tools)
01-02 09:27:16.934 I/racoon ( 6187): *.*.*.*[500] used as isakmp port (fd=10)
01-02 09:27:16.934 I/racoon ( 6187): *.*.*.*[500] used for NAT-T
01-02 09:27:16.934 I/racoon ( 6187): *.*.*.*[4500] used as isakmp port (fd=11)
01-02 09:27:16.934 I/racoon ( 6187): *.*.*.*[4500] used for NAT-T
01-02 09:27:17.275 I/racoon ( 6187): IPsec-SA request for *.*.*.* queued due to no phase1 found.
01-02 09:27:17.275 I/racoon ( 6187): initiate new phase 1 negotiation: *.*.*.*[500]<=>*.*.*.*[500]
01-02 09:27:17.275 I/racoon ( 6187): begin Identity Protection mode.
01-02 09:27:18.616 I/racoon ( 6187): received Vendor ID: draft-ietf-ipsec-nat-t-ike-02
01-02 09:27:18.616 I/racoon ( 6187):
01-02 09:27:18.616 I/racoon ( 6187): received broken Microsoft ID: FRAGMENTATION
01-02 09:27:18.616 I/racoon ( 6187): Selected NAT-T version: draft-ietf-ipsec-nat-t-ike-02
01-02 09:27:18.616 I/racoon ( 6187):
01-02 09:27:18.716 I/racoon ( 6187): Hashing *.*.*.*[500] with algo #1
01-02 09:27:18.716 I/racoon ( 6187): Hashing *.*.*.*[500] with algo #1
01-02 09:27:18.716 I/racoon ( 6187): Adding remote and local NAT-D payloads.
01-02 09:27:23.942 I/racoon ( 6187): received Vendor ID: CISCO-UNITY
01-02 09:27:23.942 I/racoon ( 6187): received Vendor ID: draft-ietf-ipsra-isakmp-xauth-06.txt
01-02 09:27:23.942 I/racoon ( 6187): Hashing *.*.*.*[500] with algo #1
01-02 09:27:23.942 I/racoon ( 6187): NAT-D payload #0 doesn't match
01-02 09:27:23.942 I/racoon ( 6187): Hashing *.*.*.*[500] with algo #1
01-02 09:27:23.942 I/racoon ( 6187): NAT-D payload #1 verified
01-02 09:27:23.942 I/racoon ( 6187): NAT detected: ME
01-02 09:27:23.942 I/racoon ( 6187): KA list add: *.*.*.*[4500]->*.*.*.*[4500]
01-02 09:27:27.676 I/racoon ( 6187): the packet is retransmitted by *.*.*.*[500] (2).
01-02 09:27:27.716 I/racoon ( 6187): received Vendor ID: DPD
01-02 09:27:27.716 W/racoon ( 6187): port 4500 expected, but 0
01-02 09:27:27.716 I/racoon ( 6187): ISAKMP-SA established *.*.*.*[4500]-*.*.*.*[4500] spi:04f25043ab113a1b:907d777ac224ef82
01-02 09:27:28.747 I/racoon ( 6187): initiate new phase 2 negotiation: *.*.*.*[4500]<=>*.*.*.*[4500]
01-02 09:27:28.747 I/racoon ( 6187): NAT detected -> UDP encapsulation (ENC_MODE 2->61444).
01-02 09:27:35.324 W/racoon ( 6187): transform number has been modified.
01-02 09:27:35.324 W/racoon ( 6187): attribute has been modified.
01-02 09:27:35.324 I/racoon ( 6187): Adjusting my encmode UDP-Transport->Transport
01-02 09:27:35.324 I/racoon ( 6187): Adjusting peer's encmode UDP-Transport(61444)->Transport(2)
01-02 09:27:35.324 W/racoon ( 6187): trns_id mismatched: my:AES peer:3DES
01-02 09:27:35.324 W/racoon ( 6187): trns_id mismatched: my:AES peer:3DES
01-02 09:27:35.324 W/racoon ( 6187): trns_id mismatched: my:AES peer:3DES
01-02 09:27:35.324 W/racoon ( 6187): trns_id mismatched: my:AES peer:3DES
01-02 09:27:35.324 I/racoon ( 6187): IPsec-SA established: ESP/Transport *.*.*.*[0]->*.*.*.*[0] spi=169644160(0xa1c9080)
01-02 09:27:35.324 I/racoon ( 6187): IPsec-SA established: ESP/Transport *.*.*.*[4500]->*.*.*.*[4500] spi=3768281574(0xe09b69e6)
4. Kernel part
kernel/net/l2tp
kernel/net/xfrm
kernel/net/key (af_key.c)
kernel/net/ipv4 (xfrm*.c,ah4.c, esp4.c, tcp.c, udp.c)
kernel/net/ipv6 (xfrm6*.c,ah6.c, esp6.c, tcp_ipv6.c, udp.c)
kernel/drivers/net (tun.c, pppolac.c, pppopns.c)
kernel/arch/arm/configs
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET6_XFRM_MODE_TRANSPORT=y
CONFIG_INET6_XFRM_MODE_TUNNEL=y
CONFIG_TUN=y