Вот обзор того, чего я пытаюсь достичь:
Отключить Wi-Fi
Настроить hostapd и dnsmasq для работы точки доступа
Настроить переадресацию IP и таблицы IP
Перенаправить трафик HTTP и HTTPS на локальный прокси-сервер
Я создали приложение для Android, которое использует Kotlin для выполнения команд оболочки для этих конфигураций. Однако точка доступа не запускается, и я получаю сообщение об ошибке, связанное с тем, что процесс hostapd не найден.
Вот соответствующий код:
`
Код: Выделить всё
private lateinit var proxyServer: ProxyServer
private val PROXY_HTTP_PORT = 8080
private val PROXY_HTTPS_PORT = 8443
private lateinit var binding: ActivityMainBinding
private lateinit var navController: NavController
private lateinit var appBarConfiguration: AppBarConfiguration
enum class HotspotState {
IDLE,
STARTING,
STARTED,
STOPPING,
STOPPED,
ERROR
}
private var hotspotState = HotspotState.IDLE
companion object {
const val PERMISSIONS_REQUEST_CODE = 1001
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
val navHostFragment = supportFragmentManager
.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
navController = navHostFragment.navController
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
proxyServer = ProxyServer()
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp() || super.onSupportNavigateUp()
}
private fun executeShellCommand(command: String): String {
return try {
val process = ProcessBuilder("su", "-c", command)
.redirectErrorStream(true)
.start()
val reader = BufferedReader(InputStreamReader(process.inputStream))
val output = reader.readText()
val exitCode = process.waitFor()
if (exitCode != 0) {
throw IOException("Command \"$command\" failed with exit code $exitCode. Output: $output")
}
output
} catch (e: IOException) {
throw IOException("Error executing shell command", e)
} catch (e: InterruptedException) {
Thread.currentThread().interrupt()
throw IOException("Command execution interrupted", e)
}
}
fun startHotspot(ssid: String) {
if (hotspotState != HotspotState.IDLE && hotspotState != HotspotState.STOPPED) {
return
}
hotspotState = HotspotState.STARTING
CoroutineScope(Dispatchers.IO).launch {
try {
// Commands to start the hotspot without a password
val commands = listOf(
"svc wifi disable",
"mkdir -p /data/misc/hostapd",
"mkdir -p /data/misc/dnsmasq",
"echo 'interface=wlan0\n" +
"driver=nl80211\n" +
"ssid=$ssid\n" +
"hw_mode=g\n" +
"channel=6\n" +
"auth_algs=1\n" + // Open authentication
"wpa=0' > /data/misc/hostapd/hostapd.conf",
"echo 'interface=wlan0\ndhcp-range=192.168.43.2,192.168.43.20,12h\ndhcp-option=3,192.168.43.1\ndhcp-option=6,192.168.43.1' > /data/misc/dnsmasq/dnsmasq.conf",
"chmod 755 /data/misc/hostapd/hostapd.conf",
"chmod 755 /data/misc/dnsmasq/dnsmasq.conf",
"echo 1 > /proc/sys/net/ipv4/ip_forward",
"iptables -I FORWARD -i wlan0 -s 192.168.43.0/24 -j ACCEPT",
"iptables -I FORWARD -i wlan0 -d 192.168.43.0/24 -j ACCEPT",
"iptables -t nat -I POSTROUTING -s 192.168.43.0/24 ! -o wlan0 -j MASQUERADE",
"iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port $PROXY_HTTP_PORT",
"iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port $PROXY_HTTPS_PORT",
"service call connectivity 24 i32 0 i32 0 i32 0 s16 random",
"hostapd /data/misc/hostapd/hostapd.conf > /data/misc/hostapd/hostapd.log 2>&1 &",
"dnsmasq -C /data/misc/dnsmasq/dnsmasq.conf > /data/misc/dnsmasq/dnsmasq.log 2>&1 &"
)
for (command in commands) {
val output = executeShellCommand(command)
Log.d("HotspotDebug", "Command: $command\nOutput: $output")
}
// Check if `hostapd` and `dnsmasq` are running
val hostapdRunning = executeShellCommand("pgrep hostapd")
val dnsmasqRunning = executeShellCommand("pgrep dnsmasq")
Log.d("HotspotDebug", "Hostapd Running: $hostapdRunning")
Log.d("HotspotDebug", "Dnsmasq Running: $dnsmasqRunning")
// Start the proxy server
withContext(Dispatchers.IO) {
proxyServer.startHttpProxy(PROXY_HTTP_PORT)
proxyServer.startHttpsProxy(PROXY_HTTPS_PORT)
}
withContext(Dispatchers.Main) {
hotspotState = HotspotState.STARTED
Toast.makeText(this@MainActivity, "Hotspot started and proxy server running", Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
e.printStackTrace()
withContext(Dispatchers.Main) {
hotspotState = HotspotState.ERROR
Toast.makeText(this@MainActivity, "Error starting the hotspot", Toast.LENGTH_SHORT).show()
}
}
}
}
fun stopHotspot() {
if (hotspotState != HotspotState.STARTED) {
return
}
hotspotState = HotspotState.STOPPING
// Commands to stop the hotspot
val commands = listOf(
"killall hostapd",
"killall dnsmasq",
"echo 0 > /proc/sys/net/ipv4/ip_forward",
"iptables -t nat -D PREROUTING -p tcp --dport 80 -j REDIRECT --to-port $PROXY_HTTP_PORT",
"iptables -t nat -D PREROUTING -p tcp --dport 443 -j REDIRECT --to-port $PROXY_HTTPS_PORT",
"iptables -t nat -D POSTROUTING -s 192.168.43.0/24 ! -o wlan0 -j MASQUERADE",
"iptables -D FORWARD -i wlan0 -s 192.168.43.0/24 -j ACCEPT",
"iptables -D FORWARD -i wlan0 -d 192.168.43.0/24 -j ACCEPT"
)
try {
for (command in commands) {
executeShellCommand(command)
}
// Stop the proxy server
proxyServer.stopHttpProxy()
proxyServer.stopHttpsProxy()
hotspotState = HotspotState.STOPPED
Toast.makeText(this, "Hotspot stopped and proxy server halted", Toast.LENGTH_SHORT).show()
} catch (e: IOException) {
e.printStackTrace()
hotspotState = HotspotState.ERROR
Toast.makeText(this, "Error executing root commands", Toast.LENGTH_SHORT).show()
}
}
Возникшие проблемы:
Службы `hostapd` и `dnsmasq` не запускаются. Команда pgrep hostapd не возвращает результатов, что указывает на то, что hostapd, возможно, не запущен.
Точка доступа не активируется должным образом.
Технические характеристики устройства:
Версия Android: 14
Устройство: Moto G04
Разрешения root: предоставлены
Что я пробовал:
Проверил, что все команды оболочки выполняются с правами root.
Проверил правильность установки путей и разрешений для файлов конфигурации.
Убедился в существовании двоичных файлов hostapd и dnsmasq.
Вопросы:
Существуют ли какие-либо известные проблемы или дополнительные действия, необходимые для успешного запуска hostapd и dnsmasq на Android 14?
Есть ли более надежный способ проверить, работают ли hostapd и dnsmasq?
Существуют ли какие-либо конкретные файлы журналов или методы отладки, которые могут помочь определить причину сбоя этих служб?
Любая помощь или предложения будут очень признательны!
Подробнее здесь: https://stackoverflow.com/questions/788 ... ermissions
Мобильная версия