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
net_iface_send_command_init(void)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 */
net_iface_send_command(int argc,char * argv[],char ** rbuf)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