We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
TTL setting in IGMP.igmpize method
#### Brief description

IGMP.igmpize method in Scapy 2.3.3 was setting IP.ttl value to 1. Currently ttl is not modified by this function. 

I consider this a bug as in docstring one can read: 
> 4. ttl = 1 (RFC 2236, section 2)

The new behaviour has been introduced in revision 8329256dcaefb0aa7e1c9ec95e15abdd7607362a

If you agree it is actually a bug, then I can provide fix :) 

#### Environment

-   Scapy version: 2.4.2
-   Python 2.7

#### How to reproduce

**Scapy 2.4.2**

```
>>> p = Ether() / IP(ttl=64) / IGMP()
>>> p.ttl
64
>>> p[IGMP].igmpize()
True
>>> p.ttl
64
```

**Scapy 2.3.3**

```
>>> p = Ether() / IP(ttl=64) / IGMP()
>>> p.ttl
64
>>> p[IGMP].igmpize(p[IP], p[Ether])
True
>>> p.ttl
1
```


#### Actual result

```
>>> p[IGMP].igmpize()
True
>>> p.ttl
64
```

#### Expected result

```
>>> p[IGMP].igmpize()
True
>>> p.ttl
1
```

#### Related resources

Full docstring of igmpize:

```
        """Called to explicitly fixup the packet according to the IGMP RFC

        The rules are:
        General:
            1.  the Max Response time is meaningful only in Membership Queries and should be zero
        IP:
            1. Send General Group Query to 224.0.0.1 (all systems)
            2. Send Leave Group to 224.0.0.2 (all routers)
            3a.Otherwise send the packet to the group address
            3b.Send reports/joins to the group address
            4. ttl = 1 (RFC 2236, section 2)
            5. send the packet with the router alert IP option (RFC 2236, section 2)
        Ether:
            1. Recalculate destination

        Returns:
            True    The tuple ether/ip/self passed all check and represents
                    a proper IGMP packet.
            False   One of more validation checks failed and no fields
                    were adjusted.

        The function will examine the IGMP message to assure proper format.
        Corrections will be attempted if possible. The IP header is then properly
        adjusted to ensure correct formatting and assignment. The Ethernet header
        is then adjusted to the proper IGMP packet format.
        """
```

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

{"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@@ -141,6 +141,7 @@\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", "issue": "TTL setting in IGMP.igmpize method\n#### Brief description\r\n\r\nIGMP.igmpize method in Scapy 2.3.3 was setting IP.ttl value to 1. Currently ttl is not modified by this function. \r\n\r\nI consider this a bug as in docstring one can read: \r\n> 4. ttl = 1 (RFC 2236, section 2)\r\n\r\nThe new behaviour has been introduced in revision 8329256dcaefb0aa7e1c9ec95e15abdd7607362a\r\n\r\nIf you agree it is actually a bug, then I can provide fix :) \r\n\r\n#### Environment\r\n\r\n-   Scapy version: 2.4.2\r\n-   Python 2.7\r\n\r\n#### How to reproduce\r\n\r\n**Scapy 2.4.2**\r\n\r\n```\r\n>>> p = Ether() / IP(ttl=64) / IGMP()\r\n>>> p.ttl\r\n64\r\n>>> p[IGMP].igmpize()\r\nTrue\r\n>>> p.ttl\r\n64\r\n```\r\n\r\n**Scapy 2.3.3**\r\n\r\n```\r\n>>> p = Ether() / IP(ttl=64) / IGMP()\r\n>>> p.ttl\r\n64\r\n>>> p[IGMP].igmpize(p[IP], p[Ether])\r\nTrue\r\n>>> p.ttl\r\n1\r\n```\r\n\r\n\r\n#### Actual result\r\n\r\n```\r\n>>> p[IGMP].igmpize()\r\nTrue\r\n>>> p.ttl\r\n64\r\n```\r\n\r\n#### Expected result\r\n\r\n```\r\n>>> p[IGMP].igmpize()\r\nTrue\r\n>>> p.ttl\r\n1\r\n```\r\n\r\n#### Related resources\r\n\r\nFull docstring of igmpize:\r\n\r\n```\r\n        \"\"\"Called to explicitly fixup the packet according to the IGMP RFC\r\n\r\n        The rules are:\r\n        General:\r\n            1.  the Max Response time is meaningful only in Membership Queries and should be zero\r\n        IP:\r\n            1. Send General Group Query to 224.0.0.1 (all systems)\r\n            2. Send Leave Group to 224.0.0.2 (all routers)\r\n            3a.Otherwise send the packet to the group address\r\n            3b.Send reports/joins to the group address\r\n            4. ttl = 1 (RFC 2236, section 2)\r\n            5. send the packet with the router alert IP option (RFC 2236, section 2)\r\n        Ether:\r\n            1. Recalculate destination\r\n\r\n        Returns:\r\n            True    The tuple ether/ip/self passed all check and represents\r\n                    a proper IGMP packet.\r\n            False   One of more validation checks failed and no fields\r\n                    were adjusted.\r\n\r\n        The function will examine the IGMP message to assure proper format.\r\n        Corrections will be attempted if possible. The IP header is then properly\r\n        adjusted to ensure correct formatting and assignment. The Ethernet header\r\n        is then adjusted to the proper IGMP packet format.\r\n        \"\"\"\r\n```\n", "before_files": [{"content": "#! /usr/bin/env python\n\n# 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# flake8: noqa: E501\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\nThis class is derived from class Packet. You  need call \"igmpize()\"\nso the packet is transformed according the RFC when sent.\na=Ether(src=\"00:01:02:03:04:05\")\nb=IP(src=\"1.2.3.4\")\nc=IGMP(type=0x12, gaddr=\"224.2.3.4\")\nx = a/b/c\nx[IGMP].igmpize()\nsendp(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\nSee RFC2236, Section 2. Introduction for definitions of proper\nIGMPv2 message format   http://www.faqs.org/rfcs/rfc2236.html\n\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            _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": "#! /usr/bin/env python\n\n# 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# flake8: noqa: E501\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\nThis class is derived from class Packet. You  need call \"igmpize()\"\nso the packet is transformed according the RFC when sent.\na=Ether(src=\"00:01:02:03:04:05\")\nb=IP(src=\"1.2.3.4\")\nc=IGMP(type=0x12, gaddr=\"224.2.3.4\")\nx = a/b/c\nx[IGMP].igmpize()\nsendp(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\nSee RFC2236, Section 2. Introduction for definitions of proper\nIGMPv2 message format   http://www.faqs.org/rfcs/rfc2236.html\n\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"}]}