1 #include <errno.h> 2 #include <fcntl.h> 3 #include <string.h> 4 #include <net/if.h> 5 #include <sys/socket.h> 6 #include <sys/stat.h> 7 #include <sys/ioctl.h> 8 #include <sys/types.h> 9 10 #include <netinet/in.h> 11 #include <arpa/inet.h> 12 13 #include <cutils/log.h> 14 #include <netutils/ifc.h> 15 #include <private/android_filesystem_config.h> 16 17 #define INTERFACE_MAX_BUFFER_SIZE 4096 18 19 typedef struct android_wifi_priv_cmd { 20 char *buf; 21 int used_len; 22 int total_len; 23 } android_wifi_priv_cmd; 24 25 static struct net_if_snd_cmd_state { 26 int sock; 27 char cmd[INTERFACE_MAX_BUFFER_SIZE]; 28 char ibuf[INTERFACE_MAX_BUFFER_SIZE]; 29 } state; 30 31 int net_iface_send_command_init(void) { 32 state.sock = socket(AF_INET, SOCK_DGRAM, 0); 33 if (state.sock < 0) { 34 return -ENOTCONN; 35 } else { 36 return 0; 37 } 38 } 39 40 /* 41 * Arguments: 42 * argv[2] - wlan interface 43 * argv[3] - command 44 * argv[4] - argument 45 */ 46 int net_iface_send_command(int argc, char *argv[], char **rbuf) { 47 int ret, i; 48 size_t bc = 0; 49 struct ifreq ifr; 50 android_wifi_priv_cmd priv_cmd; 51 52 if (argc < 3) { 53 return -EINVAL; 54 } 55 for (i = 3; i < argc; i++) { 56 bc += snprintf(&state.cmd[bc], sizeof(state.cmd) - bc, "%s ", argv[i]); 57 if (bc >= sizeof(state.cmd)) { 58 return -ENOBUFS; 59 } 60 } 61 state.cmd[bc] = '\0'; 62 63 memset(&ifr, 0, sizeof(ifr)); 64 strncpy(ifr.ifr_name, argv[2], IFNAMSIZ); 65 strncpy(state.ibuf, state.cmd, INTERFACE_MAX_BUFFER_SIZE); 66 67 priv_cmd.buf = state.ibuf; 68 priv_cmd.used_len = INTERFACE_MAX_BUFFER_SIZE; 69 priv_cmd.total_len = INTERFACE_MAX_BUFFER_SIZE; 70 71 ifr.ifr_data = &priv_cmd; 72 73 if ((ret = ioctl(state.sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) { 74 return ret; 75 } 76 77 if (rbuf) 78 *rbuf = state.ibuf; 79 else 80 ret = -EFAULT; 81 82 return ret; 83 } 84