-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWTPFrameReceive.c
324 lines (283 loc) · 10.9 KB
/
WTPFrameReceive.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
/*******************************************************************************************
* Copyright (c) 2006-7 Laboratorio di Sistemi di Elaborazione e Bioingegneria Informatica *
* Universita' Campus BioMedico - Italy *
* *
* This program is free software; you can redistribute it and/or modify it under the terms *
* of the GNU General Public License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
* PARTICULAR PURPOSE. See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along with this *
* program; if not, write to the: *
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, *
* MA 02111-1307, USA. *
* *
* --------------------------------------------------------------------------------------- *
* Project: Capwap *
* *
* Author : Ludovico Rossi ([email protected]) *
* Del Moro Andrea ([email protected]) *
* Giovannini Federica ([email protected]) *
* Massimo Vellucci ([email protected]) *
* Mauro Bisson ([email protected]) *
*******************************************************************************************/
#include "WTPFrameReceive.h"
#ifdef DMALLOC
#include "../dmalloc-5.5.0/dmalloc.h"
#endif
int getMacAddr(int sock, char* interface, unsigned char* macAddr)
{
struct ifreq ethreq;
int i;
memset(ðreq, 0, sizeof(ethreq));
strncpy(ethreq.ifr_name, interface, IFNAMSIZ);
if (ioctl(sock, SIOCGIFHWADDR, ðreq)==-1)
{
return 0;
}
for (i=0; i<MAC_ADDR_LEN; i++)
{
macAddr[i]=(unsigned char)ethreq.ifr_hwaddr.sa_data[i];
}
CWDebugLog("\n");
return 1;
}
int extractFrameInfo(char* buffer, char* RSSI, char* SNR, int* dataRate)
{
int signal, noise;
*RSSI=buffer[RSSI_BYTE]-ATHEROS_CONV_VALUE; //RSSI in dBm
signal=buffer[SIGNAL_BYTE]-ATHEROS_CONV_VALUE;
noise=buffer[NOISE_BYTE];
*SNR=(char)signal-noise; //RSN in dB
*dataRate=(buffer[DATARATE_BYTE]/2)*10; //Data rate in Mbps*10
return 1;
}
int extractFrame(CWProtocolMessage** frame, unsigned char* buffer, int len) //len: frame length including prism header
{
CW_CREATE_OBJECT_ERR(*frame, CWProtocolMessage, return 0;);
CWProtocolMessage *auxPtr = *frame;
CW_CREATE_PROTOCOL_MESSAGE(*auxPtr, len-PRISMH_LEN, return 0;);
memcpy(auxPtr->msg, buffer+PRISMH_LEN, len-PRISMH_LEN);
auxPtr->offset=len-PRISMH_LEN;
return 1;
}
int extractAddr(unsigned char* destAddr, unsigned char* sourceAddr, char* frame)
{
memset(destAddr, 0, MAC_ADDR_LEN);
memset(sourceAddr, 0, MAC_ADDR_LEN);
memcpy(destAddr, frame+DEST_ADDR_START, MAC_ADDR_LEN);
memcpy(sourceAddr, frame+SOURCE_ADDR_START, MAC_ADDR_LEN);
return 1;
}
int macAddrCmp (unsigned char* addr1, unsigned char* addr2)
{
int i, ok=1;
/* CWDebugLog("Address 1:");
for (i=0; i<MAC_ADDR_LEN; i++)
{
CWDebugLog("%02x ", addr1[i]);
}
CWDebugLog("\nAddress 2:");
for (i=0; i<MAC_ADDR_LEN; i++)
{
CWDebugLog("%02x ", addr2[i]);
}
CWDebugLog("\n");*/
for (i=0; i<MAC_ADDR_LEN; i++)
{
if (addr1[i]!=addr2[i])
{ok=0;}
}
if (ok==1) {CWDebugLog("MAC Address test: OK\n");}
else {CWDebugLog("MAC Address test: Failed\n");}
return ok;
}
CW_THREAD_RETURN_TYPE CWWTPReceiveFrame(void *arg)
{
const unsigned char VERSION_MASK=3, TYPE_MASK=12, SUBTYPE_MASK=240;
const unsigned char MANAGEMENT_TYPE=0, CONTROL_TYPE=4, DATA_TYPE=8;
int sock, n;
unsigned char buffer[2048];
unsigned char macAddr[MAC_ADDR_LEN];
unsigned char destAddr[MAC_ADDR_LEN];
unsigned char sourceAddr[MAC_ADDR_LEN];
unsigned char byte0, version=0, type=0, subtype=0;
struct sockaddr_ll addr;
CWBindingTransportHeaderValues *bindingValuesPtr=NULL;
CWProtocolMessage* frame=NULL;
CWBindingDataListElement* listElement=NULL;
#ifdef PROMODE_ON
struct ifreq ethreq;
#endif
CWThreadSetSignals(SIG_BLOCK, 1, SIGALRM);
if ((sock=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)))<0)
{
CWDebugLog("THR FRAME: Error creating socket");
CWExitThread();
}
/*
* BUG - UMR02
* It is better to zero the sockaddr structure before
* passing it to the kernel.
*
* 19/10/2009 - Donato Capitella
*/
memset(&addr, 0, sizeof(addr));
addr.sll_family=AF_PACKET;
addr.sll_protocol=htons(ETH_P_ALL);
addr.sll_ifindex=0;
if ((bind(sock, (struct sockaddr*)&addr, sizeof(addr)))<0)
{
CWDebugLog("THR FRAME: Error binding socket");
CWExitThread();
}
if (!getMacAddr(sock, gInterfaceName, macAddr))
{
CWDebugLog("THR FRAME: Ioctl error");
EXIT_THREAD
}
#ifdef PROMODE_ON
/* Set the network card in promiscuos mode */
strncpy(ethreq.ifr_name,gInterfaceName,IFNAMSIZ);
if (ioctl(sock,SIOCGIFFLAGS,ðreq)==-1)
{
CWDebugLog("THR FRAME: Error ioctl");
EXIT_THREAD
}
ethreq.ifr_flags|=IFF_PROMISC;
if (ioctl(sock,SIOCSIFFLAGS,ðreq)==-1)
{
CWDebugLog("THR FRAME: Error ioctl");
EXIT_THREAD
}
#endif
#ifdef FILTER_ON
/* Attach the filter to the socket */
if(setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &Filter, sizeof(Filter))<0)
{
CWDebugLog("THR FRAME: Error attaching filter");
EXIT_THREAD
}
#endif
CW_REPEAT_FOREVER
{
n = recvfrom(sock,buffer,sizeof(buffer),0,NULL,NULL);
if (CHECK_PRISM_HEADER)
{
/*CWDebugLog("----------\n");
CWDebugLog("%d bytes read\n",n);
CWDebugLog("Prism header OK\n");*/
if (n>PRISMH_LEN)
{
byte0=*(buffer+PRISMH_LEN);
version=byte0 & VERSION_MASK;
type=byte0 & TYPE_MASK;
subtype=byte0 & SUBTYPE_MASK;
subtype>>=4;
/* if(version == (unsigned char) VERSION) {CWDebugLog("Version OK\n");}
else {CWDebugLog("Wrong Version");}*/
if(type == (unsigned char) MANAGEMENT_TYPE) //Management Frame
{
//CWDebugLog("Management Frame\n");
//CWDebugLog("Subtype: %d ", subtype);
switch (subtype)
{
case ASSOCIATION_REQUEST_SUBTYPE:
{
if (!extractFrame(&frame, buffer, n))
{
CWDebugLog("THR FRAME: Error extracting a frame");
EXIT_THREAD
}
extractAddr(destAddr, sourceAddr, frame->msg);
int k;
printf("\nAssociation Request received from: ");
for(k=0;k<MAC_ADDR_LEN;k++)
{
printf("%02x", sourceAddr[k]);
if(k!=MAC_ADDR_LEN-1){printf(":");}
}
fflush(stdout);
CW_CREATE_OBJECT_ERR(bindingValuesPtr, CWBindingTransportHeaderValues, EXIT_THREAD);
extractFrameInfo((char*)buffer, &(bindingValuesPtr->RSSI), &(bindingValuesPtr->SNR), &(bindingValuesPtr->dataRate));
CW_CREATE_OBJECT_ERR(listElement, CWBindingDataListElement, EXIT_THREAD);
listElement->frame=frame;
listElement->bindingValues=bindingValuesPtr;
//
CWLockSafeList(gFrameList);
CWAddElementToSafeListTail(gFrameList, listElement, sizeof(CWBindingDataListElement));
CWUnlockSafeList(gFrameList);
break;
}
/* case ASSOCIATION_RESPONSE_SUBTYPE: {CWDebugLog("Association Response\n"); break;}
case REASSOCIATION_REQUEST_SUBTYPE: {CWDebugLog("Reassociation Request\n"); break;}
case REASSOCIATION_RESPONSE_SUBTYPE: {CWDebugLog("Reassociation Response\n"); break;}
case PROBE_REQUEST_SUBTYPE: {CWDebugLog("Probe Request\n"); break;}
case PROBE_RESPONSE_SUBTYPE: {CWDebugLog("Probe Response\n"); break;}
case RESERVED6_SUBTYPE: {CWDebugLog("Reserved\n"); break;}
case RESERVED7_SUBTYPE: {CWDebugLog("Reserved\n"); break;}
case BEACON_SUBTYPE: {CWDebugLog("Beacon\n"); break;}
case ATIM_SUBTYPE: {CWDebugLog("ATIM\n"); break;}
case DISASSOCIATION_SUBTYPE: {CWDebugLog("Disassociation\n"); break;}
case AUTHENTICATION_SUBTYPE: {CWDebugLog("Authentication\n"); break;}
case DEAUTHENTICATION_SUBTYPE: {CWDebugLog("Deauthentication\n"); break;}*/
default: {/*CWDebugLog("Unrecognized Frame\n");*/}
}
}
if(type == (unsigned char) CONTROL_TYPE) //Control Frame
{
/* CWDebugLog("Control Frame\n");
//CWDebugLog("Subtype: %d ", subtype);
switch (subtype)
{
case RESERVED0_SUBTYPE: {CWDebugLog("Reserved\n"); break;}
case RESERVED9_SUBTYPE: {CWDebugLog("Reserved\n"); break;}
case POWER_SAVE_SUBTYPE: {CWDebugLog("Power Save\n"); break;}
case RTS_SUBTYPE: {CWDebugLog("RTS\n"); break;}
case CTS_SUBTYPE: {CWDebugLog("CTS\n"); break;}
case ACKNOLEDGEMENT_SUBTYPE: {CWDebugLog("Acknoledgement\n"); break;}
case CF_END_SUBTYPE: {CWDebugLog("CF-End\n"); break;}
case CF_END_CF_ACK_SUBTYPE: {CWDebugLog("CF-End + CF-Ack\n"); break;}
default: {CWDebugLog("Unrecognized Frame\n");}
}*/
}
if(type == (unsigned char) DATA_TYPE)
{
/* CWDebugLog("Data Frame\n");
//CWDebugLog("Subtype: %d ", subtype);
switch (subtype)
{
case DATA_SUBTYPE: {CWDebugLog("Data\n"); break;}
case DATA_CF_ACK_SUBTYPE: {CWDebugLog("Data + CF-Ack\n"); break;}
case DATA_CF_POLL_SUBTYPE: {CWDebugLog("Data + CF-Poll\n"); break;}
case DATA_CF_ACK_CF_POLL_SUBTYPE: {CWDebugLog("Data + CF-Ack + CF-Poll\n"); break;}
case NO_DATA_SUBTYPE: {CWDebugLog("Null Function (no data)\n"); break;}
case CF_ACK_SUBTYPE: {CWDebugLog("CF-Ack (no data)\n"); break;}
case CF_POLL_SUBTYPE: {CWDebugLog("CF-Poll (no data)\n"); break;}
case CF_ACK_CF_POLL_SUBTYPE: {CWDebugLog("CF-Ack + CF-Poll (no data)\n"); break;}
case RESERVED8_SUBTYPE: {CWDebugLog("Reserved\n"); break;}
case RESERVED15_SUBTYPE: {CWDebugLog("Reserved\n"); break;}
default: {CWDebugLog("Unrecognized Frame\n");}
}*/
}
}
else CWDebugLog("Malformed Frame");
}
else
{
#ifdef WRITE_UNRECOGNIZED
for (i=0;i<n;i++)
{
if (i%16==0) CWDebugLog("\n%04x: ", i);
CWDebugLog("%02x ", buffer[i]);
}
CWDebugLog("\n");
#endif
}
}
close(sock);
return(NULL);
}