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#ifdef IGMP_SNOOP_SUPPORT
30
31#include "../rt_config.h"
32#include "../ipv6.h"
33#include "../igmp_snoop.h"
34
35
36static inline void initFreeEntryList(
37 IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
38 IN PLIST_HEADER pList)
39{
40 int i;
41
42 for (i = 0; i < FREE_MEMBER_POOL_SIZE; i++)
43 insertTailList(pList, (PLIST_ENTRY)&(pMulticastFilterTable->freeMemberPool[i]));
44
45 return;
46}
47
48static inline PMEMBER_ENTRY AllocaGrpMemberEntry(
49 IN PMULTICAST_FILTER_TABLE pMulticastFilterTable)
50{
51 PMEMBER_ENTRY pMemberEntry;
52
53 RTMP_SEM_LOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
54
55 pMemberEntry = (PMEMBER_ENTRY)removeHeadList(&pMulticastFilterTable->freeEntryList);
56
57 RTMP_SEM_UNLOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
58
59 return (PMEMBER_ENTRY)pMemberEntry;
60}
61
62static inline VOID FreeGrpMemberEntry(
63 IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
64 IN PMEMBER_ENTRY pEntry)
65{
66 RTMP_SEM_LOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
67
68 insertTailList(&pMulticastFilterTable->freeEntryList, (PLIST_ENTRY)pEntry);
69
70 RTMP_SEM_UNLOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
71}
72
73static VOID IGMPTableDisplay(
74 IN PRTMP_ADAPTER pAd);
75
76static BOOLEAN isIgmpMacAddr(
77 IN PUCHAR pMacAddr);
78
79static VOID InsertIgmpMember(
80 IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
81 IN PLIST_HEADER pList,
82 IN PUCHAR pMemberAddr);
83
84static VOID DeleteIgmpMember(
85 IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
86 IN PLIST_HEADER pList,
87 IN PUCHAR pMemberAddr);
88
89static VOID DeleteIgmpMemberList(
90 IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
91 IN PLIST_HEADER pList);
92
93
94
95
96
97
98
99
100VOID MulticastFilterTableInit(
101 IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable)
102{
103
104 *ppMulticastFilterTable = kmalloc(sizeof(MULTICAST_FILTER_TABLE), MEM_ALLOC_FLAG);
105 if (*ppMulticastFilterTable == NULL)
106 {
107 DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for Multicase filter table, size=%d\n",
108 __FUNCTION__, sizeof(MULTICAST_FILTER_TABLE)));
109 return;
110 }
111
112 NdisZeroMemory(*ppMulticastFilterTable, sizeof(MULTICAST_FILTER_TABLE));
113 NdisAllocateSpinLock(&((*ppMulticastFilterTable)->MulticastFilterTabLock));
114
115 NdisAllocateSpinLock(&((*ppMulticastFilterTable)->FreeMemberPoolTabLock));
116 initList(&((*ppMulticastFilterTable)->freeEntryList));
117 initFreeEntryList(*ppMulticastFilterTable, &((*ppMulticastFilterTable)->freeEntryList));
118 return;
119}
120
121
122
123
124
125
126
127VOID MultiCastFilterTableReset(
128 IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable)
129{
130 if(*ppMulticastFilterTable == NULL)
131 {
132 DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
133 return;
134 }
135
136 NdisFreeSpinLock(&((*ppMulticastFilterTable)->FreeMemberPoolTabLock));
137 NdisFreeSpinLock(&((*ppMulticastFilterTable)->MulticastFilterTabLock));
138 kfree(*ppMulticastFilterTable);
139 *ppMulticastFilterTable = NULL;
140}
141
142
143
144
145
146
147
148static VOID IGMPTableDisplay(
149 IN PRTMP_ADAPTER pAd)
150{
151 int i;
152 MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL;
153 PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
154
155 if (pMulticastFilterTable == NULL)
156 {
157 DBGPRINT(RT_DEBUG_OFF, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
158 return;
159 }
160
161
162 if (pMulticastFilterTable->Size == 0)
163 {
164 DBGPRINT(RT_DEBUG_ERROR, ("Table empty.\n"));
165 return;
166 }
167
168
169 RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
170
171 for (i = 0; i< MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++)
172 {
173
174 if (pMulticastFilterTable->Content[i].Valid == TRUE)
175 {
176 PMEMBER_ENTRY pMemberEntry = NULL;
177 pEntry = &pMulticastFilterTable->Content[i];
178
179 DBGPRINT(RT_DEBUG_OFF, ("IF(%s) entry #%d, type=%s, GrpId=(%02x:%02x:%02x:%02x:%02x:%02x) memberCnt=%d\n",
180 RTMP_OS_NETDEV_GET_DEVNAME(pEntry->net_dev), i, (pEntry->type==0 ? "static":"dynamic"),
181 PRINT_MAC(pEntry->Addr), IgmpMemberCnt(&pEntry->MemberList)));
182
183 pMemberEntry = (PMEMBER_ENTRY)pEntry->MemberList.pHead;
184 while (pMemberEntry)
185 {
186 DBGPRINT(RT_DEBUG_OFF, ("member mac=(%02x:%02x:%02x:%02x:%02x:%02x)\n",
187 PRINT_MAC(pMemberEntry->Addr)));
188
189 pMemberEntry = pMemberEntry->pNext;
190 }
191 }
192 }
193
194 RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
195
196 return;
197}
198
199
200
201
202
203
204
205BOOLEAN MulticastFilterTableInsertEntry(
206 IN PRTMP_ADAPTER pAd,
207 IN PUCHAR pGrpId,
208 IN PUCHAR pMemberAddr,
209 IN PNET_DEV dev,
210 IN MulticastFilterEntryType type)
211{
212 UCHAR HashIdx;
213 int i;
214 MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL, *pCurrEntry, *pPrevEntry;
215 PMEMBER_ENTRY pMemberEntry;
216 PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
217
218 if (pMulticastFilterTable == NULL)
219 {
220 DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
221 return FALSE;
222 }
223
224
225 if (pMulticastFilterTable->Size >= MAX_LEN_OF_MULTICAST_FILTER_TABLE)
226 {
227 DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table full. max-entries = %d\n",
228 __FUNCTION__, MAX_LEN_OF_MULTICAST_FILTER_TABLE));
229 return FALSE;
230 }
231
232
233 if ((pEntry = MulticastFilterTableLookup(pMulticastFilterTable, pGrpId, dev)))
234 {
235
236 if(pMemberAddr == NULL)
237 {
238 return FALSE;
239 }
240
241 pMemberEntry = (PMEMBER_ENTRY)pEntry->MemberList.pHead;
242
243 while (pMemberEntry)
244 {
245 if (MAC_ADDR_EQUAL(pMemberAddr, pMemberEntry->Addr))
246 {
247 DBGPRINT(RT_DEBUG_ERROR, ("%s: already in Members list.\n", __FUNCTION__));
248 return FALSE;
249 }
250
251 pMemberEntry = pMemberEntry->pNext;
252 }
253 }
254
255 RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
256 do
257 {
258 ULONG Now;
259
260 if (pEntry != NULL && pMemberAddr != NULL)
261 {
262 InsertIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
263 break;
264 }
265
266
267 for (i = 0; i < MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++)
268 {
269
270 pEntry = &pMulticastFilterTable->Content[i];
271 NdisGetSystemUpTime(&Now);
272 if ((pEntry->Valid == TRUE) && (pEntry->type == MCAT_FILTER_DYNAMIC)
273 && ((Now - pEntry->lastTime) > IGMPMAC_TB_ENTRY_AGEOUT_TIME))
274 {
275 PMULTICAST_FILTER_TABLE_ENTRY pHashEntry;
276
277 HashIdx = MULTICAST_ADDR_HASH_INDEX(pEntry->Addr);
278 pHashEntry = pMulticastFilterTable->Hash[HashIdx];
279
280 if ((pEntry->net_dev == pHashEntry->net_dev)
281 && MAC_ADDR_EQUAL(pEntry->Addr, pHashEntry->Addr))
282 {
283 pMulticastFilterTable->Hash[HashIdx] = pHashEntry->pNext;
284 pMulticastFilterTable->Size --;
285 DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 1 - Total= %d\n", pMulticastFilterTable->Size));
286 } else
287 {
288 while (pHashEntry->pNext)
289 {
290 pPrevEntry = pHashEntry;
291 pHashEntry = pHashEntry->pNext;
292 if ((pEntry->net_dev == pHashEntry->net_dev)
293 && MAC_ADDR_EQUAL(pEntry->Addr, pHashEntry->Addr))
294 {
295 pPrevEntry->pNext = pHashEntry->pNext;
296 pMulticastFilterTable->Size --;
297 DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
298 break;
299 }
300 }
301 }
302 pEntry->Valid = FALSE;
303 DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
304 }
305
306 if (pEntry->Valid == FALSE)
307 {
308 NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
309 pEntry->Valid = TRUE;
310
311 COPY_MAC_ADDR(pEntry->Addr, pGrpId);
312 pEntry->net_dev = dev;
313 NdisGetSystemUpTime(&Now);
314 pEntry->lastTime = Now;
315 pEntry->type = type;
316 initList(&pEntry->MemberList);
317 if (pMemberAddr != NULL)
318 InsertIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
319
320 pMulticastFilterTable->Size ++;
321
322 DBGPRINT(RT_DEBUG_TRACE, ("MulticastFilterTableInsertEntry -IF(%s) allocate entry #%d, Total= %d\n", RTMP_OS_NETDEV_GET_DEVNAME(dev), i, pMulticastFilterTable->Size));
323 break;
324 }
325 }
326
327
328 if (pEntry)
329 {
330 HashIdx = MULTICAST_ADDR_HASH_INDEX(pGrpId);
331 if (pMulticastFilterTable->Hash[HashIdx] == NULL)
332 {
333 pMulticastFilterTable->Hash[HashIdx] = pEntry;
334 } else
335 {
336 pCurrEntry = pMulticastFilterTable->Hash[HashIdx];
337 while (pCurrEntry->pNext != NULL)
338 pCurrEntry = pCurrEntry->pNext;
339 pCurrEntry->pNext = pEntry;
340 }
341 }
342 }while(FALSE);
343
344 RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
345
346 return TRUE;
347}
348
349
350
351
352
353
354
355BOOLEAN MulticastFilterTableDeleteEntry(
356 IN PRTMP_ADAPTER pAd,
357 IN PUCHAR pGrpId,
358 IN PUCHAR pMemberAddr,
359 IN PNET_DEV dev)
360{
361 USHORT HashIdx;
362 MULTICAST_FILTER_TABLE_ENTRY *pEntry, *pPrevEntry;
363 PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
364 USHORT Aid = MCAST_WCID;
365 SST Sst = SST_ASSOC;
366 UCHAR PsMode = PWR_ACTIVE, Rate;
367
368 if (pMulticastFilterTable == NULL)
369 {
370 DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
371 return FALSE;
372 }
373
374 RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
375
376 do
377 {
378 HashIdx = MULTICAST_ADDR_HASH_INDEX(pGrpId);
379 pPrevEntry = pEntry = pMulticastFilterTable->Hash[HashIdx];
380
381 while (pEntry && pEntry->Valid)
382 {
383 if ((pEntry->net_dev == dev)
384 && MAC_ADDR_EQUAL(pEntry->Addr, pGrpId))
385 break;
386 else
387 {
388 pPrevEntry = pEntry;
389 pEntry = pEntry->pNext;
390 }
391 }
392
393
394 if (pEntry && (pMemberAddr != NULL))
395 {
396 if(APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate))
397 DeleteIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
398 if (IgmpMemberCnt(&pEntry->MemberList) > 0)
399 break;
400 }
401
402 if (pEntry)
403 {
404 if (pEntry == pMulticastFilterTable->Hash[HashIdx])
405 {
406 pMulticastFilterTable->Hash[HashIdx] = pEntry->pNext;
407 DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
408 NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
409 pMulticastFilterTable->Size --;
410 DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 1 - Total= %d\n", pMulticastFilterTable->Size));
411 }
412 else
413 {
414 pPrevEntry->pNext = pEntry->pNext;
415 DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
416 NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
417 pMulticastFilterTable->Size --;
418 DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
419 }
420 }
421 else
422 {
423 DBGPRINT(RT_DEBUG_ERROR, ("%s: the Group doesn't exist.\n", __FUNCTION__));
424 }
425 } while(FALSE);
426
427 RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
428
429 return TRUE;
430}
431
432
433
434
435
436
437
438
439
440PMULTICAST_FILTER_TABLE_ENTRY MulticastFilterTableLookup(
441 IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
442 IN PUCHAR pAddr,
443 IN PNET_DEV dev)
444{
445 ULONG HashIdx, Now;
446 PMULTICAST_FILTER_TABLE_ENTRY pEntry = NULL, pPrev = NULL;
447
448 if (pMulticastFilterTable == NULL)
449 {
450 DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
451 return NULL;
452 }
453
454 RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
455
456 HashIdx = MULTICAST_ADDR_HASH_INDEX(pAddr);
457 pEntry = pPrev = pMulticastFilterTable->Hash[HashIdx];
458
459 while (pEntry && pEntry->Valid)
460 {
461 if ((pEntry->net_dev == dev)
462 && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
463 {
464 NdisGetSystemUpTime(&Now);
465 pEntry->lastTime = Now;
466 break;
467 }
468 else
469 {
470 NdisGetSystemUpTime(&Now);
471 if ((pEntry->Valid == TRUE) && (pEntry->type == MCAT_FILTER_DYNAMIC)
472 && RTMP_TIME_AFTER(Now, pEntry->lastTime+IGMPMAC_TB_ENTRY_AGEOUT_TIME))
473 {
474
475 if (pEntry == pMulticastFilterTable->Hash[HashIdx])
476 {
477 pMulticastFilterTable->Hash[HashIdx] = pEntry->pNext;
478 pPrev = pMulticastFilterTable->Hash[HashIdx];
479 DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
480 NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
481 pMulticastFilterTable->Size --;
482 pEntry = pPrev;
483 DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
484 }
485 else
486 {
487 pPrev->pNext = pEntry->pNext;
488 DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
489 NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
490 pMulticastFilterTable->Size --;
491 pEntry = (pPrev == NULL ? NULL: pPrev->pNext);
492 DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
493 }
494 }
495 else
496 {
497 pPrev = pEntry;
498 pEntry = pEntry->pNext;
499 }
500 }
501 }
502
503 RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
504
505 return pEntry;
506}
507
508VOID IGMPSnooping(
509 IN PRTMP_ADAPTER pAd,
510 IN PUCHAR pDstMacAddr,
511 IN PUCHAR pSrcMacAddr,
512 IN PUCHAR pIpHeader,
513 IN PNET_DEV pDev)
514{
515 INT i;
516 INT IpHeaderLen;
517 UCHAR GroupType;
518 UINT16 numOfGroup;
519 UCHAR IgmpVerType;
520 PUCHAR pIgmpHeader;
521 PUCHAR pGroup;
522 UCHAR AuxDataLen;
523 UINT16 numOfSources;
524 PUCHAR pGroupIpAddr;
525 UCHAR GroupMacAddr[6];
526 PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr;
527
528 if(isIgmpPkt(pDstMacAddr, pIpHeader))
529 {
530 IpHeaderLen = (*(pIpHeader + 2) & 0x0f) * 4;
531 pIgmpHeader = pIpHeader + 2 + IpHeaderLen;
532 IgmpVerType = (UCHAR)(*(pIgmpHeader));
533
534 DBGPRINT(RT_DEBUG_TRACE, ("IGMP type=%0x\n", IgmpVerType));
535
536 switch(IgmpVerType)
537 {
538 case IGMP_V1_MEMBERSHIP_REPORT:
539 case IGMP_V2_MEMBERSHIP_REPORT:
540 pGroupIpAddr = (PUCHAR)(pIgmpHeader + 4);
541 ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
542 DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
543 GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
544 MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
545 break;
546
547 case IGMP_LEAVE_GROUP:
548 pGroupIpAddr = (PUCHAR)(pIgmpHeader + 4);
549 ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
550 DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
551 GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
552 MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
553 break;
554
555 case IGMP_V3_MEMBERSHIP_REPORT:
556 numOfGroup = ntohs(*((UINT16 *)(pIgmpHeader + 6)));
557 pGroup = (PUCHAR)(pIgmpHeader + 8);
558 for (i=0; i < numOfGroup; i++)
559 {
560 GroupType = (UCHAR)(*pGroup);
561 AuxDataLen = (UCHAR)(*(pGroup + 1));
562 numOfSources = ntohs(*((UINT16 *)(pGroup + 2)));
563 pGroupIpAddr = (PUCHAR)(pGroup + 4);
564 DBGPRINT(RT_DEBUG_TRACE, ("IGMPv3 Type=%d, ADL=%d, numOfSource=%d\n", GroupType, AuxDataLen, numOfSources));
565 ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
566 DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
567 GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
568
569 do
570 {
571 if((GroupType == MODE_IS_EXCLUDE) || (GroupType == CHANGE_TO_EXCLUDE_MODE) || (GroupType == ALLOW_NEW_SOURCES))
572 {
573 MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
574 break;
575 }
576
577 if((GroupType == MODE_IS_INCLUDE) || (GroupType == BLOCK_OLD_SOURCES))
578 {
579 MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
580 break;
581 }
582
583 if((GroupType == CHANGE_TO_INCLUDE_MODE))
584 {
585 if(numOfSources == 0)
586 MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
587 else
588 MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
589 break;
590 }
591 } while(FALSE);
592 pGroup += (8 + (numOfSources * 4) + AuxDataLen);
593 }
594 break;
595
596 default:
597 DBGPRINT(RT_DEBUG_TRACE, ("unknow IGMP Type=%d\n", IgmpVerType));
598 break;
599 }
600 }
601
602 return;
603}
604
605
606static BOOLEAN isIgmpMacAddr(
607 IN PUCHAR pMacAddr)
608{
609 if((pMacAddr[0] == 0x01)
610 && (pMacAddr[1] == 0x00)
611 && (pMacAddr[2] == 0x5e))
612 return TRUE;
613 return FALSE;
614}
615
616BOOLEAN isIgmpPkt(
617 IN PUCHAR pDstMacAddr,
618 IN PUCHAR pIpHeader)
619{
620 UINT16 IpProtocol = ntohs(*((UINT16 *)(pIpHeader)));
621 UCHAR IgmpProtocol;
622
623 if(!isIgmpMacAddr(pDstMacAddr))
624 return FALSE;
625
626 if(IpProtocol == ETH_P_IP)
627 {
628 IgmpProtocol = (UCHAR)*(pIpHeader + 11);
629 if(IgmpProtocol == IGMP_PROTOCOL_DESCRIPTOR)
630 return TRUE;
631 }
632
633 return FALSE;
634}
635
636static VOID InsertIgmpMember(
637 IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
638 IN PLIST_HEADER pList,
639 IN PUCHAR pMemberAddr)
640{
641 PMEMBER_ENTRY pMemberEntry;
642
643 if(pList == NULL)
644 {
645 DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
646 return;
647 }
648
649 if (pMemberAddr == NULL)
650 {
651 DBGPRINT(RT_DEBUG_ERROR, ("%s: invalid member.\n", __FUNCTION__));
652 return;
653 }
654
655 if((pMemberEntry = (PMEMBER_ENTRY)AllocaGrpMemberEntry(pMulticastFilterTable)) != NULL)
656 {
657 NdisZeroMemory(pMemberEntry, sizeof(MEMBER_ENTRY));
658 COPY_MAC_ADDR(pMemberEntry->Addr, pMemberAddr);
659 insertTailList(pList, (PLIST_ENTRY)pMemberEntry);
660
661 DBGPRINT(RT_DEBUG_TRACE, ("%s Member Mac=%02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
662 pMemberEntry->Addr[0], pMemberEntry->Addr[1], pMemberEntry->Addr[2],
663 pMemberEntry->Addr[3], pMemberEntry->Addr[4], pMemberEntry->Addr[5]));
664 }
665 return;
666}
667
668static VOID DeleteIgmpMember(
669 IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
670 IN PLIST_HEADER pList,
671 IN PUCHAR pMemberAddr)
672{
673 PMEMBER_ENTRY pCurEntry;
674
675 if((pList == NULL) || (pList->pHead == NULL))
676 {
677 DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
678 return;
679 }
680
681 if (pMemberAddr == NULL)
682 {
683 DBGPRINT(RT_DEBUG_ERROR, ("%s: invalid member.\n", __FUNCTION__));
684 return;
685 }
686
687 pCurEntry = (PMEMBER_ENTRY)pList->pHead;
688 while (pCurEntry)
689 {
690 if(MAC_ADDR_EQUAL(pMemberAddr, pCurEntry->Addr))
691 {
692 delEntryList(pList, (PLIST_ENTRY)pCurEntry);
693 FreeGrpMemberEntry(pMulticastFilterTable, pCurEntry);
694 break;
695 }
696 pCurEntry = pCurEntry->pNext;
697 }
698
699 return;
700}
701
702static VOID DeleteIgmpMemberList(
703 IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
704 IN PLIST_HEADER pList)
705{
706 PMEMBER_ENTRY pCurEntry, pPrvEntry;
707
708 if((pList == NULL) || (pList->pHead == NULL))
709 {
710 DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
711 return;
712 }
713
714 pPrvEntry = pCurEntry = (PMEMBER_ENTRY)pList->pHead;
715 while (pCurEntry)
716 {
717 delEntryList(pList, (PLIST_ENTRY)pCurEntry);
718 pPrvEntry = pCurEntry;
719 pCurEntry = pCurEntry->pNext;
720 FreeGrpMemberEntry(pMulticastFilterTable, pPrvEntry);
721 }
722
723 initList(pList);
724 return;
725}
726
727
728UCHAR IgmpMemberCnt(
729 IN PLIST_HEADER pList)
730{
731 if(pList == NULL)
732 {
733 DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
734 return 0;
735 }
736
737 return getListSize(pList);
738}
739
740VOID IgmpGroupDelMembers(
741 IN PRTMP_ADAPTER pAd,
742 IN PUCHAR pMemberAddr,
743 IN PNET_DEV pDev)
744{
745 INT i;
746 MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL;
747 PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
748
749 for (i = 0; i < MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++)
750 {
751
752 pEntry = &pMulticastFilterTable->Content[i];
753 if (pEntry->Valid == TRUE)
754 {
755 if(pMemberAddr != NULL)
756 {
757 RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
758 DeleteIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
759 RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
760 }
761
762 if((pEntry->type == MCAT_FILTER_DYNAMIC)
763 && (IgmpMemberCnt(&pEntry->MemberList) == 0))
764 MulticastFilterTableDeleteEntry(pAd, pEntry->Addr, pMemberAddr, pDev);
765 }
766 }
767}
768
769INT Set_IgmpSn_Enable_Proc(
770 IN PRTMP_ADAPTER pAd,
771 IN PSTRING arg)
772{
773 UINT Enable;
774 POS_COOKIE pObj;
775 UCHAR ifIndex;
776 PNET_DEV pDev;
777
778 pObj = (POS_COOKIE) pAd->OS_Cookie;
779 ifIndex = pObj->ioctl_if;
780
781 pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].MSSIDDev);
782 Enable = (UINT) simple_strtol(arg, 0, 10);
783
784 pAd->ApCfg.MBSSID[ifIndex].IgmpSnoopEnable = (BOOLEAN)(Enable == 0 ? 0 : 1);
785 DBGPRINT(RT_DEBUG_TRACE, ("%s::(%s) %s\n", __FUNCTION__, RTMP_OS_NETDEV_GET_DEVNAME(pDev), Enable == TRUE ? "Enable IGMP Snooping":"Disable IGMP Snooping"));
786
787 return TRUE;
788}
789
790INT Set_IgmpSn_AddEntry_Proc(
791 IN PRTMP_ADAPTER pAd,
792 IN PSTRING arg)
793{
794 INT i;
795 BOOLEAN bGroupId = 1;
796 PSTRING value;
797 PSTRING thisChar;
798 UCHAR IpAddr[4];
799 UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
800 UCHAR GroupId[ETH_LENGTH_OF_ADDRESS];
801 PUCHAR *pAddr = (PUCHAR *)&Addr;
802 PNET_DEV pDev;
803 POS_COOKIE pObj;
804 UCHAR ifIndex;
805
806 pObj = (POS_COOKIE) pAd->OS_Cookie;
807 ifIndex = pObj->ioctl_if;
808
809 pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].MSSIDDev);
810
811 while ((thisChar = strsep((char **)&arg, "-")) != NULL)
812 {
813
814 if((bGroupId == 0) && (strlen(thisChar) != 17))
815 continue;
816
817 if(strlen(thisChar) == 17)
818 {
819 for (i=0, value = rstrtok(thisChar,":"); value; value = rstrtok(NULL,":"))
820 {
821 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
822 return FALSE;
823
824 AtoH(value, &Addr[i++], 1);
825 }
826
827 if(i != 6)
828 return FALSE;
829 }
830 else
831 {
832 for (i=0, value = rstrtok(thisChar,"."); value; value = rstrtok(NULL,"."))
833 {
834 if((strlen(value) > 0) && (strlen(value) <= 3))
835 {
836 int ii;
837 for(ii=0; ii<strlen(value); ii++)
838 if (!isxdigit(*(value + ii)))
839 return FALSE;
840 }
841 else
842 return FALSE;
843
844 IpAddr[i] = (UCHAR)simple_strtol(value, NULL, 10);
845 i++;
846 }
847
848 if(i != 4)
849 return FALSE;
850
851 ConvertMulticastIP2MAC(IpAddr, (PUCHAR *)&pAddr, ETH_P_IP);
852 }
853
854 if(bGroupId == 1)
855 COPY_MAC_ADDR(GroupId, Addr);
856
857
858 if((bGroupId == 1) && IS_MULTICAST_MAC_ADDR(Addr))
859 MulticastFilterTableInsertEntry(pAd, GroupId, NULL, pDev, MCAT_FILTER_STATIC);
860
861 else if ((bGroupId == 0) && !IS_MULTICAST_MAC_ADDR(Addr))
862 MulticastFilterTableInsertEntry(pAd, GroupId, Addr, pDev, MCAT_FILTER_STATIC);
863 else
864 {
865 DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X) is not a acceptable address.\n",
866 __FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5]));
867 return FALSE;
868 }
869
870 bGroupId = 0;
871 DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X)\n",
872 __FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5]));
873
874 }
875
876 return TRUE;
877}
878
879INT Set_IgmpSn_DelEntry_Proc(
880 IN PRTMP_ADAPTER pAd,
881 IN PSTRING arg)
882{
883 INT i, memberCnt = 0;
884 BOOLEAN bGroupId = 1;
885 PSTRING value;
886 PSTRING thisChar;
887 UCHAR IpAddr[4];
888 UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
889 UCHAR GroupId[ETH_LENGTH_OF_ADDRESS];
890 PUCHAR *pAddr = (PUCHAR *)&Addr;
891 PNET_DEV pDev;
892 POS_COOKIE pObj;
893 UCHAR ifIndex;
894
895 pObj = (POS_COOKIE) pAd->OS_Cookie;
896 ifIndex = pObj->ioctl_if;
897
898 pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].MSSIDDev);
899
900 while ((thisChar = strsep((char **)&arg, "-")) != NULL)
901 {
902
903 if((bGroupId == 0) && (strlen(thisChar) != 17))
904 continue;
905
906 if(strlen(thisChar) == 17)
907 {
908 for (i=0, value = rstrtok(thisChar,":"); value; value = rstrtok(NULL,":"))
909 {
910 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
911 return FALSE;
912
913 AtoH(value, &Addr[i++], 1);
914 }
915
916 if(i != 6)
917 return FALSE;
918 }
919 else
920 {
921 for (i=0, value = rstrtok(thisChar,"."); value; value = rstrtok(NULL,"."))
922 {
923 if((strlen(value) > 0) && (strlen(value) <= 3))
924 {
925 int ii;
926 for(ii=0; ii<strlen(value); ii++)
927 if (!isxdigit(*(value + ii)))
928 return FALSE;
929 }
930 else
931 return FALSE;
932
933 IpAddr[i] = (UCHAR)simple_strtol(value, NULL, 10);
934 i++;
935 }
936
937 if(i != 4)
938 return FALSE;
939
940 ConvertMulticastIP2MAC(IpAddr, (PUCHAR *)&pAddr, ETH_P_IP);
941 }
942
943 if(bGroupId == 1)
944 COPY_MAC_ADDR(GroupId, Addr);
945 else
946 memberCnt++;
947
948 if (memberCnt > 0 )
949 MulticastFilterTableDeleteEntry(pAd, (PUCHAR)GroupId, Addr, pDev);
950
951 bGroupId = 0;
952 }
953
954 if(memberCnt == 0)
955 MulticastFilterTableDeleteEntry(pAd, (PUCHAR)GroupId, NULL, pDev);
956
957 DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X)\n",
958 __FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5]));
959
960 return TRUE;
961}
962
963INT Set_IgmpSn_TabDisplay_Proc(
964 IN PRTMP_ADAPTER pAd,
965 IN PSTRING arg)
966{
967 IGMPTableDisplay(pAd);
968 return TRUE;
969}
970
971void rtmp_read_igmp_snoop_from_file(
972 IN PRTMP_ADAPTER pAd,
973 PSTRING tmpbuf,
974 PSTRING buffer)
975{
976 PSTRING macptr;
977 INT i=0;
978
979
980 if(RTMPGetKeyParameter("IgmpSnEnable", tmpbuf, 128, buffer, TRUE))
981 {
982 for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < pAd->ApCfg.BssidNum); macptr = rstrtok(NULL,";"), i++)
983 {
984 if ((strncmp(macptr, "0", 1) == 0))
985 pAd->ApCfg.MBSSID[i].IgmpSnoopEnable = FALSE;
986 else if ((strncmp(macptr, "1", 1) == 0))
987 pAd->ApCfg.MBSSID[i].IgmpSnoopEnable = TRUE;
988 else
989 pAd->ApCfg.MBSSID[i].IgmpSnoopEnable = FALSE;
990
991 DBGPRINT(RT_DEBUG_TRACE, ("MBSSID[%d].Enable=%d\n", i, pAd->ApCfg.MBSSID[i].IgmpSnoopEnable));
992 }
993 }
994}
995
996NDIS_STATUS IgmpPktInfoQuery(
997 IN PRTMP_ADAPTER pAd,
998 IN PUCHAR pSrcBufVA,
999 IN PNDIS_PACKET pPacket,
1000 IN UCHAR apidx,
1001 OUT BOOLEAN *pInIgmpGroup,
1002 OUT PMULTICAST_FILTER_TABLE_ENTRY *ppGroupEntry)
1003{
1004 if(IS_MULTICAST_MAC_ADDR(pSrcBufVA))
1005 {
1006 BOOLEAN IgmpMldPkt = FALSE;
1007 PUCHAR pIpHeader = pSrcBufVA + 12;
1008
1009 if(ntohs(*((UINT16 *)(pIpHeader))) == ETH_P_IPV6)
1010 IgmpMldPkt = isMldPkt(pSrcBufVA, pIpHeader, NULL, NULL);
1011 else
1012 IgmpMldPkt = isIgmpPkt(pSrcBufVA, pIpHeader);
1013
1014 if (IgmpMldPkt)
1015 {
1016 *ppGroupEntry = NULL;
1017 }
1018 else if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pSrcBufVA,
1019 pAd->ApCfg.MBSSID[apidx].MSSIDDev)) == NULL)
1020 {
1021 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1022 return NDIS_STATUS_FAILURE;
1023 }
1024 *pInIgmpGroup = TRUE;
1025 }
1026 else if (IS_BROADCAST_MAC_ADDR(pSrcBufVA))
1027 {
1028 PUCHAR pDstIpAddr = pSrcBufVA + 30;
1029 UCHAR GroupMacAddr[6];
1030 PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr;
1031
1032 ConvertMulticastIP2MAC(pDstIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
1033 if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pGroupMacAddr,
1034 pAd->ApCfg.MBSSID[apidx].MSSIDDev)) != NULL)
1035 {
1036 *pInIgmpGroup = TRUE;
1037 }
1038 }
1039 return NDIS_STATUS_SUCCESS;
1040}
1041
1042NDIS_STATUS IgmpPktClone(
1043 IN PRTMP_ADAPTER pAd,
1044 IN PNDIS_PACKET pPacket,
1045 IN UCHAR QueIdx,
1046 IN PMULTICAST_FILTER_TABLE_ENTRY pGroupEntry)
1047{
1048 PNDIS_PACKET pSkbClone = NULL;
1049 PMEMBER_ENTRY pMemberEntry = (PMEMBER_ENTRY)pGroupEntry->MemberList.pHead;
1050 MAC_TABLE_ENTRY *pMacEntry = NULL;
1051 USHORT Aid;
1052 SST Sst = SST_ASSOC;
1053 UCHAR PsMode = PWR_ACTIVE;
1054 UCHAR Rate;
1055 unsigned long IrqFlags;
1056
1057
1058 while(pMemberEntry != NULL)
1059 {
1060 pMacEntry = APSsPsInquiry(pAd, pMemberEntry->Addr, &Sst, &Aid, &PsMode, &Rate);
1061
1062 if (pMacEntry && (Sst == SST_ASSOC) && (PsMode != PWR_SAVE))
1063 {
1064 pSkbClone = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
1065 if(pSkbClone)
1066 {
1067 RTMP_SET_PACKET_WCID(pSkbClone, (UCHAR)Aid);
1068
1069
1070
1071 RTMP_SET_PACKET_SOURCE(pSkbClone, PKTSRC_NDIS);
1072 }
1073 else
1074 {
1075 pMemberEntry = pMemberEntry->pNext;
1076 continue;
1077 }
1078
1079
1080 if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE)
1081 {
1082#ifdef BLOCK_NET_IF
1083 StopNetIfQueue(pAd, QueIdx, pSkbClone);
1084#endif
1085 RELEASE_NDIS_PACKET(pAd, pSkbClone, NDIS_STATUS_FAILURE);
1086 return NDIS_STATUS_FAILURE;
1087 }
1088 else
1089 {
1090 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
1091 InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pSkbClone));
1092 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1093 }
1094 }
1095 pMemberEntry = pMemberEntry->pNext;
1096 }
1097 return NDIS_STATUS_SUCCESS;
1098}
1099
1100static inline BOOLEAN isMldMacAddr(
1101 IN PUCHAR pMacAddr)
1102{
1103 return ((pMacAddr[0] == 0x33) && (pMacAddr[1] == 0x33)) ? TRUE : FALSE;
1104}
1105
1106static inline BOOLEAN IsSupportedMldMsg(
1107 IN UINT8 MsgType)
1108{
1109 BOOLEAN result = FALSE;
1110 switch(MsgType)
1111 {
1112 case MLD_V1_LISTENER_REPORT:
1113 case MLD_V1_LISTENER_DONE:
1114 case MLD_V2_LISTERNER_REPORT:
1115 result = TRUE;
1116 break;
1117 default:
1118 result = FALSE;
1119 break;
1120 }
1121
1122 return result;
1123}
1124
1125BOOLEAN isMldPkt(
1126 IN PUCHAR pDstMacAddr,
1127 IN PUCHAR pIpHeader,
1128 OUT UINT8 *pProtoType,
1129 OUT PUCHAR *pMldHeader)
1130{
1131 BOOLEAN result = FALSE;
1132 UINT16 IpProtocol = ntohs(*((UINT16 *)(pIpHeader)));
1133
1134 if(!isMldMacAddr(pDstMacAddr))
1135 return FALSE;
1136
1137 if(IpProtocol != ETH_P_IPV6)
1138 return FALSE;
1139
1140
1141 pIpHeader += 2;
1142 do
1143 {
1144 PRT_IPV6_HDR pIpv6Hdr = (PRT_IPV6_HDR)(pIpHeader);
1145 UINT8 nextProtocol = pIpv6Hdr->nextHdr;
1146 UINT32 offset = IPV6_HDR_LEN;
1147
1148 while(nextProtocol != IPV6_NEXT_HEADER_ICMPV6)
1149 {
1150 if(IPv6ExtHdrHandle((RT_IPV6_EXT_HDR *)(pIpHeader + offset), &nextProtocol, &offset) == FALSE)
1151 break;
1152 }
1153
1154 if(nextProtocol == IPV6_NEXT_HEADER_ICMPV6)
1155 {
1156 PRT_ICMPV6_HDR pICMPv6Hdr = (PRT_ICMPV6_HDR)(pIpHeader + offset);
1157 if (IsSupportedMldMsg(pICMPv6Hdr->type) == TRUE)
1158 {
1159 if (pProtoType != NULL)
1160 *pProtoType = pICMPv6Hdr->type;
1161 if (pMldHeader != NULL)
1162 *pMldHeader = (PUCHAR)pICMPv6Hdr;
1163 result = TRUE;
1164 }
1165 }
1166 }while(FALSE);
1167
1168 return result;
1169}
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269VOID MLDSnooping(
1270 IN PRTMP_ADAPTER pAd,
1271 IN PUCHAR pDstMacAddr,
1272 IN PUCHAR pSrcMacAddr,
1273 IN PUCHAR pIpHeader,
1274 IN PNET_DEV pDev)
1275{
1276 INT i;
1277 UCHAR GroupType;
1278 UINT16 numOfGroup;
1279 PUCHAR pGroup;
1280 UCHAR AuxDataLen;
1281 UINT16 numOfSources;
1282 PUCHAR pGroupIpAddr;
1283 UCHAR GroupMacAddr[6];
1284 PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr;
1285
1286 UINT8 MldType;
1287 PUCHAR pMldHeader;
1288
1289 if(isMldPkt(pDstMacAddr, pIpHeader, &MldType, &pMldHeader) == TRUE)
1290 {
1291 DBGPRINT(RT_DEBUG_TRACE, ("MLD type=%0x\n", MldType));
1292
1293 switch(MldType)
1294 {
1295 case MLD_V1_LISTENER_REPORT:
1296
1297 pGroupIpAddr = (PUCHAR)(pMldHeader + 8);
1298 ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6);
1299 DBGPRINT(RT_DEBUG_TRACE, ("Group Id=%02x:%02x:%02x:%02x:%02x:%02x\n",
1300 GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
1301 MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
1302 break;
1303
1304 case MLD_V1_LISTENER_DONE:
1305
1306 pGroupIpAddr = (PUCHAR)(pMldHeader + 8);
1307 ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6);
1308 DBGPRINT(RT_DEBUG_TRACE, ("Group Id=%02x:%02x:%02x:%02x:%02x:%02x\n",
1309 GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
1310 MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
1311 break;
1312
1313 case MLD_V2_LISTERNER_REPORT:
1314 numOfGroup = ntohs(*((UINT16 *)(pMldHeader + 6)));
1315 pGroup = (PUCHAR)(pMldHeader + 8);
1316 for (i=0; i < numOfGroup; i++)
1317 {
1318 GroupType = (UCHAR)(*pGroup);
1319 AuxDataLen = (UCHAR)(*(pGroup + 1));
1320 numOfSources = ntohs(*((UINT16 *)(pGroup + 2)));
1321 pGroupIpAddr = (PUCHAR)(pGroup + 4);
1322 DBGPRINT(RT_DEBUG_TRACE, ("MLDv2 Type=%d, ADL=%d, numOfSource=%d\n", GroupType, AuxDataLen, numOfSources));
1323 ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6);
1324 DBGPRINT(RT_DEBUG_TRACE, ("MLD Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
1325 GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
1326
1327 do
1328 {
1329 if((GroupType == MODE_IS_EXCLUDE) || (GroupType == CHANGE_TO_EXCLUDE_MODE) || (GroupType == ALLOW_NEW_SOURCES))
1330 {
1331 MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
1332 break;
1333 }
1334
1335 if((GroupType == MODE_IS_INCLUDE) || (GroupType == BLOCK_OLD_SOURCES))
1336 {
1337 MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
1338 break;
1339 }
1340
1341 if((GroupType == CHANGE_TO_INCLUDE_MODE))
1342 {
1343 if(numOfSources == 0)
1344 MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
1345 else
1346 MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
1347 break;
1348 }
1349 } while(FALSE);
1350
1351 pGroup += (4 + IPV6_ADDR_LEN + (numOfSources * 16) + AuxDataLen);
1352 }
1353 break;
1354
1355 default:
1356 DBGPRINT(RT_DEBUG_TRACE, ("unknow MLD Type=%d\n", MldType));
1357 break;
1358 }
1359 }
1360
1361 return;
1362}
1363
1364
1365#endif
1366