We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
IGMPv3 igmpize broken
#### Brief description

the `igmpize` method is broken when used on IGMPv3 message types that don't appear in IGMP.

#### Environment

-   Scapy version: `scapy version and/or commit-hash`
    aefcfd322999637abeed183447d60112070e7a35 (master)
-   Python version: `e.g. 3.5`
    Python 3.6.10
-   Operating System: `e.g. Minix 3.4`
    Nixos Unstable (nixos-20.09pre215947.82b54d49066)

#### How to reproduce

```
from scapy.contrib.igmpv3 import *

a = Ether()
b = IP()
c = IGMPv3()/IGMPv3mr(records = [IGMPv3gr(maddr = "232.1.1.10", srcaddrs = "10.0.0.10")])
x = a/b/c
x[IGMPv3].igmpize()
```

1. construct a simple IGMPv3 packet (but not a membership query, which is shared with IGMP)
2. try to `.igmpize()`

#### Actual result

```
>>> x[IGMPv3].igmpize()
WARNING: Invalid IGMP Type detected !
False
```

#### Expected result

It would return `True`, and then I would be able to send the packet with sendp() and it would be valid.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `scapy/contrib/igmp.py`
Content:
```
1 # This file is part of Scapy
2 # Scapy is free software: you can redistribute it and/or modify
3 # it under the terms of the GNU General Public License as published by
4 # the Free Software Foundation, either version 2 of the License, or
5 # any later version.
6 #
7 # Scapy is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
11 #
12 # You should have received a copy of the GNU General Public License
13 # along with Scapy. If not, see <http://www.gnu.org/licenses/>.
14 
15 # scapy.contrib.description = Internet Group Management Protocol v1/v2 (IGMP/IGMPv2)
16 # scapy.contrib.status = loads
17 
18 from __future__ import print_function
19 from scapy.compat import chb, orb
20 from scapy.error import warning
21 from scapy.fields import ByteEnumField, ByteField, IPField, XShortField
22 from scapy.layers.inet import IP, IPOption_Router_Alert
23 from scapy.layers.l2 import Ether, getmacbyip
24 from scapy.packet import bind_layers, Packet
25 from scapy.utils import atol, checksum
26 
27 
28 def isValidMCAddr(ip):
29     """convert dotted quad string to long and check the first octet"""
30     FirstOct = atol(ip) >> 24 & 0xFF
31     return (FirstOct >= 224) and (FirstOct <= 239)
32 
33 
34 class IGMP(Packet):
35     """IGMP Message Class for v1 and v2.
36 
37     This class is derived from class Packet. You  need call "igmpize()"
38     so the packet is transformed according the RFC when sent.
39     a=Ether(src="00:01:02:03:04:05")
40     b=IP(src="1.2.3.4")
41     c=IGMP(type=0x12, gaddr="224.2.3.4")
42     x = a/b/c
43     x[IGMP].igmpize()
44     sendp(a/b/c, iface="en0")
45 
46         Parameters:
47           type    IGMP type field, 0x11, 0x12, 0x16 or 0x17
48           mrcode  Maximum Response time (zero for v1)
49           gaddr   Multicast Group Address 224.x.x.x/4
50 
51     See RFC2236, Section 2. Introduction for definitions of proper
52     IGMPv2 message format   http://www.faqs.org/rfcs/rfc2236.html
53     """
54     name = "IGMP"
55 
56     igmptypes = {0x11: "Group Membership Query",
57                  0x12: "Version 1 - Membership Report",
58                  0x16: "Version 2 - Membership Report",
59                  0x17: "Leave Group"}
60 
61     fields_desc = [ByteEnumField("type", 0x11, igmptypes),
62                    ByteField("mrcode", 20),
63                    XShortField("chksum", None),
64                    IPField("gaddr", "0.0.0.0")]
65 
66     def post_build(self, p, pay):
67         """Called implicitly before a packet is sent to compute and place IGMP checksum.
68 
69         Parameters:
70           self    The instantiation of an IGMP class
71           p       The IGMP message in hex in network byte order
72           pay     Additional payload for the IGMP message
73         """
74         p += pay
75         if self.chksum is None:
76             ck = checksum(p)
77             p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:]
78         return p
79 
80     @classmethod
81     def dispatch_hook(cls, _pkt=None, *args, **kargs):
82         if _pkt and len(_pkt) >= 4:
83             from scapy.contrib.igmpv3 import IGMPv3
84             if orb(_pkt[0]) in [0x22, 0x30, 0x31, 0x32]:
85                 return IGMPv3
86             if orb(_pkt[0]) == 0x11 and len(_pkt) >= 12:
87                 return IGMPv3
88         return IGMP
89 
90     def igmpize(self):
91         """Called to explicitly fixup the packet according to the IGMP RFC
92 
93         The rules are:
94         - General:
95         1.  the Max Response time is meaningful only in Membership Queries and should be zero
96         - IP:
97         1. Send General Group Query to 224.0.0.1 (all systems)
98         2. Send Leave Group to 224.0.0.2 (all routers)
99         3a.Otherwise send the packet to the group address
100         3b.Send reports/joins to the group address
101         4. ttl = 1 (RFC 2236, section 2)
102         5. send the packet with the router alert IP option (RFC 2236, section 2)
103         - Ether:
104         1. Recalculate destination
105 
106         Returns:
107             True    The tuple ether/ip/self passed all check and represents
108                     a proper IGMP packet.
109             False   One of more validation checks failed and no fields
110                     were adjusted.
111 
112         The function will examine the IGMP message to assure proper format.
113         Corrections will be attempted if possible. The IP header is then properly
114         adjusted to ensure correct formatting and assignment. The Ethernet header
115         is then adjusted to the proper IGMP packet format.
116         """
117         gaddr = self.gaddr if hasattr(self, "gaddr") and self.gaddr else "0.0.0.0"  # noqa: E501
118         underlayer = self.underlayer
119         if self.type not in [0x11, 0x30]:                               # General Rule 1  # noqa: E501
120             self.mrcode = 0
121         if isinstance(underlayer, IP):
122             if (self.type == 0x11):
123                 if (gaddr == "0.0.0.0"):
124                     underlayer.dst = "224.0.0.1"                        # IP rule 1  # noqa: E501
125                 elif isValidMCAddr(gaddr):
126                     underlayer.dst = gaddr                              # IP rule 3a  # noqa: E501
127                 else:
128                     warning("Invalid IGMP Group Address detected !")
129                     return False
130             elif ((self.type == 0x17) and isValidMCAddr(gaddr)):
131                 underlayer.dst = "224.0.0.2"                           # IP rule 2  # noqa: E501
132             elif ((self.type == 0x12) or (self.type == 0x16)) and (isValidMCAddr(gaddr)):  # noqa: E501
133                 underlayer.dst = gaddr                                 # IP rule 3b  # noqa: E501
134             else:
135                 warning("Invalid IGMP Type detected !")
136                 return False
137             if not any(isinstance(x, IPOption_Router_Alert) for x in underlayer.options):  # noqa: E501
138                 underlayer.options.append(IPOption_Router_Alert())
139             underlayer.ttl = 1                                         # IP rule 4
140             _root = self.firstlayer()
141             if _root.haslayer(Ether):
142                 # Force recalculate Ether dst
143                 _root[Ether].dst = getmacbyip(underlayer.dst)          # Ether rule 1  # noqa: E501
144         from scapy.contrib.igmpv3 import IGMPv3
145         if isinstance(self, IGMPv3):
146             self.encode_maxrespcode()
147         return True
148 
149     def mysummary(self):
150         """Display a summary of the IGMP object."""
151         if isinstance(self.underlayer, IP):
152             return self.underlayer.sprintf("IGMP: %IP.src% > %IP.dst% %IGMP.type% %IGMP.gaddr%")  # noqa: E501
153         else:
154             return self.sprintf("IGMP %IGMP.type% %IGMP.gaddr%")
155 
156 
157 bind_layers(IP, IGMP, frag=0,
158             proto=2,
159             ttl=1)
160
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/scapy/contrib/igmp.py b/scapy/contrib/igmp.py
--- a/scapy/contrib/igmp.py
+++ b/scapy/contrib/igmp.py
@@ -114,6 +114,7 @@
         adjusted to ensure correct formatting and assignment. The Ethernet header
         is then adjusted to the proper IGMP packet format.
         """
+        from scapy.contrib.igmpv3 import IGMPv3
         gaddr = self.gaddr if hasattr(self, "gaddr") and self.gaddr else "0.0.0.0"  # noqa: E501
         underlayer = self.underlayer
         if self.type not in [0x11, 0x30]:                               # General Rule 1  # noqa: E501
@@ -131,6 +132,8 @@
                 underlayer.dst = "224.0.0.2"                           # IP rule 2  # noqa: E501
             elif ((self.type == 0x12) or (self.type == 0x16)) and (isValidMCAddr(gaddr)):  # noqa: E501
                 underlayer.dst = gaddr                                 # IP rule 3b  # noqa: E501
+            elif (self.type in [0x11, 0x22, 0x30, 0x31, 0x32] and isinstance(self, IGMPv3)):
+                pass
             else:
                 warning("Invalid IGMP Type detected !")
                 return False
@@ -141,7 +144,6 @@
             if _root.haslayer(Ether):
                 # Force recalculate Ether dst
                 _root[Ether].dst = getmacbyip(underlayer.dst)          # Ether rule 1  # noqa: E501
-        from scapy.contrib.igmpv3 import IGMPv3
         if isinstance(self, IGMPv3):
             self.encode_maxrespcode()
         return True

{"golden_diff": "diff --git a/scapy/contrib/igmp.py b/scapy/contrib/igmp.py\n--- a/scapy/contrib/igmp.py\n+++ b/scapy/contrib/igmp.py\n@@ -114,6 +114,7 @@\n         adjusted to ensure correct formatting and assignment. The Ethernet header\n         is then adjusted to the proper IGMP packet format.\n         \"\"\"\n+        from scapy.contrib.igmpv3 import IGMPv3\n         gaddr = self.gaddr if hasattr(self, \"gaddr\") and self.gaddr else \"0.0.0.0\"  # noqa: E501\n         underlayer = self.underlayer\n         if self.type not in [0x11, 0x30]:                               # General Rule 1  # noqa: E501\n@@ -131,6 +132,8 @@\n                 underlayer.dst = \"224.0.0.2\"                           # IP rule 2  # noqa: E501\n             elif ((self.type == 0x12) or (self.type == 0x16)) and (isValidMCAddr(gaddr)):  # noqa: E501\n                 underlayer.dst = gaddr                                 # IP rule 3b  # noqa: E501\n+            elif (self.type in [0x11, 0x22, 0x30, 0x31, 0x32] and isinstance(self, IGMPv3)):\n+                pass\n             else:\n                 warning(\"Invalid IGMP Type detected !\")\n                 return False\n@@ -141,7 +144,6 @@\n             if _root.haslayer(Ether):\n                 # Force recalculate Ether dst\n                 _root[Ether].dst = getmacbyip(underlayer.dst)          # Ether rule 1  # noqa: E501\n-        from scapy.contrib.igmpv3 import IGMPv3\n         if isinstance(self, IGMPv3):\n             self.encode_maxrespcode()\n         return True\n", "issue": "IGMPv3 igmpize broken\n#### Brief description\r\n\r\nthe `igmpize` method is broken when used on IGMPv3 message types that don't appear in IGMP.\r\n\r\n#### Environment\r\n\r\n-   Scapy version: `scapy version and/or commit-hash`\r\n    aefcfd322999637abeed183447d60112070e7a35 (master)\r\n-   Python version: `e.g. 3.5`\r\n    Python 3.6.10\r\n-   Operating System: `e.g. Minix 3.4`\r\n    Nixos Unstable (nixos-20.09pre215947.82b54d49066)\r\n\r\n#### How to reproduce\r\n\r\n```\r\nfrom scapy.contrib.igmpv3 import *\r\n\r\na = Ether()\r\nb = IP()\r\nc = IGMPv3()/IGMPv3mr(records = [IGMPv3gr(maddr = \"232.1.1.10\", srcaddrs = \"10.0.0.10\")])\r\nx = a/b/c\r\nx[IGMPv3].igmpize()\r\n```\r\n\r\n1. construct a simple IGMPv3 packet (but not a membership query, which is shared with IGMP)\r\n2. try to `.igmpize()`\r\n\r\n#### Actual result\r\n\r\n```\r\n>>> x[IGMPv3].igmpize()\r\nWARNING: Invalid IGMP Type detected !\r\nFalse\r\n```\r\n\r\n#### Expected result\r\n\r\nIt would return `True`, and then I would be able to send the packet with sendp() and it would be valid.\r\n\n", "before_files": [{"content": "# This file is part of Scapy\n# Scapy is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 2 of the License, or\n# any later version.\n#\n# Scapy is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with Scapy. If not, see <http://www.gnu.org/licenses/>.\n\n# scapy.contrib.description = Internet Group Management Protocol v1/v2 (IGMP/IGMPv2)\n# scapy.contrib.status = loads\n\nfrom __future__ import print_function\nfrom scapy.compat import chb, orb\nfrom scapy.error import warning\nfrom scapy.fields import ByteEnumField, ByteField, IPField, XShortField\nfrom scapy.layers.inet import IP, IPOption_Router_Alert\nfrom scapy.layers.l2 import Ether, getmacbyip\nfrom scapy.packet import bind_layers, Packet\nfrom scapy.utils import atol, checksum\n\n\ndef isValidMCAddr(ip):\n    \"\"\"convert dotted quad string to long and check the first octet\"\"\"\n    FirstOct = atol(ip) >> 24 & 0xFF\n    return (FirstOct >= 224) and (FirstOct <= 239)\n\n\nclass IGMP(Packet):\n    \"\"\"IGMP Message Class for v1 and v2.\n\n    This class is derived from class Packet. You  need call \"igmpize()\"\n    so the packet is transformed according the RFC when sent.\n    a=Ether(src=\"00:01:02:03:04:05\")\n    b=IP(src=\"1.2.3.4\")\n    c=IGMP(type=0x12, gaddr=\"224.2.3.4\")\n    x = a/b/c\n    x[IGMP].igmpize()\n    sendp(a/b/c, iface=\"en0\")\n\n        Parameters:\n          type    IGMP type field, 0x11, 0x12, 0x16 or 0x17\n          mrcode  Maximum Response time (zero for v1)\n          gaddr   Multicast Group Address 224.x.x.x/4\n\n    See RFC2236, Section 2. Introduction for definitions of proper\n    IGMPv2 message format   http://www.faqs.org/rfcs/rfc2236.html\n    \"\"\"\n    name = \"IGMP\"\n\n    igmptypes = {0x11: \"Group Membership Query\",\n                 0x12: \"Version 1 - Membership Report\",\n                 0x16: \"Version 2 - Membership Report\",\n                 0x17: \"Leave Group\"}\n\n    fields_desc = [ByteEnumField(\"type\", 0x11, igmptypes),\n                   ByteField(\"mrcode\", 20),\n                   XShortField(\"chksum\", None),\n                   IPField(\"gaddr\", \"0.0.0.0\")]\n\n    def post_build(self, p, pay):\n        \"\"\"Called implicitly before a packet is sent to compute and place IGMP checksum.\n\n        Parameters:\n          self    The instantiation of an IGMP class\n          p       The IGMP message in hex in network byte order\n          pay     Additional payload for the IGMP message\n        \"\"\"\n        p += pay\n        if self.chksum is None:\n            ck = checksum(p)\n            p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:]\n        return p\n\n    @classmethod\n    def dispatch_hook(cls, _pkt=None, *args, **kargs):\n        if _pkt and len(_pkt) >= 4:\n            from scapy.contrib.igmpv3 import IGMPv3\n            if orb(_pkt[0]) in [0x22, 0x30, 0x31, 0x32]:\n                return IGMPv3\n            if orb(_pkt[0]) == 0x11 and len(_pkt) >= 12:\n                return IGMPv3\n        return IGMP\n\n    def igmpize(self):\n        \"\"\"Called to explicitly fixup the packet according to the IGMP RFC\n\n        The rules are:\n        - General:\n        1.  the Max Response time is meaningful only in Membership Queries and should be zero\n        - IP:\n        1. Send General Group Query to 224.0.0.1 (all systems)\n        2. Send Leave Group to 224.0.0.2 (all routers)\n        3a.Otherwise send the packet to the group address\n        3b.Send reports/joins to the group address\n        4. ttl = 1 (RFC 2236, section 2)\n        5. send the packet with the router alert IP option (RFC 2236, section 2)\n        - Ether:\n        1. Recalculate destination\n\n        Returns:\n            True    The tuple ether/ip/self passed all check and represents\n                    a proper IGMP packet.\n            False   One of more validation checks failed and no fields\n                    were adjusted.\n\n        The function will examine the IGMP message to assure proper format.\n        Corrections will be attempted if possible. The IP header is then properly\n        adjusted to ensure correct formatting and assignment. The Ethernet header\n        is then adjusted to the proper IGMP packet format.\n        \"\"\"\n        gaddr = self.gaddr if hasattr(self, \"gaddr\") and self.gaddr else \"0.0.0.0\"  # noqa: E501\n        underlayer = self.underlayer\n        if self.type not in [0x11, 0x30]:                               # General Rule 1  # noqa: E501\n            self.mrcode = 0\n        if isinstance(underlayer, IP):\n            if (self.type == 0x11):\n                if (gaddr == \"0.0.0.0\"):\n                    underlayer.dst = \"224.0.0.1\"                        # IP rule 1  # noqa: E501\n                elif isValidMCAddr(gaddr):\n                    underlayer.dst = gaddr                              # IP rule 3a  # noqa: E501\n                else:\n                    warning(\"Invalid IGMP Group Address detected !\")\n                    return False\n            elif ((self.type == 0x17) and isValidMCAddr(gaddr)):\n                underlayer.dst = \"224.0.0.2\"                           # IP rule 2  # noqa: E501\n            elif ((self.type == 0x12) or (self.type == 0x16)) and (isValidMCAddr(gaddr)):  # noqa: E501\n                underlayer.dst = gaddr                                 # IP rule 3b  # noqa: E501\n            else:\n                warning(\"Invalid IGMP Type detected !\")\n                return False\n            if not any(isinstance(x, IPOption_Router_Alert) for x in underlayer.options):  # noqa: E501\n                underlayer.options.append(IPOption_Router_Alert())\n            underlayer.ttl = 1                                         # IP rule 4\n            _root = self.firstlayer()\n            if _root.haslayer(Ether):\n                # Force recalculate Ether dst\n                _root[Ether].dst = getmacbyip(underlayer.dst)          # Ether rule 1  # noqa: E501\n        from scapy.contrib.igmpv3 import IGMPv3\n        if isinstance(self, IGMPv3):\n            self.encode_maxrespcode()\n        return True\n\n    def mysummary(self):\n        \"\"\"Display a summary of the IGMP object.\"\"\"\n        if isinstance(self.underlayer, IP):\n            return self.underlayer.sprintf(\"IGMP: %IP.src% > %IP.dst% %IGMP.type% %IGMP.gaddr%\")  # noqa: E501\n        else:\n            return self.sprintf(\"IGMP %IGMP.type% %IGMP.gaddr%\")\n\n\nbind_layers(IP, IGMP, frag=0,\n            proto=2,\n            ttl=1)\n", "path": "scapy/contrib/igmp.py"}], "after_files": [{"content": "# This file is part of Scapy\n# Scapy is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 2 of the License, or\n# any later version.\n#\n# Scapy is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with Scapy. If not, see <http://www.gnu.org/licenses/>.\n\n# scapy.contrib.description = Internet Group Management Protocol v1/v2 (IGMP/IGMPv2)\n# scapy.contrib.status = loads\n\nfrom __future__ import print_function\nfrom scapy.compat import chb, orb\nfrom scapy.error import warning\nfrom scapy.fields import ByteEnumField, ByteField, IPField, XShortField\nfrom scapy.layers.inet import IP, IPOption_Router_Alert\nfrom scapy.layers.l2 import Ether, getmacbyip\nfrom scapy.packet import bind_layers, Packet\nfrom scapy.utils import atol, checksum\n\n\ndef isValidMCAddr(ip):\n    \"\"\"convert dotted quad string to long and check the first octet\"\"\"\n    FirstOct = atol(ip) >> 24 & 0xFF\n    return (FirstOct >= 224) and (FirstOct <= 239)\n\n\nclass IGMP(Packet):\n    \"\"\"IGMP Message Class for v1 and v2.\n\n    This class is derived from class Packet. You  need call \"igmpize()\"\n    so the packet is transformed according the RFC when sent.\n    a=Ether(src=\"00:01:02:03:04:05\")\n    b=IP(src=\"1.2.3.4\")\n    c=IGMP(type=0x12, gaddr=\"224.2.3.4\")\n    x = a/b/c\n    x[IGMP].igmpize()\n    sendp(a/b/c, iface=\"en0\")\n\n        Parameters:\n          type    IGMP type field, 0x11, 0x12, 0x16 or 0x17\n          mrcode  Maximum Response time (zero for v1)\n          gaddr   Multicast Group Address 224.x.x.x/4\n\n    See RFC2236, Section 2. Introduction for definitions of proper\n    IGMPv2 message format   http://www.faqs.org/rfcs/rfc2236.html\n    \"\"\"\n    name = \"IGMP\"\n\n    igmptypes = {0x11: \"Group Membership Query\",\n                 0x12: \"Version 1 - Membership Report\",\n                 0x16: \"Version 2 - Membership Report\",\n                 0x17: \"Leave Group\"}\n\n    fields_desc = [ByteEnumField(\"type\", 0x11, igmptypes),\n                   ByteField(\"mrcode\", 20),\n                   XShortField(\"chksum\", None),\n                   IPField(\"gaddr\", \"0.0.0.0\")]\n\n    def post_build(self, p, pay):\n        \"\"\"Called implicitly before a packet is sent to compute and place IGMP checksum.\n\n        Parameters:\n          self    The instantiation of an IGMP class\n          p       The IGMP message in hex in network byte order\n          pay     Additional payload for the IGMP message\n        \"\"\"\n        p += pay\n        if self.chksum is None:\n            ck = checksum(p)\n            p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:]\n        return p\n\n    @classmethod\n    def dispatch_hook(cls, _pkt=None, *args, **kargs):\n        if _pkt and len(_pkt) >= 4:\n            from scapy.contrib.igmpv3 import IGMPv3\n            if orb(_pkt[0]) in [0x22, 0x30, 0x31, 0x32]:\n                return IGMPv3\n            if orb(_pkt[0]) == 0x11 and len(_pkt) >= 12:\n                return IGMPv3\n        return IGMP\n\n    def igmpize(self):\n        \"\"\"Called to explicitly fixup the packet according to the IGMP RFC\n\n        The rules are:\n        - General:\n        1.  the Max Response time is meaningful only in Membership Queries and should be zero\n        - IP:\n        1. Send General Group Query to 224.0.0.1 (all systems)\n        2. Send Leave Group to 224.0.0.2 (all routers)\n        3a.Otherwise send the packet to the group address\n        3b.Send reports/joins to the group address\n        4. ttl = 1 (RFC 2236, section 2)\n        5. send the packet with the router alert IP option (RFC 2236, section 2)\n        - Ether:\n        1. Recalculate destination\n\n        Returns:\n            True    The tuple ether/ip/self passed all check and represents\n                    a proper IGMP packet.\n            False   One of more validation checks failed and no fields\n                    were adjusted.\n\n        The function will examine the IGMP message to assure proper format.\n        Corrections will be attempted if possible. The IP header is then properly\n        adjusted to ensure correct formatting and assignment. The Ethernet header\n        is then adjusted to the proper IGMP packet format.\n        \"\"\"\n        from scapy.contrib.igmpv3 import IGMPv3\n        gaddr = self.gaddr if hasattr(self, \"gaddr\") and self.gaddr else \"0.0.0.0\"  # noqa: E501\n        underlayer = self.underlayer\n        if self.type not in [0x11, 0x30]:                               # General Rule 1  # noqa: E501\n            self.mrcode = 0\n        if isinstance(underlayer, IP):\n            if (self.type == 0x11):\n                if (gaddr == \"0.0.0.0\"):\n                    underlayer.dst = \"224.0.0.1\"                        # IP rule 1  # noqa: E501\n                elif isValidMCAddr(gaddr):\n                    underlayer.dst = gaddr                              # IP rule 3a  # noqa: E501\n                else:\n                    warning(\"Invalid IGMP Group Address detected !\")\n                    return False\n            elif ((self.type == 0x17) and isValidMCAddr(gaddr)):\n                underlayer.dst = \"224.0.0.2\"                           # IP rule 2  # noqa: E501\n            elif ((self.type == 0x12) or (self.type == 0x16)) and (isValidMCAddr(gaddr)):  # noqa: E501\n                underlayer.dst = gaddr                                 # IP rule 3b  # noqa: E501\n            elif (self.type in [0x11, 0x22, 0x30, 0x31, 0x32] and isinstance(self, IGMPv3)):\n                pass\n            else:\n                warning(\"Invalid IGMP Type detected !\")\n                return False\n            if not any(isinstance(x, IPOption_Router_Alert) for x in underlayer.options):  # noqa: E501\n                underlayer.options.append(IPOption_Router_Alert())\n            underlayer.ttl = 1                                         # IP rule 4\n            _root = self.firstlayer()\n            if _root.haslayer(Ether):\n                # Force recalculate Ether dst\n                _root[Ether].dst = getmacbyip(underlayer.dst)          # Ether rule 1  # noqa: E501\n        if isinstance(self, IGMPv3):\n            self.encode_maxrespcode()\n        return True\n\n    def mysummary(self):\n        \"\"\"Display a summary of the IGMP object.\"\"\"\n        if isinstance(self.underlayer, IP):\n            return self.underlayer.sprintf(\"IGMP: %IP.src% > %IP.dst% %IGMP.type% %IGMP.gaddr%\")  # noqa: E501\n        else:\n            return self.sprintf(\"IGMP %IGMP.type% %IGMP.gaddr%\")\n\n\nbind_layers(IP, IGMP, frag=0,\n            proto=2,\n            ttl=1)\n", "path": "scapy/contrib/igmp.py"}]}