completed most major work on this

Still waiting for:
- New fork of hostap/wpa_supplicant
- Read udhcpc output for leased IP address
This commit is contained in:
MattKC 2024-12-09 13:35:33 -08:00
parent 7788aebd8b
commit 6d014a06b5
8 changed files with 1423 additions and 396 deletions

3
.gitmodules vendored
View file

@ -1,3 +1,6 @@
[submodule "lib/hostap"]
path = pipe/linux/hostap
url = https://github.com/rolandoislas/drc-hostap
[submodule "pipe/linux/busybox"]
path = pipe/linux/busybox
url = git://git.busybox.net/busybox

View file

@ -19,8 +19,6 @@ if (NOT ANDROID)
)
endif()
install(TARGETS vanilla)
if (VANILLA_BUILD_TESTS)
function(add_test TEST_NAME TEST_FILES)
add_executable(${TEST_NAME}

View file

@ -1,3 +1,4 @@
# Set up vanilla-pipe targer
add_executable(vanilla-pipe
main.c
wpa.c
@ -5,12 +6,31 @@ add_executable(vanilla-pipe
install(TARGETS vanilla-pipe)
# Find libnm
find_package(PkgConfig REQUIRED)
pkg_check_modules(OPENSSL REQUIRED libssl libcrypto)
pkg_check_modules(LIBNM REQUIRED libnm)
pkg_check_modules(LIBNL3 REQUIRED libnl-3.0 libnl-route-3.0 libnl-genl-3.0)
# Add include dirs for vanilla-pipe
target_include_directories(vanilla-pipe PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/hostap/src
${CMAKE_CURRENT_SOURCE_DIR}/hostap/src/common
${CMAKE_CURRENT_SOURCE_DIR}/hostap/src/utils
${CMAKE_CURRENT_SOURCE_DIR}/hostap/wpa_supplicant
${CMAKE_SOURCE_DIR}/lib
${LIBNM_INCLUDE_DIRS}
${LIBNL3_INCLUDE_DIRS}
)
# Ensure submodules are checked out before we build anything
find_package(Git)
if(Git_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endif()
# Build WPA supplicant
add_custom_target(
wpa_supplicant_configure
@ -18,41 +38,47 @@ add_custom_target(
)
add_custom_target(
wpa_supplicant_build
COMMAND make -j$$(nproc)
COMMAND make -j$$(nproc) libwpa_supplicant.a
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/hostap/wpa_supplicant"
BYPRODUCTS "${CMAKE_CURRENT_SOURCE_DIR}/hostap/wpa_supplicant/wpa_supplicant"
USES_TERMINAL
DEPENDS wpa_supplicant_configure
)
add_executable(wpa_supplicant IMPORTED)
add_dependencies(wpa_supplicant wpa_supplicant_build)
add_library(wpa_supplicant STATIC IMPORTED)
set_target_properties(wpa_supplicant PROPERTIES
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/hostap/wpa_supplicant/wpa_supplicant"
)
add_custom_command(
TARGET wpa_supplicant_build POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/hostap/wpa_supplicant/wpa_supplicant" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/wpa_supplicant_drc"
DEPENDS wpa_supplicant_build
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/hostap/wpa_supplicant/libwpa_supplicant.a"
)
add_dependencies(wpa_supplicant wpa_supplicant_build)
# Install dhcp script
# Build udhcpc (from busybox)
add_custom_target(
dhcp_script ALL
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/dhcp.sh" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/../sbin/dhcp.sh"
udhcpc_configure
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/busybox.config" "${CMAKE_CURRENT_SOURCE_DIR}/busybox/.config"
)
add_custom_target(
udhcpc_build
COMMAND make -j$$(nproc)
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/busybox"
USES_TERMINAL
DEPENDS udhcpc_configure
)
add_library(udhcpc SHARED IMPORTED)
set_target_properties(udhcpc PROPERTIES
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/busybox/0_lib/libbusybox.so.1.38.0.git"
)
install(IMPORTED_RUNTIME_ARTIFACTS udhcpc)
# Build client library
add_custom_target(
wpa_client_build
COMMAND make libwpa_client.so
COMMAND make libwpa_client.a
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/hostap/wpa_supplicant"
DEPENDS wpa_supplicant
BYPRODUCTS "${CMAKE_CURRENT_SOURCE_DIR}/hostap/wpa_supplicant/libwpa_client.so"
BYPRODUCTS "${CMAKE_CURRENT_SOURCE_DIR}/hostap/wpa_supplicant/libwpa_client.a"
)
add_library(wpa_client SHARED IMPORTED)
add_library(wpa_client STATIC IMPORTED)
set_target_properties(wpa_client PROPERTIES
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/hostap/wpa_supplicant/libwpa_client.so"
IMPORTED_NO_SONAME true
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/hostap/wpa_supplicant/libwpa_client.a"
)
add_dependencies(wpa_client wpa_client_build)
@ -60,12 +86,9 @@ add_dependencies(wpa_client wpa_client_build)
target_link_libraries(vanilla-pipe PRIVATE
wpa_client
pthread
wpa_supplicant
udhcpc
${LIBNM_LIBRARIES}
${OPENSSL_LIBRARIES}
${LIBNL3_LIBRARIES}
)
# Copy files into build directory
#add_custom_command(
# TARGET wpa_supplicant POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/hostap/wpa_supplicant/wpa_supplicant" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/wpa_supplicant_drc"
#)
install(IMPORTED_RUNTIME_ARTIFACTS wpa_client wpa_supplicant)

1
pipe/linux/busybox Submodule

@ -0,0 +1 @@
Subproject commit be7d1b7b1701d225379bc1665487ed0871b592a5

1207
pipe/linux/busybox.config Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,20 +0,0 @@
#!/bin/sh
ip=/sbin/ip
case "$reason" in
PREINIT)
${ip} -4 link set dev ${interface} up
;;
BOUND|RENEW|REBIND|REBOOT)
# Add IP address to interface. Provide no subnet so OS doesn't think there's a network here.
${ip} -4 addr flush dev ${interface}
${ip} -4 addr add ${new_ip_address}/32 dev ${interface}
;;
EXPIRE|FAIL|RELEASE|STOP)
# Remove old IP address
${ip} -4 addr flush dev ${interface}
;;
esac

View file

@ -3,6 +3,10 @@
#include <arpa/inet.h>
#include <errno.h>
#include <libgen.h>
#include <netlink/addr.h>
#include <netlink/netlink.h>
#include <netlink/route/addr.h>
#include <netlink/route/link.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
@ -24,6 +28,12 @@
#include "vanilla.h"
#include "wpa.h"
#include <utils/common.h>
#include <wpa_supplicant_i.h>
#include <libnm/NetworkManager.h>
extern int udhcpc_main(const char **argv);
const char *wpa_ctrl_interface = "/var/run/wpa_supplicant_drc";
pthread_mutex_t running_mutex;
@ -92,7 +102,7 @@ int is_interrupted()
return r;
}
void wpa_msg(char *msg, size_t len)
void vanilla_wpa_msg(char *msg, size_t len)
{
print_info("%.*s", len, msg);
}
@ -102,201 +112,6 @@ void wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd, char *buf, size_t
wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, buf_len, NULL /*wpa_msg*/);
}
int get_binary_in_working_directory(const char *bin_name, char *buf, size_t buf_size)
{
size_t path_size = get_max_path_length();
char *path_buf = malloc(path_size);
if (!path_buf) {
// Failed to allocate buffer, terminate
return -1;
}
// Get current working directory
// TODO: This is Linux only and will require changes on other platforms
ssize_t link_len = readlink("/proc/self/exe", path_buf, path_size);
if (link_len < 0) {
print_info("READLINK ERROR: %i", errno);
free(path_buf);
return -1;
}
// Merge current working directory with wpa_supplicant name
path_buf[link_len] = 0;
dirname(path_buf);
int r = snprintf(buf, path_size, "%s/%s", path_buf, bin_name);
free(path_buf);
return r;
}
ssize_t read_line_from_pipe(int pipe, char *buf, size_t buf_len)
{
int attempts = 0;
const static int max_attempts = 5;
ssize_t read_count = 0;
while (read_count < buf_len) {
ssize_t this_read = read(pipe, buf + read_count, 1);
if (this_read == 0) {
attempts++;
if (is_interrupted() || attempts == max_attempts) {
return -1;
}
sleep(1); // Wait for more output
continue;
}
attempts = 0;
if (buf[read_count] == '\n') {
buf[read_count] = 0;
break;
}
read_count++;
}
return read_count;
}
int wait_for_output(int pipe, const char *expected_output)
{
static const int max_attempts = 5;
int nbytes, attempts = 0, success = 0;
const int expected_len = strlen(expected_output);
char buf[256];
int read_count = 0;
int ret = 0;
do {
// Read line from child process
ssize_t read_sz = read_line_from_pipe(pipe, buf, sizeof(buf));
print_info("SUBPROCESS %.*s", read_sz, buf);
// We got success message!
if (!memcmp(buf, expected_output, expected_len)) {
ret = 1;
break;
}
// Haven't gotten success message (yet), wait and try again
} while (attempts < max_attempts && !is_interrupted());
return ret;
}
int start_process(const char **argv, pid_t *pid_out, int *stdout_pipe, int *stderr_pipe)
{
// Set up pipes so child stdout can be read by the parent process
int out_pipes[2], err_pipes[2];
pipe(out_pipes);
pipe(err_pipes);
// Get parent pid (allows us to check if parent was terminated immediately after fork)
pid_t ppid_before_fork = getpid();
// Fork into parent/child processes
pid_t pid = fork();
if (pid == 0) {
// We are in the child. Set child to terminate when parent does.
int r = prctl(PR_SET_PDEATHSIG, SIGHUP);
if (r == -1) {
perror(0);
exit(1);
}
// See if parent pid is still the same. If not, it must have been terminated, so we will exit too.
if (getppid() != ppid_before_fork) {
exit(1);
}
// Set up pipes so our stdout can be read by the parent process
dup2(out_pipes[1], STDOUT_FILENO);
dup2(err_pipes[1], STDERR_FILENO);
close(out_pipes[0]);
close(out_pipes[1]);
close(err_pipes[0]);
close(err_pipes[1]);
setsid();
// Execute process (this will replace the running code)
r = execvp(argv[0], (char * const *) argv);
// Handle failure to execute, use _exit so we don't interfere with the host
_exit(1);
} else if (pid < 0) {
// Fork error
return VANILLA_ERROR;
} else {
// Continuation of parent
close(out_pipes[1]);
close(err_pipes[1]);
if (!stdout_pipe) {
// Caller is not interested in the stdout
close(out_pipes[0]);
} else {
// Caller is interested so we'll hand them the pipe
*stdout_pipe = out_pipes[0];
}
if (!stderr_pipe) {
close(err_pipes[0]);
} else {
*stderr_pipe = err_pipes[0];
}
// If caller wants the pid, send it to them
if (pid_out) {
*pid_out = pid;
}
return VANILLA_SUCCESS;
}
}
int start_wpa_supplicant(const char *wireless_interface, const char *config_file, pid_t *pid)
{
// TODO: drc-sim has `rfkill unblock wlan`, should we do that too?
// Kill any potentially orphaned wpa_supplicant_drcs
const char *wpa_supplicant_drc = "wpa_supplicant_drc";
const char *kill_argv[] = {"killall", "-9", wpa_supplicant_drc, NULL};
pid_t kill_pid;
int kill_pipe;
int r = start_process(kill_argv, &kill_pid, &kill_pipe, NULL);
int status;
waitpid(kill_pid, &status, 0);
size_t path_size = get_max_path_length();
char *wpa_buf = malloc(path_size);
get_binary_in_working_directory(wpa_supplicant_drc, wpa_buf, path_size);
const char *argv[] = {wpa_buf, "-Dnl80211", "-i", wireless_interface, "-c", config_file, NULL};
print_info("USING WPA CONFIG: %s", config_file);
int pipe;
r = start_process(argv, pid, &pipe, NULL);
free(wpa_buf);
if (r != VANILLA_SUCCESS) {
return r;
}
// Wait for WPA supplicant to start
if (wait_for_output(pipe, "Successfully initialized wpa_supplicant")) {
// I'm not sure why, but closing this pipe breaks wpa_supplicant in subtle ways, so just leave it.
//close(pipe);
// WPA initialized correctly! Continue with action...
return VANILLA_SUCCESS;
} else {
// Give up
give_up:
kill((*pid), SIGTERM);
return VANILLA_ERROR;
}
}
void quit_loop()
{
pthread_mutex_lock(&running_mutex);
@ -339,6 +154,11 @@ void *read_stdin(void *)
return NULL;
}
void *start_wpa(void *arg)
{
return THREADRESULT(wpa_supplicant_run((struct wpa_global *) arg));
}
void *wpa_setup_environment(void *data)
{
void *ret = THREADRESULT(VANILLA_ERROR);
@ -346,36 +166,58 @@ void *wpa_setup_environment(void *data)
struct sync_args *args = (struct sync_args *) data;
// Check status of interface with NetworkManager
int is_managed = 0;
if (is_networkmanager_managing_device(args->wireless_interface, &is_managed) != VANILLA_SUCCESS) {
print_info("FAILED TO DETERMINE MANAGED STATE OF WIRELESS INTERFACE");
//goto die;
}
GError *nm_err;
NMClient *nmcli = nm_client_new(NULL, &nm_err);
NMDevice *nmdev = NULL;
gboolean is_managed = 0;
if (nmcli) {
nmdev = nm_client_get_device_by_iface(nmcli, args->wireless_interface);
if (!nmdev) {
pprint("FAILED TO GET STATUS OF DEVICE %s\n", args->wireless_interface);
goto die_and_close_nmcli;
}
// If NetworkManager is managing this device, temporarily stop it from doing so
if (is_managed) {
if (disable_networkmanager_on_device(args->wireless_interface) != VANILLA_SUCCESS) {
print_info("FAILED TO SET %s TO UNMANAGED, RESULTS MAY BE UNPREDICTABLE");
} else {
if ((is_managed = nm_device_get_managed(nmdev))) {
nm_device_set_managed(nmdev, FALSE);
print_info("TEMPORARILY SET %s TO UNMANAGED", args->wireless_interface);
}
} else {
// Failed to get NetworkManager, host may just not have it?
g_message("Failed to create NetworkManager client: %s", nm_err->message);
g_error_free(nm_err);
}
// Start modified WPA supplicant
pid_t pid;
int err = start_wpa_supplicant(args->wireless_interface, args->wireless_config, &pid);
if (err != VANILLA_SUCCESS || is_interrupted()) {
print_info("FAILED TO START WPA SUPPLICANT");
struct wpa_params params = {0};
params.wpa_debug_level = MSG_INFO;
struct wpa_interface interface = {0};
interface.driver = "nl80211";
interface.ifname = args->wireless_interface;
interface.confname = args->wireless_config;
struct wpa_global *wpa = wpa_supplicant_init(&params);
if (!wpa) {
print_info("FAILED TO INIT WPA SUPPLICANT");
goto die_and_reenable_managed;
}
struct wpa_supplicant *wpa_s = wpa_supplicant_add_iface(wpa, &interface, NULL);
if (!wpa_s) {
print_info("FAILED TO ADD WPA IFACE");
goto die_and_kill;
}
pthread_t wpa_thread;
pthread_create(&wpa_thread, NULL, start_wpa, wpa);
// Get control interface
const size_t buf_len = 1048576;
char *buf = malloc(buf_len);
snprintf(buf, buf_len, "%s/%s", wpa_ctrl_interface, args->wireless_interface);
struct wpa_ctrl *ctrl;
while (!(ctrl = wpa_ctrl_open(buf))) {
if (is_interrupted()) goto die_and_kill;
if (is_interrupted()) goto die_and_free_buf;
print_info("WAITING FOR CTRL INTERFACE");
sleep(1);
}
@ -394,131 +236,29 @@ die_and_detach:
die_and_close:
wpa_ctrl_close(ctrl);
die_and_kill:
kill(pid, SIGTERM);
die_and_free_buf:
free(buf);
die_and_kill:
pthread_kill(wpa_thread, SIGINT);
pthread_join(wpa_thread, NULL);
wpa_supplicant_deinit(wpa);
die_and_reenable_managed:
if (is_managed) {
print_info("SETTING %s BACK TO MANAGED", args->wireless_interface);
enable_networkmanager_on_device(args->wireless_interface);
nm_device_set_managed(nmdev, TRUE);
}
die_and_close_nmcli:
if (nmcli) {
g_object_unref(nmcli);
}
die:
return ret;
}
int call_dhcp(const char *network_interface, pid_t *dhclient_pid)
{
// See if dhclient exists in our local directories
size_t buf_size = get_max_path_length();
char *dhclient_buf = malloc(buf_size);
char *dhclient_script = malloc(buf_size);
get_binary_in_working_directory("dhclient", dhclient_buf, buf_size);
get_binary_in_working_directory("../sbin/dhcp.sh", dhclient_script, buf_size);
if (access(dhclient_buf, F_OK) == 0) {
// Prefer our local dhclient if it's available
// TODO: dhclient is EOL and should be replaced with something else
print_info("Using custom dhclient at: %s", dhclient_buf);
} else {
print_info("Using system dhclient");
strncpy(dhclient_buf, "dhclient", buf_size);
}
const char *argv[] = {dhclient_buf, "-d", "--no-pid", "-sf", dhclient_script, network_interface, NULL};
int dhclient_pipe;
int r = start_process(argv, dhclient_pid, NULL, &dhclient_pipe);
free(dhclient_buf);
free(dhclient_script);
if (r != VANILLA_SUCCESS) {
print_info("FAILED TO CALL DHCLIENT");
return r;
}
if (wait_for_output(dhclient_pipe, "bound to")) {
return VANILLA_SUCCESS;
} else {
print_info("FAILED TO ESTABLISH DHCP");
kill(*dhclient_pid, SIGTERM);
return VANILLA_ERROR;
}
}
static const char *nmcli = "nmcli";
int is_networkmanager_managing_device(const char *wireless_interface, int *is_managed)
{
pid_t nmcli_pid;
int pipe;
const char *argv[] = {nmcli, "device", "show", wireless_interface, NULL};
int r = start_process(argv, &nmcli_pid, &pipe, NULL);
if (r != VANILLA_SUCCESS) {
// Assume nmcli is not installed so the host is not using NetworkManager
print_info("FAILED TO LAUNCH NMCLI, RESULTS MAY BE UNPREDICTABLE");
*is_managed = 0;
return VANILLA_SUCCESS;
}
int status;
waitpid(nmcli_pid, &status, 0);
if (!WIFEXITED(status)) {
// Something went wrong
print_info("NMCLI DID NOT EXIT NORMALLY");
return VANILLA_ERROR;
}
char buf[100];
int ret = VANILLA_ERROR;
while (read_line_from_fd(pipe, buf, sizeof(buf))) {
if (memcmp(buf, "GENERAL.STATE", 13) == 0) {
*is_managed = !strstr(buf, "unmanaged");
ret = VANILLA_SUCCESS;
goto exit;
}
}
exit:
close(pipe);
return ret;
}
int set_networkmanager_on_device(const char *wireless_interface, int on)
{
const char *argv[] = {nmcli, "device", "set", wireless_interface, "managed", on ? "on" : "off", NULL};
pid_t nmcli_pid;
int r = start_process(argv, &nmcli_pid, NULL, NULL);
if (r != VANILLA_SUCCESS) {
return r;
}
int status;
waitpid(nmcli_pid, &status, 0);
if (WIFEXITED(status)) {
return VANILLA_SUCCESS;
} else {
return VANILLA_ERROR;
}
}
int disable_networkmanager_on_device(const char *wireless_interface)
{
return set_networkmanager_on_device(wireless_interface, 0);
}
int enable_networkmanager_on_device(const char *wireless_interface)
{
return set_networkmanager_on_device(wireless_interface, 1);
}
void *do_relay(void *data)
{
relay_ports *ports = (relay_ports *) data;
@ -887,6 +627,102 @@ exit_loop:
return THREADRESULT(found_console ? VANILLA_SUCCESS : VANILLA_ERROR);
}
int apply_addr_on_intf(const char *wireless_interface, const char *addr_to_set)
{
int ret = VANILLA_ERROR;
struct nl_sock* sk = nl_socket_alloc();
if (nl_connect(sk, NETLINK_ROUTE)) {
pprint("FAILED TO CONNECT TO NETLINK\n");
goto die_and_free_socket;
}
struct nl_cache *cache;
if (rtnl_link_alloc_cache(sk, AF_INET, &cache)) {
pprint("FAILED TO ALLOC LINK CACHE\n");
goto die_and_close_socket;
}
int ifindex = rtnl_link_name2i(cache, wireless_interface);
if (!ifindex) {
pprint("FAILED TO RESOLVE IFINDEX FROM NAME\n");
goto die_and_free_cache;
}
struct nl_addr *nla;
if (nl_addr_parse(addr_to_set, AF_INET, &nla)) {
pprint("FAILED TO PARSE ADDRESS\n");
goto die_and_free_cache;
}
struct rtnl_addr *addr = rtnl_addr_alloc();
rtnl_addr_set_ifindex(addr, ifindex);
rtnl_addr_set_local(addr, nla);
if (rtnl_addr_add(sk, addr, 0)) {
pprint("FAILED TO ADD IP TO INTERFACE\n");
} else {
ret = VANILLA_SUCCESS;
}
die_and_free_nl_addr:
nl_addr_put(nla);
die_and_free_rtnl_addr:
rtnl_addr_put(addr);
die_and_free_cache:
nl_cache_free(cache);
die_and_close_socket:
nl_close(sk);
die_and_free_socket:
nl_socket_free(sk);
return ret;
}
int do_dhcp(const char *wireless_interface)
{
int dhcp_pipes[2];
if (pipe(dhcp_pipes)) {
print_info("FAILED TO CREATE DHCP PIPE: %i", errno);
return VANILLA_ERROR;
}
if (dup2(dhcp_pipes[1], STDOUT_FILENO) == -1) {
print_info("FAILED TO DUP2 STDOUT: %i", errno);
return VANILLA_ERROR;
}
const char *udhcpc_argv[] = {
"-i", wireless_interface,
"-v",
"-q",
"-f",
"-s", "/dev/null",
NULL};
int r = udhcpc_main(udhcpc_argv);
if (r) {
print_info("FAILED TO RUN DHCP ON %s", wireless_interface);
return VANILLA_ERROR;
}
print_info("DHCP ESTABLISHED");
char buf[1024];
read(dhcp_pipes[0], buf, sizeof(buf));
print_info("DHCP OUTPUT: %s", buf);
if (apply_addr_on_intf(wireless_interface, "192.168.1.11") != VANILLA_SUCCESS) {
return VANILLA_ERROR;
}
return VANILLA_SUCCESS;
}
void *do_connect(void *data)
{
struct sync_args *args = (struct sync_args *) data;
@ -917,20 +753,12 @@ void *do_connect(void *data)
print_info("CONNECTED TO CONSOLE");
// Use DHCP on interface
pid_t dhclient_pid;
int r = call_dhcp(args->wireless_interface, &dhclient_pid);
if (r != VANILLA_SUCCESS) {
print_info("FAILED TO RUN DHCP ON %s", args->wireless_interface);
return THREADRESULT(r);
} else {
print_info("DHCP ESTABLISHED");
if (do_dhcp(args->wireless_interface) != VANILLA_SUCCESS) {
return THREADRESULT(VANILLA_ERROR);
}
create_all_relays(args->wireless_interface);
int kill_ret = kill(dhclient_pid, SIGTERM);
print_info("KILLING DHCLIENT %i", dhclient_pid);
return THREADRESULT(VANILLA_SUCCESS);
}

View file

@ -5,20 +5,7 @@
#include <stdlib.h>
#include <sys/types.h>
struct wpa_ctrl;
extern const char *wpa_ctrl_interface;
void wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd, char *buf, size_t *buf_len);
int start_wpa_supplicant(const char *wireless_interface, const char *config_file, pid_t *pid);
int call_dhcp(const char *network_interface, pid_t *dhclient_pid);
int is_networkmanager_managing_device(const char *wireless_interface, int *is_managed);
int disable_networkmanager_on_device(const char *wireless_interface);
int enable_networkmanager_on_device(const char *wireless_interface);
void pprint(const char *fmt, ...);
void vanilla_listen(const char *wireless_interface);
#endif // VANILLA_WPA_H