nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
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 }