nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /*************************************************************************** |
2 | * * |
||
3 | * ########### ########### ########## ########## * |
||
4 | * ############ ############ ############ ############ * |
||
5 | * ## ## ## ## ## ## ## * |
||
6 | * ## ## ## ## ## ## ## * |
||
7 | * ########### #### ###### ## ## ## ## ###### * |
||
8 | * ########### #### # ## ## ## ## # # * |
||
9 | * ## ## ###### ## ## ## ## # # * |
||
10 | * ## ## # ## ## ## ## # # * |
||
11 | * ############ ##### ###### ## ## ## ##### ###### * |
||
12 | * ########### ########### ## ## ## ########## * |
||
13 | * * |
||
14 | * S E C U R E M O B I L E N E T W O R K I N G * |
||
15 | * * |
||
16 | * This file is part of NexMon. * |
||
17 | * * |
||
18 | * Based on: * |
||
19 | * * |
||
20 | * This code is based on the ldpreloadhook example by Pau Oliva Fora * |
||
21 | * <pofłeslack.org> and the idea of hooking ioctls to fake a monitor mode * |
||
22 | * interface, which was presented by Omri Ildis, Yuval Ofir and Ruby * |
||
23 | * Feinstein at recon2013. * |
||
24 | * * |
||
25 | * Copyright (c) 2016 NexMon Team * |
||
26 | * * |
||
27 | * NexMon is free software: you can redistribute it and/or modify * |
||
28 | * it under the terms of the GNU General Public License as published by * |
||
29 | * the Free Software Foundation, either version 3 of the License, or * |
||
30 | * (at your option) any later version. * |
||
31 | * * |
||
32 | * NexMon is distributed in the hope that it will be useful, * |
||
33 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
||
34 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
||
35 | * GNU General Public License for more details. * |
||
36 | * * |
||
37 | * You should have received a copy of the GNU General Public License * |
||
38 | * along with NexMon. If not, see <http://www.gnu.org/licenses/>. * |
||
39 | * * |
||
40 | **************************************************************************/ |
||
41 | |||
42 | #include <stdarg.h> |
||
43 | #include <dlfcn.h> |
||
44 | #include <stdio.h> |
||
45 | #include <stdlib.h> |
||
46 | #include <stdbool.h> |
||
47 | #include <sys/socket.h> |
||
48 | #include <linux/if_arp.h> |
||
49 | #include <linux/sockios.h> |
||
50 | #include <linux/wireless.h> |
||
51 | #include <monitormode.h> |
||
52 | |||
53 | #define WLC_GET_MONITOR 107 |
||
54 | #define WLC_SET_MONITOR 108 |
||
55 | |||
56 | struct nexio { |
||
57 | struct ifreq *ifr; |
||
58 | int sock_rx_ioctl; |
||
59 | int sock_rx_frame; |
||
60 | int sock_tx; |
||
61 | }; |
||
62 | |||
63 | extern int nex_ioctl(struct nexio *nexio, int cmd, void *buf, int len, bool set); |
||
64 | extern struct nexio *nex_init_ioctl(const char *ifname); |
||
65 | |||
66 | #ifndef RTLD_NEXT |
||
67 | #define RTLD_NEXT ((void *) -1l) |
||
68 | #endif |
||
69 | |||
70 | #define REAL_LIBC RTLD_NEXT |
||
71 | |||
72 | typedef int request_t; |
||
73 | |||
74 | typedef void (*sighandler_t)(int); |
||
75 | |||
76 | static struct nexio *nexio = NULL; |
||
77 | |||
78 | static const char *ifname = "wlan0"; |
||
79 | |||
80 | static void _libfakeioctl_init() __attribute__ ((constructor)); |
||
81 | static void _libfakeioctl_init() { |
||
82 | nexio = nex_init_ioctl("wlan0"); |
||
83 | |||
84 | } |
||
85 | |||
86 | int ioctl (int fd, request_t request, ...){ |
||
87 | static int (*func_ioctl) (int, request_t, void *) = NULL; |
||
88 | va_list args; |
||
89 | void *argp; |
||
90 | int ret; |
||
91 | |||
92 | if (! func_ioctl) |
||
93 | func_ioctl = (int (*) (int, request_t, void *)) dlsym (REAL_LIBC, "ioctl"); |
||
94 | va_start (args, request); |
||
95 | argp = va_arg (args, void *); |
||
96 | va_end (args); |
||
97 | |||
98 | ret = func_ioctl(fd, request, argp); |
||
99 | |||
100 | switch (request) { |
||
101 | case SIOCGIFHWADDR: |
||
102 | { |
||
103 | int buf; |
||
104 | struct ifreq* p_ifr = (struct ifreq *) argp; |
||
105 | if (!strncmp(p_ifr->ifr_ifrn.ifrn_name, ifname, strlen(ifname))) { |
||
106 | nex_ioctl(nexio, WLC_GET_MONITOR, &buf, 4, false); |
||
107 | |||
108 | if (buf & MONITOR_IEEE80211) p_ifr->ifr_hwaddr.sa_family = ARPHRD_IEEE80211; |
||
109 | else if (buf & MONITOR_RADIOTAP) p_ifr->ifr_hwaddr.sa_family = ARPHRD_IEEE80211_RADIOTAP; |
||
110 | else if (buf & MONITOR_DISABLED || buf & MONITOR_LOG_ONLY || buf & MONITOR_DROP_FRM || buf & MONITOR_IPV4_UDP) |
||
111 | p_ifr->ifr_hwaddr.sa_family = ARPHRD_ETHER; |
||
112 | } |
||
113 | } |
||
114 | break; |
||
115 | |||
116 | case SIOCGIWMODE: |
||
117 | { |
||
118 | int buf; |
||
119 | struct iwreq* p_wrq = (struct iwreq*) argp; |
||
120 | |||
121 | if (!strncmp(p_wrq->ifr_ifrn.ifrn_name, ifname, strlen(ifname))) { |
||
122 | nex_ioctl(nexio, WLC_GET_MONITOR, &buf, 4, false); |
||
123 | |||
124 | if (buf & MONITOR_RADIOTAP || buf & MONITOR_IEEE80211 || buf & MONITOR_LOG_ONLY || buf & MONITOR_DROP_FRM || buf & MONITOR_IPV4_UDP) { |
||
125 | p_wrq->u.mode = IW_MODE_MONITOR; |
||
126 | } |
||
127 | } |
||
128 | } |
||
129 | break; |
||
130 | |||
131 | case SIOCSIWMODE: |
||
132 | { |
||
133 | int buf; |
||
134 | struct iwreq* p_wrq = (struct iwreq*) argp; |
||
135 | |||
136 | if (!strncmp(p_wrq->ifr_ifrn.ifrn_name, ifname, strlen(ifname))) { |
||
137 | if (p_wrq->u.mode == IW_MODE_MONITOR) { |
||
138 | buf = MONITOR_RADIOTAP; |
||
139 | } else { |
||
140 | buf = MONITOR_DISABLED; |
||
141 | } |
||
142 | |||
143 | ret = nex_ioctl(nexio, WLC_SET_MONITOR, &buf, 4, true); |
||
144 | } |
||
145 | } |
||
146 | break; |
||
147 | } |
||
148 | return ret; |
||
149 | } |