15UINT32 mRouteAlertOption = 0x00000494;
38 IgmpCtrl = &IpSb->IgmpCtrl;
46 return EFI_OUT_OF_RESOURCES;
51 Group->Address = IP4_ALLSYSTEM_ADDRESS;
54 Group->ReportByUs =
FALSE;
58 if (EFI_ERROR (Status)) {
62 Status = Mnp->Groups (Mnp,
TRUE, &Group->Mac);
64 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
97 NET_LIST_FOR_EACH (Entry, &IgmpCtrl->Groups) {
98 Group = NET_LIST_USER_STRUCT (Entry,
IGMP_GROUP, Link);
100 if (Group->Address == Address) {
132 NET_LIST_FOR_EACH (Entry, &IgmpCtrl->Groups) {
133 Group = NET_LIST_USER_STRUCT (Entry,
IGMP_GROUP, Link);
175 if (Packet ==
NULL) {
176 return EFI_OUT_OF_RESOURCES;
186 return EFI_OUT_OF_RESOURCES;
190 Igmp->MaxRespTime = 0;
192 Igmp->Group = HTONL (Group);
196 Head.Protocol = IP4_PROTO_IGMP;
200 Head.Src = IP4_ALLZERO_ADDRESS;
207 (UINT8 *)&mRouteAlertOption,
234 if (IpSb->IgmpCtrl.Igmpv1QuerySeen != 0) {
264 IpSb = IpInstance->Service;
265 IgmpCtrl = &IpSb->IgmpCtrl;
286 return EFI_OUT_OF_RESOURCES;
289 Group->Address = Address;
291 Group->DelayTime = IGMP_UNSOLICIATED_REPORT;
292 Group->ReportByUs =
TRUE;
296 if (EFI_ERROR (Status)) {
302 if (EFI_ERROR (Status)) {
306 Status = Mnp->Groups (Mnp,
TRUE, &Group->Mac);
308 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
344 IpSb = IpInstance->Service;
345 IgmpCtrl = &IpSb->IgmpCtrl;
351 return EFI_NOT_FOUND;
358 if (--Group->RefCnt > 0) {
367 if (
Ip4FindMac (IgmpCtrl, &Group->Mac) == 1) {
368 Status = Mnp->Groups (Mnp,
FALSE, &Group->Mac);
370 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
379 if (Group->ReportByUs && (IgmpCtrl->Igmpv1QuerySeen == 0)) {
413 IgmpCtrl = &IpSb->IgmpCtrl;
420 if ((Packet->TotalSize < sizeof (Igmp)) || (
NetbufChecksum (Packet) != 0)) {
422 return EFI_INVALID_PARAMETER;
431 case IGMP_MEMBERSHIP_QUERY:
436 if (Igmp.MaxRespTime == 0) {
437 IgmpCtrl->Igmpv1QuerySeen = IGMP_V1ROUTER_PRESENT;
438 Igmp.MaxRespTime = 100;
445 Igmp.MaxRespTime /= 10;
446 Address = NTOHL (Igmp.Group);
448 if (Address == IP4_ALLSYSTEM_ADDRESS) {
452 NET_LIST_FOR_EACH (Entry, &IgmpCtrl->Groups) {
453 Group = NET_LIST_USER_STRUCT (Entry,
IGMP_GROUP, Link);
459 if ((Address == IP4_ALLZERO_ADDRESS) || (Address == Group->Address)) {
464 if ((Group->DelayTime == 0) || (Group->DelayTime > Igmp.MaxRespTime)) {
465 Group->DelayTime =
MAX (1, Igmp.MaxRespTime);
472 case IGMP_V1_MEMBERSHIP_REPORT:
473 case IGMP_V2_MEMBERSHIP_REPORT:
474 Address = NTOHL (Igmp.Group);
477 if ((Group !=
NULL) && (Group->DelayTime > 0)) {
478 Group->DelayTime = 0;
479 Group->ReportByUs =
FALSE;
509 IgmpCtrl = &IpSb->IgmpCtrl;
511 if (IgmpCtrl->Igmpv1QuerySeen > 0) {
512 IgmpCtrl->Igmpv1QuerySeen--;
518 NET_LIST_FOR_EACH (Entry, &IgmpCtrl->Groups) {
519 Group = NET_LIST_USER_STRUCT (Entry,
IGMP_GROUP, Link);
520 ASSERT (Group->DelayTime >= 0);
522 if (Group->DelayTime > 0) {
525 if (Group->DelayTime == 0) {
527 Group->ReportByUs =
TRUE;
557 Groups =
AllocatePool (
sizeof (IP4_ADDR) * (Count + 1));
559 if (Groups ==
NULL) {
563 CopyMem (Groups, Source, Count *
sizeof (IP4_ADDR));
564 Groups[Count] = Addr;
585 IN OUT IP4_ADDR *Groups,
592 for (Index = 0; Index < Count; Index++) {
593 if (Groups[Index] == Addr) {
598 while (Index < Count - 1) {
599 Groups[Index] = Groups[Index + 1];
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS Ip4GetMulticastMac(IN EFI_MANAGED_NETWORK_PROTOCOL *Mnp, IN IP4_ADDR Multicast, OUT EFI_MAC_ADDRESS *Mac)
IGMP_GROUP * Ip4FindGroup(IN IGMP_SERVICE_DATA *IgmpCtrl, IN IP4_ADDR Address)
EFI_STATUS Ip4IgmpHandle(IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, IN NET_BUF *Packet)
EFI_STATUS Ip4JoinGroup(IN IP4_PROTOCOL *IpInstance, IN IP4_ADDR Address)
VOID Ip4IgmpTicking(IN IP4_SERVICE *IpSb)
EFI_STATUS Ip4InitIgmp(IN OUT IP4_SERVICE *IpSb)
EFI_STATUS Ip4LeaveGroup(IN IP4_PROTOCOL *IpInstance, IN IP4_ADDR Address)
INTN Ip4RemoveGroupAddr(IN OUT IP4_ADDR *Groups, IN UINT32 Count, IN IP4_ADDR Addr)
EFI_STATUS Ip4SendIgmpMessage(IN IP4_SERVICE *IpSb, IN IP4_ADDR Dst, IN UINT8 Type, IN IP4_ADDR Group)
INTN Ip4FindMac(IN IGMP_SERVICE_DATA *IgmpCtrl, IN EFI_MAC_ADDRESS *Mac)
EFI_STATUS Ip4SendIgmpReport(IN IP4_SERVICE *IpSb, IN IP4_ADDR Group)
IP4_ADDR * Ip4CombineGroups(IN IP4_ADDR *Source, IN UINT32 Count, IN IP4_ADDR Addr)
VOID Ip4SysPacketSent(IP4_PROTOCOL *Ip4Instance, NET_BUF *Packet, EFI_STATUS IoStatus, UINT32 LinkFlag, VOID *Context)
EFI_STATUS Ip4Output(IN IP4_SERVICE *IpSb, IN IP4_PROTOCOL *IpInstance OPTIONAL, IN NET_BUF *Packet, IN IP4_HEAD *Head, IN UINT8 *Option, IN UINT32 OptLen, IN IP4_ADDR GateWay, IN IP4_FRAME_CALLBACK Callback, IN VOID *Context)
VOID EFIAPI NetbufFree(IN NET_BUF *Nbuf)
VOID EFIAPI NetbufReserve(IN OUT NET_BUF *Nbuf, IN UINT32 Len)
UINT16 EFIAPI NetbufChecksum(IN NET_BUF *Nbuf)
UINT16 EFIAPI NetblockChecksum(IN UINT8 *Bulk, IN UINT32 Len)
UINT32 EFIAPI NetbufCopy(IN NET_BUF *Nbuf, IN UINT32 Offset, IN UINT32 Len, IN UINT8 *Dest)
NET_BUF *EFIAPI NetbufAlloc(IN UINT32 Len)
UINT8 *EFIAPI NetbufAllocSpace(IN OUT NET_BUF *Nbuf, IN UINT32 Len, IN BOOLEAN FromHead)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)