I’m working on a Kotlin app in Android Studio that requires the user’s web browsing to be monitored. I tried to use the android VPN API for this, and wrote the two functions below. The script compiles and runs fine showing logs as such
...
2024-08-07 13:52:02.492 18270-18311 WebFilterVpnService com.example.pbapp D
Packet captured from 10.0.0.2 to 142.250.68.227
2024-08-07 13:52:02.525 18270-18311 WebFilterVpnService com.example.pbapp D
Packet captured from 10.0.0.2 to 216.239.32.116
2024-08-07 13:52:02.589 18270-18311 WebFilterVpnService com.example.pbapp D
Packet captured from 10.0.0.2 to 216.239.32.116
2024-08-07 13:52:02.589 18270-18311 WebFilterVpnService com.example.pbapp D
Packet captured from 10.0.0.2 to 172.253.63.188
2024-08-07 13:52:02.589 18270-18311 WebFilterVpnService com.example.pbapp D
Packet captured from 10.0.0.2 to 216.239.32.116
...
Though, despite it running fine, it does not allow any websites to be loaded. When opening a site after running the VPN the page will load for about a minute and then throw this error “ERR_NETWORK_CHANGED”.
function to initialize the VPN:
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "VPN Service started")
val builder = Builder()
.addAddress("10.0.0.2", 24)
.addRoute("0.0.0.0", 0)
.setSession("WebFilterVpnService")
val configureIntent = PendingIntent.getActivity(
this,
0,
Intent(this, MainActivity::class.java),
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
builder.setConfigureIntent(configureIntent)
vpnInterface = builder.establish()
if (vpnInterface == null) {
Log.e(TAG, "Failed to establish VPN interface")
stopSelf()
return START_NOT_STICKY
}
Log.d(TAG, "VPN interface established")
startCapture()
return START_STICKY
}
function to sniff packets intercepted by the VPN:
private fun startCapture() {
vpnInterface?.let { vpnInterface ->
executor.execute {
Log.d(TAG, "Starting packet capture")
val fileInputStream = FileInputStream(vpnInterface.fileDescriptor)
val packet = ByteBuffer.allocate(32767)
try {
while (true) {
packet.clear()
val length = fileInputStream.read(packet.array())
if (length > 0) {
packet.limit(length)
if (length >= 20) {
val header = ByteArray(20)
packet.position(0)
packet.get(header, 0, 20)
val sourceIP = "${header[12].toInt() and 0xff}.${header[13].toInt() and 0xff}.${header[14].toInt() and 0xff}.${header[15].toInt() and 0xff}"
val destinationIP = "${header[16].toInt() and 0xff}.${header[17].toInt() and 0xff}.${header[18].toInt() and 0xff}.${header[19].toInt() and 0xff}"
Log.d(TAG, "Packet captured from $sourceIP to $destinationIP")
}
}
}
} catch (e: Exception) {
Log.e(TAG, "Error during packet capture", e)
} finally {
fileInputStream.close()
}
}
} ?: run {
Log.e(TAG, "VPN interface is null, cannot start packet capture")
}
}
I also tried to add a DNS along with the route and address as such
.builder.addDnsServer("8.8.8.8")
.builder.addDnsServer("1.1.1.1")
But that had no effect. Dose anyone know the cause for the ERR_NETWORK_CHANGED with the vpn enabled?