12eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt/* 22eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Copyright (C) 2012 The Android Open Source Project 32eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * 42eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Licensed under the Apache License, Version 2.0 (the "License"); 52eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * you may not use this file except in compliance with the License. 62eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * You may obtain a copy of the License at 72eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * 8329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy * http://www.apache.org/licenses/LICENSE-2.0 92eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * 102eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Unless required by applicable law or agreed to in writing, software 112eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * distributed under the License is distributed on an "AS IS" BASIS, 122eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * See the License for the specific language governing permissions and 142eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * limitations under the License. 152eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt */ 162eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 172eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <stdlib.h> 182eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <errno.h> 192eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <fcntl.h> 202eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <string.h> 212eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 22329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy#include <dlfcn.h> 23329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy 242eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <sys/socket.h> 252eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <sys/stat.h> 262eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <sys/ioctl.h> 272eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <sys/types.h> 282eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 292eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <netinet/in.h> 302eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <arpa/inet.h> 312eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 322eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#define LOG_TAG "InterfaceController" 332eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <cutils/log.h> 342eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <netutils/ifc.h> 352eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <private/android_filesystem_config.h> 362eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 372eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include "InterfaceController.h" 382eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 39329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiychar if_cmd_lib_file_name[] = "/system/lib/libnetcmdiface.so"; 40329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiychar set_cmd_func_name[] = "net_iface_send_command"; 41329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiychar set_cmd_init_func_name[] = "net_iface_send_command_init"; 42329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiychar set_cmd_fini_func_name[] = "net_iface_send_command_fini"; 432eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 44329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha LevitskiyInterfaceController::InterfaceController() 45329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy : sendCommand_(NULL) { 46329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy libh_ = dlopen(if_cmd_lib_file_name, RTLD_NOW | RTLD_LOCAL); 47329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy if (libh_ == NULL) { 48329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy const char *err_str = dlerror(); 4987482aa6d64b835ce8f6485fd5b0953d939ed94fSasha Levitskiy ALOGW("Warning (%s) while opening the net interface command library", err_str ? err_str : "unknown"); 50329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy } else { 51329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy sendCommandInit_ = (int (*)(void))dlsym(libh_, set_cmd_init_func_name); 52329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy if (sendCommandInit_ == NULL) { 53329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy const char *err_str = dlerror(); 54329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy ALOGW("Error (%s) while searching for the interface command init function", err_str ? err_str : "unknown"); 55329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy } else if (sendCommandInit_()) { 56329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy ALOGE("Can't init the interface command API"); 57329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy return; 58329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy } 59329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy sendCommandFini_ = (int (*)(void))dlsym(libh_, set_cmd_fini_func_name); 60329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy if (sendCommandFini_ == NULL) { 61329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy const char *err_str = dlerror(); 62329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy ALOGW("Error (%s) while searching for the interface command fini function", err_str ? err_str : "unknown"); 63329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy } 64329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy sendCommand_ = (int (*)(int, char **, char **))dlsym(libh_, set_cmd_func_name); 65329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy if (sendCommand_ == NULL) { 66329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy const char *err_str = dlerror(); 67329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy ALOGE("Error (%s) while searching for the interface command function", err_str ? err_str : "unknown"); 68329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy return; 69329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy } 70329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy } 712eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt} 722eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 73329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha LevitskiyInterfaceController::~InterfaceController() { 74329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy if (sendCommandFini_) { 75329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy if (sendCommandFini_()) { 76329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy ALOGE("Can't shutdown the interface command API"); 77329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy } 78329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy } 79329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy if (libh_) { 80329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy int err = dlclose(libh_); 81329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy if (err) { 82329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy const char *err_str = dlerror(); 83329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy ALOGE("Error (%s) while closing the net interface command library", err_str ? err_str : "unknown"); 84329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy } 85329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy } 862eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt} 872eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 882eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt/* 892eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Arguments: 90329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy * argv[2] - wlan interface 91329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy * argv[3] - command 92329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy * argv[4] - argument 93329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy * rbuf - returned buffer 942eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt */ 952eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidtint InterfaceController::interfaceCommand(int argc, char *argv[], char **rbuf) { 96329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy int ret = -ENOSYS; 97329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy if (sendCommand_) 98329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy ret = sendCommand_(argc, argv, rbuf); 992eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 100329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy return ret; 1012eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt} 102