Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nu11secur1ty
GitHub Repository: nu11secur1ty/Kali-Linux
Path: blob/master/ALFA-W1F1/RTL8814AU/core/rtw_br_ext.c
1307 views
1
/******************************************************************************
2
*
3
* Copyright(c) 2007 - 2017 Realtek Corporation.
4
*
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms of version 2 of the GNU General Public License as
7
* published by the Free Software Foundation.
8
*
9
* This program is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
* more details.
13
*
14
*****************************************************************************/
15
#define _RTW_BR_EXT_C_
16
17
#ifdef __KERNEL__
18
#include <linux/if_arp.h>
19
#include <net/ip.h>
20
#include <linux/atalk.h>
21
#include <linux/udp.h>
22
#include <linux/if_pppox.h>
23
#endif
24
25
#if 1 /* rtw_wifi_driver */
26
#include <drv_types.h>
27
#else /* rtw_wifi_driver */
28
#include "./8192cd_cfg.h"
29
30
#ifndef __KERNEL__
31
#include "./sys-support.h"
32
#endif
33
34
#include "./8192cd.h"
35
#include "./8192cd_headers.h"
36
#include "./8192cd_br_ext.h"
37
#include "./8192cd_debug.h"
38
#endif /* rtw_wifi_driver */
39
40
#ifdef CL_IPV6_PASS
41
#ifdef __KERNEL__
42
#include <linux/ipv6.h>
43
#include <linux/icmpv6.h>
44
#include <net/ndisc.h>
45
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
46
#include <net/ip6_checksum.h>
47
#else
48
#include <net/checksum.h>
49
#endif
50
#endif
51
#endif
52
53
#ifdef CONFIG_BR_EXT
54
55
/* #define BR_EXT_DEBUG */
56
57
#define NAT25_IPV4 01
58
#define NAT25_IPV6 02
59
#define NAT25_IPX 03
60
#define NAT25_APPLE 04
61
#define NAT25_PPPOE 05
62
63
#define RTL_RELAY_TAG_LEN (ETH_ALEN)
64
#define TAG_HDR_LEN 4
65
66
#define MAGIC_CODE 0x8186
67
#define MAGIC_CODE_LEN 2
68
#define WAIT_TIME_PPPOE 5 /* waiting time for pppoe server in sec */
69
70
/*-----------------------------------------------------------------
71
How database records network address:
72
0 1 2 3 4 5 6 7 8 9 10
73
|----|----|----|----|----|----|----|----|----|----|----|
74
IPv4 |type| | IP addr |
75
IPX |type| Net addr | Node addr |
76
IPX |type| Net addr |Sckt addr|
77
Apple |type| Network |node|
78
PPPoE |type| SID | AC MAC |
79
-----------------------------------------------------------------*/
80
81
82
/* Find a tag in pppoe frame and return the pointer */
83
static unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type)
84
{
85
unsigned char *cur_ptr, *start_ptr;
86
unsigned short tagLen, tagType;
87
88
start_ptr = cur_ptr = (unsigned char *)ph->tag;
89
while ((cur_ptr - start_ptr) < ntohs(ph->length)) {
90
/* prevent un-alignment access */
91
tagType = (unsigned short)((cur_ptr[0] << 8) + cur_ptr[1]);
92
tagLen = (unsigned short)((cur_ptr[2] << 8) + cur_ptr[3]);
93
if (tagType == type)
94
return cur_ptr;
95
cur_ptr = cur_ptr + TAG_HDR_LEN + tagLen;
96
}
97
return 0;
98
}
99
100
101
static int __nat25_add_pppoe_tag(struct sk_buff *skb, struct pppoe_tag *tag)
102
{
103
struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN);
104
int data_len;
105
106
data_len = tag->tag_len + TAG_HDR_LEN;
107
if (skb_tailroom(skb) < data_len) {
108
_DEBUG_ERR("skb_tailroom() failed in add SID tag!\n");
109
return -1;
110
}
111
112
skb_put(skb, data_len);
113
/* have a room for new tag */
114
memmove(((unsigned char *)ph->tag + data_len), (unsigned char *)ph->tag, ntohs(ph->length));
115
ph->length = htons(ntohs(ph->length) + data_len);
116
memcpy((unsigned char *)ph->tag, tag, data_len);
117
return data_len;
118
}
119
120
static int skb_pull_and_merge(struct sk_buff *skb, unsigned char *src, int len)
121
{
122
int tail_len;
123
unsigned long end, tail;
124
125
if ((src + len) > skb_tail_pointer(skb) || skb->len < len)
126
return -1;
127
128
tail = (unsigned long)skb_tail_pointer(skb);
129
end = (unsigned long)src + len;
130
if (tail < end)
131
return -1;
132
133
tail_len = (int)(tail - end);
134
if (tail_len > 0)
135
memmove(src, src + len, tail_len);
136
137
skb_trim(skb, skb->len - len);
138
return 0;
139
}
140
141
static unsigned long __nat25_timeout(_adapter *priv)
142
{
143
unsigned long timeout;
144
145
timeout = jiffies - NAT25_AGEING_TIME * HZ;
146
147
return timeout;
148
}
149
150
151
static int __nat25_has_expired(_adapter *priv,
152
struct nat25_network_db_entry *fdb)
153
{
154
if (time_before_eq(fdb->ageing_timer, __nat25_timeout(priv)))
155
return 1;
156
157
return 0;
158
}
159
160
161
static void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr,
162
unsigned int *ipAddr)
163
{
164
memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
165
166
networkAddr[0] = NAT25_IPV4;
167
memcpy(networkAddr + 7, (unsigned char *)ipAddr, 4);
168
}
169
170
171
static void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr,
172
unsigned char *ac_mac, unsigned short *sid)
173
{
174
memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
175
176
networkAddr[0] = NAT25_PPPOE;
177
memcpy(networkAddr + 1, (unsigned char *)sid, 2);
178
memcpy(networkAddr + 3, (unsigned char *)ac_mac, 6);
179
}
180
181
182
#ifdef CL_IPV6_PASS
183
static void __nat25_generate_ipv6_network_addr(unsigned char *networkAddr,
184
unsigned int *ipAddr)
185
{
186
memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
187
188
networkAddr[0] = NAT25_IPV6;
189
memcpy(networkAddr + 1, (unsigned char *)ipAddr, 16);
190
}
191
192
193
static unsigned char *scan_tlv(unsigned char *data, int len, unsigned char tag, unsigned char len8b)
194
{
195
while (len > 0) {
196
if (*data == tag && *(data + 1) == len8b && len >= len8b * 8)
197
return data + 2;
198
199
len -= (*(data + 1)) * 8;
200
data += (*(data + 1)) * 8;
201
}
202
return NULL;
203
}
204
205
206
static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char *replace_mac)
207
{
208
struct icmp6hdr *icmphdr = (struct icmp6hdr *)data;
209
unsigned char *mac;
210
211
if (icmphdr->icmp6_type == NDISC_ROUTER_SOLICITATION) {
212
if (len >= 8) {
213
mac = scan_tlv(&data[8], len - 8, 1, 1);
214
if (mac) {
215
RTW_INFO("Router Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
216
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
217
replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
218
memcpy(mac, replace_mac, 6);
219
return 1;
220
}
221
}
222
} else if (icmphdr->icmp6_type == NDISC_ROUTER_ADVERTISEMENT) {
223
if (len >= 16) {
224
mac = scan_tlv(&data[16], len - 16, 1, 1);
225
if (mac) {
226
RTW_INFO("Router Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
227
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
228
replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
229
memcpy(mac, replace_mac, 6);
230
return 1;
231
}
232
}
233
} else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) {
234
if (len >= 24) {
235
mac = scan_tlv(&data[24], len - 24, 1, 1);
236
if (mac) {
237
RTW_INFO("Neighbor Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
238
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
239
replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
240
memcpy(mac, replace_mac, 6);
241
return 1;
242
}
243
}
244
} else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) {
245
if (len >= 24) {
246
mac = scan_tlv(&data[24], len - 24, 2, 1);
247
if (mac) {
248
RTW_INFO("Neighbor Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
249
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
250
replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
251
memcpy(mac, replace_mac, 6);
252
return 1;
253
}
254
}
255
} else if (icmphdr->icmp6_type == NDISC_REDIRECT) {
256
if (len >= 40) {
257
mac = scan_tlv(&data[40], len - 40, 2, 1);
258
if (mac) {
259
RTW_INFO("Redirect, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
260
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
261
replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
262
memcpy(mac, replace_mac, 6);
263
return 1;
264
}
265
}
266
}
267
return 0;
268
}
269
270
#ifdef SUPPORT_RX_UNI2MCAST
271
static void convert_ipv6_mac_to_mc(struct sk_buff *skb)
272
{
273
struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN);
274
unsigned char *dst_mac = skb->data;
275
276
/* dst_mac[0] = 0xff; */
277
/* dst_mac[1] = 0xff; */
278
/*modified by qinjunjie,ipv6 multicast address ix 0x33-33-xx-xx-xx-xx*/
279
dst_mac[0] = 0x33;
280
dst_mac[1] = 0x33;
281
memcpy(&dst_mac[2], &iph->daddr.s6_addr32[3], 4);
282
#if defined(__LINUX_2_6__)
283
/*modified by qinjunjie,warning:should not remove next line*/
284
skb->pkt_type = PACKET_MULTICAST;
285
#endif
286
}
287
#endif /* CL_IPV6_PASS */
288
#endif /* SUPPORT_RX_UNI2MCAST */
289
290
291
static int __nat25_network_hash(unsigned char *networkAddr)
292
{
293
if (networkAddr[0] == NAT25_IPV4) {
294
unsigned long x;
295
296
x = networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10];
297
298
return x & (NAT25_HASH_SIZE - 1);
299
} else if (networkAddr[0] == NAT25_IPX) {
300
unsigned long x;
301
302
x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^
303
networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10];
304
305
return x & (NAT25_HASH_SIZE - 1);
306
} else if (networkAddr[0] == NAT25_APPLE) {
307
unsigned long x;
308
309
x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3];
310
311
return x & (NAT25_HASH_SIZE - 1);
312
} else if (networkAddr[0] == NAT25_PPPOE) {
313
unsigned long x;
314
315
x = networkAddr[0] ^ networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8];
316
317
return x & (NAT25_HASH_SIZE - 1);
318
}
319
#ifdef CL_IPV6_PASS
320
else if (networkAddr[0] == NAT25_IPV6) {
321
unsigned long x;
322
323
x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^
324
networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10] ^
325
networkAddr[11] ^ networkAddr[12] ^ networkAddr[13] ^ networkAddr[14] ^ networkAddr[15] ^
326
networkAddr[16];
327
328
return x & (NAT25_HASH_SIZE - 1);
329
}
330
#endif
331
else {
332
unsigned long x = 0;
333
int i;
334
335
for (i = 0; i < MAX_NETWORK_ADDR_LEN; i++)
336
x ^= networkAddr[i];
337
338
return x & (NAT25_HASH_SIZE - 1);
339
}
340
}
341
342
343
static void __network_hash_link(_adapter *priv,
344
struct nat25_network_db_entry *ent, int hash)
345
{
346
/* Caller must _enter_critical_bh already! */
347
/* _irqL irqL; */
348
/* _enter_critical_bh(&priv->br_ext_lock, &irqL); */
349
350
ent->next_hash = priv->nethash[hash];
351
if (ent->next_hash != NULL)
352
ent->next_hash->pprev_hash = &ent->next_hash;
353
priv->nethash[hash] = ent;
354
ent->pprev_hash = &priv->nethash[hash];
355
356
/* _exit_critical_bh(&priv->br_ext_lock, &irqL); */
357
}
358
359
360
static void __network_hash_unlink(struct nat25_network_db_entry *ent)
361
{
362
/* Caller must _enter_critical_bh already! */
363
/* _irqL irqL; */
364
/* _enter_critical_bh(&priv->br_ext_lock, &irqL); */
365
366
*(ent->pprev_hash) = ent->next_hash;
367
if (ent->next_hash != NULL)
368
ent->next_hash->pprev_hash = ent->pprev_hash;
369
ent->next_hash = NULL;
370
ent->pprev_hash = NULL;
371
372
/* _exit_critical_bh(&priv->br_ext_lock, &irqL); */
373
}
374
375
376
static int __nat25_db_network_lookup_and_replace(_adapter *priv,
377
struct sk_buff *skb, unsigned char *networkAddr)
378
{
379
struct nat25_network_db_entry *db;
380
_irqL irqL;
381
_enter_critical_bh(&priv->br_ext_lock, &irqL);
382
383
db = priv->nethash[__nat25_network_hash(networkAddr)];
384
while (db != NULL) {
385
if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) {
386
if (!__nat25_has_expired(priv, db)) {
387
/* replace the destination mac address */
388
memcpy(skb->data, db->macAddr, ETH_ALEN);
389
atomic_inc(&db->use_count);
390
391
#ifdef CL_IPV6_PASS
392
RTW_INFO("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
393
"%02x%02x%02x%02x%02x%02x\n",
394
db->macAddr[0],
395
db->macAddr[1],
396
db->macAddr[2],
397
db->macAddr[3],
398
db->macAddr[4],
399
db->macAddr[5],
400
db->networkAddr[0],
401
db->networkAddr[1],
402
db->networkAddr[2],
403
db->networkAddr[3],
404
db->networkAddr[4],
405
db->networkAddr[5],
406
db->networkAddr[6],
407
db->networkAddr[7],
408
db->networkAddr[8],
409
db->networkAddr[9],
410
db->networkAddr[10],
411
db->networkAddr[11],
412
db->networkAddr[12],
413
db->networkAddr[13],
414
db->networkAddr[14],
415
db->networkAddr[15],
416
db->networkAddr[16]);
417
#else
418
RTW_INFO("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
419
db->macAddr[0],
420
db->macAddr[1],
421
db->macAddr[2],
422
db->macAddr[3],
423
db->macAddr[4],
424
db->macAddr[5],
425
db->networkAddr[0],
426
db->networkAddr[1],
427
db->networkAddr[2],
428
db->networkAddr[3],
429
db->networkAddr[4],
430
db->networkAddr[5],
431
db->networkAddr[6],
432
db->networkAddr[7],
433
db->networkAddr[8],
434
db->networkAddr[9],
435
db->networkAddr[10]);
436
#endif
437
}
438
_exit_critical_bh(&priv->br_ext_lock, &irqL);
439
return 1;
440
}
441
442
db = db->next_hash;
443
}
444
445
_exit_critical_bh(&priv->br_ext_lock, &irqL);
446
return 0;
447
}
448
449
450
static void __nat25_db_network_insert(_adapter *priv,
451
unsigned char *macAddr, unsigned char *networkAddr)
452
{
453
struct nat25_network_db_entry *db;
454
int hash;
455
_irqL irqL;
456
_enter_critical_bh(&priv->br_ext_lock, &irqL);
457
458
hash = __nat25_network_hash(networkAddr);
459
db = priv->nethash[hash];
460
while (db != NULL) {
461
if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) {
462
memcpy(db->macAddr, macAddr, ETH_ALEN);
463
db->ageing_timer = jiffies;
464
_exit_critical_bh(&priv->br_ext_lock, &irqL);
465
return;
466
}
467
468
db = db->next_hash;
469
}
470
471
db = (struct nat25_network_db_entry *) rtw_malloc(sizeof(*db));
472
if (db == NULL) {
473
_exit_critical_bh(&priv->br_ext_lock, &irqL);
474
return;
475
}
476
477
memcpy(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN);
478
memcpy(db->macAddr, macAddr, ETH_ALEN);
479
atomic_set(&db->use_count, 1);
480
db->ageing_timer = jiffies;
481
482
__network_hash_link(priv, db, hash);
483
484
_exit_critical_bh(&priv->br_ext_lock, &irqL);
485
}
486
487
488
static void __nat25_db_print(_adapter *priv)
489
{
490
_irqL irqL;
491
_enter_critical_bh(&priv->br_ext_lock, &irqL);
492
493
#ifdef BR_EXT_DEBUG
494
static int counter = 0;
495
int i, j;
496
struct nat25_network_db_entry *db;
497
498
counter++;
499
if ((counter % 16) != 0)
500
return;
501
502
for (i = 0, j = 0; i < NAT25_HASH_SIZE; i++) {
503
db = priv->nethash[i];
504
505
while (db != NULL) {
506
#ifdef CL_IPV6_PASS
507
panic_printk("NAT25: DB(%d) H(%02d) C(%d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
508
"%02x%02x%02x%02x%02x%02x\n",
509
j,
510
i,
511
atomic_read(&db->use_count),
512
db->macAddr[0],
513
db->macAddr[1],
514
db->macAddr[2],
515
db->macAddr[3],
516
db->macAddr[4],
517
db->macAddr[5],
518
db->networkAddr[0],
519
db->networkAddr[1],
520
db->networkAddr[2],
521
db->networkAddr[3],
522
db->networkAddr[4],
523
db->networkAddr[5],
524
db->networkAddr[6],
525
db->networkAddr[7],
526
db->networkAddr[8],
527
db->networkAddr[9],
528
db->networkAddr[10],
529
db->networkAddr[11],
530
db->networkAddr[12],
531
db->networkAddr[13],
532
db->networkAddr[14],
533
db->networkAddr[15],
534
db->networkAddr[16]);
535
#else
536
panic_printk("NAT25: DB(%d) H(%02d) C(%d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
537
j,
538
i,
539
atomic_read(&db->use_count),
540
db->macAddr[0],
541
db->macAddr[1],
542
db->macAddr[2],
543
db->macAddr[3],
544
db->macAddr[4],
545
db->macAddr[5],
546
db->networkAddr[0],
547
db->networkAddr[1],
548
db->networkAddr[2],
549
db->networkAddr[3],
550
db->networkAddr[4],
551
db->networkAddr[5],
552
db->networkAddr[6],
553
db->networkAddr[7],
554
db->networkAddr[8],
555
db->networkAddr[9],
556
db->networkAddr[10]);
557
#endif
558
j++;
559
560
db = db->next_hash;
561
}
562
}
563
#endif
564
565
_exit_critical_bh(&priv->br_ext_lock, &irqL);
566
}
567
568
569
570
571
/*
572
* NAT2.5 interface
573
*/
574
575
void nat25_db_cleanup(_adapter *priv)
576
{
577
int i;
578
_irqL irqL;
579
_enter_critical_bh(&priv->br_ext_lock, &irqL);
580
581
for (i = 0; i < NAT25_HASH_SIZE; i++) {
582
struct nat25_network_db_entry *f;
583
f = priv->nethash[i];
584
while (f != NULL) {
585
struct nat25_network_db_entry *g;
586
587
g = f->next_hash;
588
if (priv->scdb_entry == f) {
589
memset(priv->scdb_mac, 0, ETH_ALEN);
590
memset(priv->scdb_ip, 0, 4);
591
priv->scdb_entry = NULL;
592
}
593
__network_hash_unlink(f);
594
rtw_mfree((u8 *) f, sizeof(struct nat25_network_db_entry));
595
596
f = g;
597
}
598
}
599
600
_exit_critical_bh(&priv->br_ext_lock, &irqL);
601
}
602
603
604
void nat25_db_expire(_adapter *priv)
605
{
606
int i;
607
_irqL irqL;
608
_enter_critical_bh(&priv->br_ext_lock, &irqL);
609
610
/* if(!priv->ethBrExtInfo.nat25_disable) */
611
{
612
for (i = 0; i < NAT25_HASH_SIZE; i++) {
613
struct nat25_network_db_entry *f;
614
f = priv->nethash[i];
615
616
while (f != NULL) {
617
struct nat25_network_db_entry *g;
618
g = f->next_hash;
619
620
if (__nat25_has_expired(priv, f)) {
621
if (atomic_dec_and_test(&f->use_count)) {
622
#ifdef BR_EXT_DEBUG
623
#ifdef CL_IPV6_PASS
624
panic_printk("NAT25 Expire H(%02d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
625
"%02x%02x%02x%02x%02x%02x\n",
626
i,
627
f->macAddr[0],
628
f->macAddr[1],
629
f->macAddr[2],
630
f->macAddr[3],
631
f->macAddr[4],
632
f->macAddr[5],
633
f->networkAddr[0],
634
f->networkAddr[1],
635
f->networkAddr[2],
636
f->networkAddr[3],
637
f->networkAddr[4],
638
f->networkAddr[5],
639
f->networkAddr[6],
640
f->networkAddr[7],
641
f->networkAddr[8],
642
f->networkAddr[9],
643
f->networkAddr[10],
644
f->networkAddr[11],
645
f->networkAddr[12],
646
f->networkAddr[13],
647
f->networkAddr[14],
648
f->networkAddr[15],
649
f->networkAddr[16]);
650
#else
651
652
panic_printk("NAT25 Expire H(%02d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
653
i,
654
f->macAddr[0],
655
f->macAddr[1],
656
f->macAddr[2],
657
f->macAddr[3],
658
f->macAddr[4],
659
f->macAddr[5],
660
f->networkAddr[0],
661
f->networkAddr[1],
662
f->networkAddr[2],
663
f->networkAddr[3],
664
f->networkAddr[4],
665
f->networkAddr[5],
666
f->networkAddr[6],
667
f->networkAddr[7],
668
f->networkAddr[8],
669
f->networkAddr[9],
670
f->networkAddr[10]);
671
#endif
672
#endif
673
if (priv->scdb_entry == f) {
674
memset(priv->scdb_mac, 0, ETH_ALEN);
675
memset(priv->scdb_ip, 0, 4);
676
priv->scdb_entry = NULL;
677
}
678
__network_hash_unlink(f);
679
rtw_mfree((u8 *) f, sizeof(struct nat25_network_db_entry));
680
}
681
}
682
683
f = g;
684
}
685
}
686
}
687
688
_exit_critical_bh(&priv->br_ext_lock, &irqL);
689
}
690
691
692
#ifdef SUPPORT_TX_MCAST2UNI
693
static int checkIPMcAndReplace(_adapter *priv, struct sk_buff *skb, unsigned int *dst_ip)
694
{
695
struct stat_info *pstat;
696
struct list_head *phead, *plist;
697
int i;
698
699
phead = &priv->asoc_list;
700
plist = phead->next;
701
702
while (plist != phead) {
703
pstat = list_entry(plist, struct stat_info, asoc_list);
704
plist = plist->next;
705
706
if (pstat->ipmc_num == 0)
707
continue;
708
709
for (i = 0; i < MAX_IP_MC_ENTRY; i++) {
710
if (pstat->ipmc[i].used && !memcmp(&pstat->ipmc[i].mcmac[3], ((unsigned char *)dst_ip) + 1, 3)) {
711
memcpy(skb->data, pstat->ipmc[i].mcmac, ETH_ALEN);
712
return 1;
713
}
714
}
715
}
716
return 0;
717
}
718
#endif
719
720
int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method)
721
{
722
unsigned short protocol;
723
unsigned char networkAddr[MAX_NETWORK_ADDR_LEN];
724
725
if (skb == NULL)
726
return -1;
727
728
if ((method <= NAT25_MIN) || (method >= NAT25_MAX))
729
return -1;
730
731
protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN));
732
733
/*---------------------------------------------------*/
734
/* Handle IP frame */
735
/*---------------------------------------------------*/
736
if (protocol == __constant_htons(ETH_P_IP)) {
737
struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN);
738
739
if (((unsigned char *)(iph) + (iph->ihl << 2)) >= (skb->data + ETH_HLEN + skb->len)) {
740
DEBUG_WARN("NAT25: malformed IP packet !\n");
741
return -1;
742
}
743
744
switch (method) {
745
case NAT25_CHECK:
746
return -1;
747
748
case NAT25_INSERT: {
749
/* some muticast with source IP is all zero, maybe other case is illegal */
750
/* in class A, B, C, host address is all zero or all one is illegal */
751
if (iph->saddr == 0)
752
return 0;
753
RTW_INFO("NAT25: Insert IP, SA=%08x, DA=%08x\n", iph->saddr, iph->daddr);
754
__nat25_generate_ipv4_network_addr(networkAddr, &iph->saddr);
755
/* record source IP address and , source mac address into db */
756
__nat25_db_network_insert(priv, skb->data + ETH_ALEN, networkAddr);
757
758
__nat25_db_print(priv);
759
}
760
return 0;
761
762
case NAT25_LOOKUP: {
763
RTW_INFO("NAT25: Lookup IP, SA=%08x, DA=%08x\n", iph->saddr, iph->daddr);
764
#ifdef SUPPORT_TX_MCAST2UNI
765
if (priv->pshare->rf_ft_var.mc2u_disable ||
766
((((OPMODE & (WIFI_STATION_STATE | WIFI_ASOC_STATE))
767
== (WIFI_STATION_STATE | WIFI_ASOC_STATE)) &&
768
!checkIPMcAndReplace(priv, skb, &iph->daddr)) ||
769
(OPMODE & WIFI_ADHOC_STATE)))
770
#endif
771
{
772
__nat25_generate_ipv4_network_addr(networkAddr, &iph->daddr);
773
774
if (!__nat25_db_network_lookup_and_replace(priv, skb, networkAddr)) {
775
if (*((unsigned char *)&iph->daddr + 3) == 0xff) {
776
/* L2 is unicast but L3 is broadcast, make L2 bacome broadcast */
777
RTW_INFO("NAT25: Set DA as boardcast\n");
778
memset(skb->data, 0xff, ETH_ALEN);
779
} else {
780
/* forward unknow IP packet to upper TCP/IP */
781
RTW_INFO("NAT25: Replace DA with BR's MAC\n");
782
if ((*(u32 *)priv->br_mac) == 0 && (*(u16 *)(priv->br_mac + 4)) == 0) {
783
void netdev_br_init(struct net_device *netdev);
784
printk("Re-init netdev_br_init() due to br_mac==0!\n");
785
netdev_br_init(priv->pnetdev);
786
}
787
memcpy(skb->data, priv->br_mac, ETH_ALEN);
788
}
789
}
790
}
791
}
792
return 0;
793
794
default:
795
return -1;
796
}
797
}
798
799
/*---------------------------------------------------*/
800
/* Handle ARP frame */
801
/*---------------------------------------------------*/
802
else if (protocol == __constant_htons(ETH_P_ARP)) {
803
struct arphdr *arp = (struct arphdr *)(skb->data + ETH_HLEN);
804
unsigned char *arp_ptr = (unsigned char *)(arp + 1);
805
unsigned int *sender, *target;
806
807
if (arp->ar_pro != __constant_htons(ETH_P_IP)) {
808
DEBUG_WARN("NAT25: arp protocol unknown (%4x)!\n", htons(arp->ar_pro));
809
return -1;
810
}
811
812
switch (method) {
813
case NAT25_CHECK:
814
return 0; /* skb_copy for all ARP frame */
815
816
case NAT25_INSERT: {
817
RTW_INFO("NAT25: Insert ARP, MAC=%02x%02x%02x%02x%02x%02x\n", arp_ptr[0],
818
arp_ptr[1], arp_ptr[2], arp_ptr[3], arp_ptr[4], arp_ptr[5]);
819
820
/* change to ARP sender mac address to wlan STA address */
821
memcpy(arp_ptr, GET_MY_HWADDR(priv), ETH_ALEN);
822
823
arp_ptr += arp->ar_hln;
824
sender = (unsigned int *)arp_ptr;
825
826
__nat25_generate_ipv4_network_addr(networkAddr, sender);
827
828
__nat25_db_network_insert(priv, skb->data + ETH_ALEN, networkAddr);
829
830
__nat25_db_print(priv);
831
}
832
return 0;
833
834
case NAT25_LOOKUP: {
835
RTW_INFO("NAT25: Lookup ARP\n");
836
837
arp_ptr += arp->ar_hln;
838
sender = (unsigned int *)arp_ptr;
839
arp_ptr += (arp->ar_hln + arp->ar_pln);
840
target = (unsigned int *)arp_ptr;
841
842
__nat25_generate_ipv4_network_addr(networkAddr, target);
843
844
__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
845
846
/* change to ARP target mac address to Lookup result */
847
arp_ptr = (unsigned char *)(arp + 1);
848
arp_ptr += (arp->ar_hln + arp->ar_pln);
849
memcpy(arp_ptr, skb->data, ETH_ALEN);
850
}
851
return 0;
852
853
default:
854
return -1;
855
}
856
}
857
858
/*---------------------------------------------------*/
859
/* Handle PPPoE frame */
860
/*---------------------------------------------------*/
861
else if ((protocol == __constant_htons(ETH_P_PPP_DISC)) ||
862
(protocol == __constant_htons(ETH_P_PPP_SES))) {
863
struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN);
864
unsigned short *pMagic;
865
866
switch (method) {
867
case NAT25_CHECK:
868
if (ph->sid == 0)
869
return 0;
870
return 1;
871
872
case NAT25_INSERT:
873
if (ph->sid == 0) { /* Discovery phase according to tag */
874
if (ph->code == PADI_CODE || ph->code == PADR_CODE) {
875
if (priv->ethBrExtInfo.addPPPoETag) {
876
struct pppoe_tag *tag, *pOldTag;
877
unsigned char tag_buf[40];
878
int old_tag_len = 0;
879
880
tag = (struct pppoe_tag *)tag_buf;
881
pOldTag = (struct pppoe_tag *)__nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID));
882
if (pOldTag) { /* if SID existed, copy old value and delete it */
883
old_tag_len = ntohs(pOldTag->tag_len);
884
if (old_tag_len + TAG_HDR_LEN + MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN > sizeof(tag_buf)) {
885
DEBUG_ERR("SID tag length too long!\n");
886
return -1;
887
}
888
889
memcpy(tag->tag_data + MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN,
890
pOldTag->tag_data, old_tag_len);
891
892
if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN + old_tag_len) < 0) {
893
DEBUG_ERR("call skb_pull_and_merge() failed in PADI/R packet!\n");
894
return -1;
895
}
896
ph->length = htons(ntohs(ph->length) - TAG_HDR_LEN - old_tag_len);
897
}
898
899
tag->tag_type = PTT_RELAY_SID;
900
tag->tag_len = htons(MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN + old_tag_len);
901
902
/* insert the magic_code+client mac in relay tag */
903
pMagic = (unsigned short *)tag->tag_data;
904
*pMagic = htons(MAGIC_CODE);
905
memcpy(tag->tag_data + MAGIC_CODE_LEN, skb->data + ETH_ALEN, ETH_ALEN);
906
907
/* Add relay tag */
908
if (__nat25_add_pppoe_tag(skb, tag) < 0)
909
return -1;
910
911
RTW_INFO("NAT25: Insert PPPoE, forward %s packet\n",
912
(ph->code == PADI_CODE ? "PADI" : "PADR"));
913
} else { /* not add relay tag */
914
if (priv->pppoe_connection_in_progress &&
915
memcmp(skb->data + ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) {
916
DEBUG_ERR("Discard PPPoE packet due to another PPPoE connection is in progress!\n");
917
return -2;
918
}
919
920
if (priv->pppoe_connection_in_progress == 0)
921
memcpy(priv->pppoe_addr, skb->data + ETH_ALEN, ETH_ALEN);
922
923
priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE;
924
}
925
} else
926
return -1;
927
} else { /* session phase */
928
RTW_INFO("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name);
929
930
__nat25_generate_pppoe_network_addr(networkAddr, skb->data, &(ph->sid));
931
932
__nat25_db_network_insert(priv, skb->data + ETH_ALEN, networkAddr);
933
934
__nat25_db_print(priv);
935
936
if (!priv->ethBrExtInfo.addPPPoETag &&
937
priv->pppoe_connection_in_progress &&
938
!memcmp(skb->data + ETH_ALEN, priv->pppoe_addr, ETH_ALEN))
939
priv->pppoe_connection_in_progress = 0;
940
}
941
return 0;
942
943
case NAT25_LOOKUP:
944
if (ph->code == PADO_CODE || ph->code == PADS_CODE) {
945
if (priv->ethBrExtInfo.addPPPoETag) {
946
struct pppoe_tag *tag;
947
unsigned char *ptr;
948
unsigned short tagType, tagLen;
949
int offset = 0;
950
951
ptr = __nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID));
952
if (ptr == 0) {
953
DEBUG_ERR("Fail to find PTT_RELAY_SID in FADO!\n");
954
return -1;
955
}
956
957
tag = (struct pppoe_tag *)ptr;
958
tagType = (unsigned short)((ptr[0] << 8) + ptr[1]);
959
tagLen = (unsigned short)((ptr[2] << 8) + ptr[3]);
960
961
if ((tagType != ntohs(PTT_RELAY_SID)) || (tagLen < (MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN))) {
962
DEBUG_ERR("Invalid PTT_RELAY_SID tag length [%d]!\n", tagLen);
963
return -1;
964
}
965
966
pMagic = (unsigned short *)tag->tag_data;
967
if (ntohs(*pMagic) != MAGIC_CODE) {
968
DEBUG_ERR("Can't find MAGIC_CODE in %s packet!\n",
969
(ph->code == PADO_CODE ? "PADO" : "PADS"));
970
return -1;
971
}
972
973
memcpy(skb->data, tag->tag_data + MAGIC_CODE_LEN, ETH_ALEN);
974
975
if (tagLen > MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN)
976
offset = TAG_HDR_LEN;
977
978
if (skb_pull_and_merge(skb, ptr + offset, TAG_HDR_LEN + MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN - offset) < 0) {
979
DEBUG_ERR("call skb_pull_and_merge() failed in PADO packet!\n");
980
return -1;
981
}
982
ph->length = htons(ntohs(ph->length) - (TAG_HDR_LEN + MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN - offset));
983
if (offset > 0)
984
tag->tag_len = htons(tagLen - MAGIC_CODE_LEN - RTL_RELAY_TAG_LEN);
985
986
RTW_INFO("NAT25: Lookup PPPoE, forward %s Packet from %s\n",
987
(ph->code == PADO_CODE ? "PADO" : "PADS"), skb->dev->name);
988
} else { /* not add relay tag */
989
if (!priv->pppoe_connection_in_progress) {
990
DEBUG_ERR("Discard PPPoE packet due to no connection in progresss!\n");
991
return -1;
992
}
993
memcpy(skb->data, priv->pppoe_addr, ETH_ALEN);
994
priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE;
995
}
996
} else {
997
if (ph->sid != 0) {
998
RTW_INFO("NAT25: Lookup PPPoE, lookup session packet from %s\n", skb->dev->name);
999
__nat25_generate_pppoe_network_addr(networkAddr, skb->data + ETH_ALEN, &(ph->sid));
1000
1001
__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
1002
1003
__nat25_db_print(priv);
1004
} else
1005
return -1;
1006
1007
}
1008
return 0;
1009
1010
default:
1011
return -1;
1012
}
1013
}
1014
1015
/*---------------------------------------------------*/
1016
/* Handle EAP frame */
1017
/*---------------------------------------------------*/
1018
else if (protocol == __constant_htons(0x888e)) {
1019
switch (method) {
1020
case NAT25_CHECK:
1021
return -1;
1022
1023
case NAT25_INSERT:
1024
return 0;
1025
1026
case NAT25_LOOKUP:
1027
return 0;
1028
1029
default:
1030
return -1;
1031
}
1032
}
1033
1034
/*---------------------------------------------------*/
1035
/* Handle C-Media proprietary frame */
1036
/*---------------------------------------------------*/
1037
else if ((protocol == __constant_htons(0xe2ae)) ||
1038
(protocol == __constant_htons(0xe2af))) {
1039
switch (method) {
1040
case NAT25_CHECK:
1041
return -1;
1042
1043
case NAT25_INSERT:
1044
return 0;
1045
1046
case NAT25_LOOKUP:
1047
return 0;
1048
1049
default:
1050
return -1;
1051
}
1052
}
1053
1054
/*---------------------------------------------------*/
1055
/* Handle IPV6 frame */
1056
/*---------------------------------------------------*/
1057
#ifdef CL_IPV6_PASS
1058
else if (protocol == __constant_htons(ETH_P_IPV6)) {
1059
struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN);
1060
1061
if (sizeof(*iph) >= (skb->len - ETH_HLEN)) {
1062
DEBUG_WARN("NAT25: malformed IPv6 packet !\n");
1063
return -1;
1064
}
1065
1066
switch (method) {
1067
case NAT25_CHECK:
1068
if (skb->data[0] & 1)
1069
return 0;
1070
return -1;
1071
1072
case NAT25_INSERT: {
1073
RTW_INFO("NAT25: Insert IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x,"
1074
" DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n",
1075
iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1], iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3],
1076
iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5], iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7],
1077
iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1], iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3],
1078
iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5], iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]);
1079
1080
if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) {
1081
__nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->saddr);
1082
__nat25_db_network_insert(priv, skb->data + ETH_ALEN, networkAddr);
1083
__nat25_db_print(priv);
1084
1085
if (iph->nexthdr == IPPROTO_ICMPV6 &&
1086
skb->len > (ETH_HLEN + sizeof(*iph) + 4)) {
1087
if (update_nd_link_layer_addr(skb->data + ETH_HLEN + sizeof(*iph),
1088
skb->len - ETH_HLEN - sizeof(*iph), GET_MY_HWADDR(priv))) {
1089
struct icmp6hdr *hdr = (struct icmp6hdr *)(skb->data + ETH_HLEN + sizeof(*iph));
1090
hdr->icmp6_cksum = 0;
1091
hdr->icmp6_cksum = csum_ipv6_magic(&iph->saddr, &iph->daddr,
1092
iph->payload_len,
1093
IPPROTO_ICMPV6,
1094
csum_partial((__u8 *)hdr, iph->payload_len, 0));
1095
}
1096
}
1097
}
1098
}
1099
return 0;
1100
1101
case NAT25_LOOKUP:
1102
RTW_INFO("NAT25: Lookup IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x,"
1103
" DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n",
1104
iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1], iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3],
1105
iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5], iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7],
1106
iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1], iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3],
1107
iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5], iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]);
1108
1109
1110
__nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->daddr);
1111
if (!__nat25_db_network_lookup_and_replace(priv, skb, networkAddr)) {
1112
#ifdef SUPPORT_RX_UNI2MCAST
1113
if (iph->daddr.s6_addr[0] == 0xff)
1114
convert_ipv6_mac_to_mc(skb);
1115
#endif
1116
}
1117
return 0;
1118
1119
default:
1120
return -1;
1121
}
1122
}
1123
#endif /* CL_IPV6_PASS */
1124
1125
return -1;
1126
}
1127
1128
1129
int nat25_handle_frame(_adapter *priv, struct sk_buff *skb)
1130
{
1131
#ifdef BR_EXT_DEBUG
1132
if ((!priv->ethBrExtInfo.nat25_disable) && (!(skb->data[0] & 1))) {
1133
panic_printk("NAT25: Input Frame: DA=%02x%02x%02x%02x%02x%02x SA=%02x%02x%02x%02x%02x%02x\n",
1134
skb->data[0],
1135
skb->data[1],
1136
skb->data[2],
1137
skb->data[3],
1138
skb->data[4],
1139
skb->data[5],
1140
skb->data[6],
1141
skb->data[7],
1142
skb->data[8],
1143
skb->data[9],
1144
skb->data[10],
1145
skb->data[11]);
1146
}
1147
#endif
1148
1149
if (!(skb->data[0] & 1)) {
1150
int is_vlan_tag = 0, i, retval = 0;
1151
unsigned short vlan_hdr = 0;
1152
1153
if (*((unsigned short *)(skb->data + ETH_ALEN * 2)) == __constant_htons(ETH_P_8021Q)) {
1154
is_vlan_tag = 1;
1155
vlan_hdr = *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2));
1156
for (i = 0; i < 6; i++)
1157
*((unsigned short *)(skb->data + ETH_ALEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + ETH_ALEN * 2 - 2 - i * 2));
1158
skb_pull(skb, 4);
1159
}
1160
1161
if (!priv->ethBrExtInfo.nat25_disable) {
1162
_irqL irqL;
1163
_enter_critical_bh(&priv->br_ext_lock, &irqL);
1164
/*
1165
* This function look up the destination network address from
1166
* the NAT2.5 database. Return value = -1 means that the
1167
* corresponding network protocol is NOT support.
1168
*/
1169
if (!priv->ethBrExtInfo.nat25sc_disable &&
1170
(*((unsigned short *)(skb->data + ETH_ALEN * 2)) == __constant_htons(ETH_P_IP)) &&
1171
!memcmp(priv->scdb_ip, skb->data + ETH_HLEN + 16, 4)) {
1172
memcpy(skb->data, priv->scdb_mac, ETH_ALEN);
1173
1174
_exit_critical_bh(&priv->br_ext_lock, &irqL);
1175
} else {
1176
_exit_critical_bh(&priv->br_ext_lock, &irqL);
1177
1178
retval = nat25_db_handle(priv, skb, NAT25_LOOKUP);
1179
}
1180
} else {
1181
if (((*((unsigned short *)(skb->data + ETH_ALEN * 2)) == __constant_htons(ETH_P_IP)) &&
1182
!memcmp(priv->br_ip, skb->data + ETH_HLEN + 16, 4)) ||
1183
((*((unsigned short *)(skb->data + ETH_ALEN * 2)) == __constant_htons(ETH_P_ARP)) &&
1184
!memcmp(priv->br_ip, skb->data + ETH_HLEN + 24, 4))) {
1185
/* for traffic to upper TCP/IP */
1186
retval = nat25_db_handle(priv, skb, NAT25_LOOKUP);
1187
}
1188
}
1189
1190
if (is_vlan_tag) {
1191
skb_push(skb, 4);
1192
for (i = 0; i < 6; i++)
1193
*((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2));
1194
*((unsigned short *)(skb->data + ETH_ALEN * 2)) = __constant_htons(ETH_P_8021Q);
1195
*((unsigned short *)(skb->data + ETH_ALEN * 2 + 2)) = vlan_hdr;
1196
}
1197
1198
if (retval == -1) {
1199
/* DEBUG_ERR("NAT25: Lookup fail!\n"); */
1200
return -1;
1201
}
1202
}
1203
1204
return 0;
1205
}
1206
1207
#if 0
1208
void mac_clone(_adapter *priv, unsigned char *addr)
1209
{
1210
struct sockaddr sa;
1211
1212
memcpy(sa.sa_data, addr, ETH_ALEN);
1213
RTW_INFO("MAC Clone: Addr=%02x%02x%02x%02x%02x%02x\n",
1214
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
1215
rtl8192cd_set_hwaddr(priv->dev, &sa);
1216
}
1217
1218
1219
int mac_clone_handle_frame(_adapter *priv, struct sk_buff *skb)
1220
{
1221
if (priv->ethBrExtInfo.macclone_enable && !priv->macclone_completed) {
1222
if (!(skb->data[ETH_ALEN] & 1)) { /* check any other particular MAC add */
1223
if (memcmp(skb->data + ETH_ALEN, GET_MY_HWADDR(priv), ETH_ALEN) &&
1224
((priv->dev->br_port) &&
1225
memcmp(skb->data + ETH_ALEN, priv->br_mac, ETH_ALEN))) {
1226
mac_clone(priv, skb->data + ETH_ALEN);
1227
priv->macclone_completed = 1;
1228
}
1229
}
1230
}
1231
1232
return 0;
1233
}
1234
#endif /* 0 */
1235
1236
#define SERVER_PORT 67
1237
#define CLIENT_PORT 68
1238
#define DHCP_MAGIC 0x63825363
1239
#define BROADCAST_FLAG 0x8000
1240
1241
struct dhcpMessage {
1242
u_int8_t op;
1243
u_int8_t htype;
1244
u_int8_t hlen;
1245
u_int8_t hops;
1246
u_int32_t xid;
1247
u_int16_t secs;
1248
u_int16_t flags;
1249
u_int32_t ciaddr;
1250
u_int32_t yiaddr;
1251
u_int32_t siaddr;
1252
u_int32_t giaddr;
1253
u_int8_t chaddr[16];
1254
u_int8_t sname[64];
1255
u_int8_t file[128];
1256
u_int32_t cookie;
1257
u_int8_t options[308]; /* 312 - cookie */
1258
};
1259
1260
void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb)
1261
{
1262
if (skb == NULL)
1263
return;
1264
1265
if (!priv->ethBrExtInfo.dhcp_bcst_disable) {
1266
unsigned short protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN));
1267
1268
if (protocol == __constant_htons(ETH_P_IP)) { /* IP */
1269
struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN);
1270
1271
if (iph->protocol == IPPROTO_UDP) { /* UDP */
1272
struct udphdr *udph = (struct udphdr *)((SIZE_PTR)iph + (iph->ihl << 2));
1273
1274
if ((udph->source == __constant_htons(CLIENT_PORT))
1275
&& (udph->dest == __constant_htons(SERVER_PORT))) { /* DHCP request */
1276
struct dhcpMessage *dhcph =
1277
(struct dhcpMessage *)((SIZE_PTR)udph + sizeof(struct udphdr));
1278
1279
if (dhcph->cookie == __constant_htonl(DHCP_MAGIC)) { /* match magic word */
1280
if (!(dhcph->flags & htons(BROADCAST_FLAG))) { /* if not broadcast */
1281
register int sum = 0;
1282
1283
RTW_INFO("DHCP: change flag of DHCP request to broadcast.\n");
1284
/* or BROADCAST flag */
1285
dhcph->flags |= htons(BROADCAST_FLAG);
1286
/* recalculate checksum */
1287
sum = ~(udph->check) & 0xffff;
1288
sum += dhcph->flags;
1289
while (sum >> 16)
1290
sum = (sum & 0xffff) + (sum >> 16);
1291
udph->check = ~sum;
1292
}
1293
}
1294
}
1295
}
1296
}
1297
}
1298
}
1299
1300
1301
void *scdb_findEntry(_adapter *priv, unsigned char *macAddr,
1302
unsigned char *ipAddr)
1303
{
1304
unsigned char networkAddr[MAX_NETWORK_ADDR_LEN];
1305
struct nat25_network_db_entry *db;
1306
int hash;
1307
/* _irqL irqL; */
1308
/* _enter_critical_bh(&priv->br_ext_lock, &irqL); */
1309
1310
__nat25_generate_ipv4_network_addr(networkAddr, (unsigned int *)ipAddr);
1311
hash = __nat25_network_hash(networkAddr);
1312
db = priv->nethash[hash];
1313
while (db != NULL) {
1314
if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) {
1315
/* _exit_critical_bh(&priv->br_ext_lock, &irqL); */
1316
return (void *)db;
1317
}
1318
1319
db = db->next_hash;
1320
}
1321
1322
/* _exit_critical_bh(&priv->br_ext_lock, &irqL); */
1323
return NULL;
1324
}
1325
1326
#endif /* CONFIG_BR_EXT */
1327
1328