internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: secdev/scapy

Issue:
scapy config using obsolete utilities
Hello,
the scapy/config.py is using (on Linux) quite obsolete tools to display PDF and PostScript.
PDF - acroread is not supported on Linux anymore since 2013 
PS - gv - ghostview was not having even minor release since 2013 with very old-style X11 user interface

What about using the xdg-open ... which will then use the system preferences to use the default application configured for that file type? This way the users can configure within their desktop environment on what applications to use.

This is the patch used in Fedora:
https://src.fedoraproject.org/rpms/scapy/blob/master/f/scapy-2.2.0-xdg-open.patch

```
# HG changeset patch
# User Lubomir Rintel <lkundrak@v3.sk>
# Date 1411237938 -7200
# Node ID 0ce553161b799e9dc91f63de73dfdb0f50360056
# Parent  ac04713bb61839a3476b72118e3d1c3ce5c81e86
Do not default to acroread and gv

They are not very likely to be present nowadays. Default to user's preferred
application instead.

diff --git a/scapy/config.py b/scapy/config.py
--- a/scapy/config.py
+++ b/scapy/config.py
@@ -56,8 +56,8 @@
 
     
 class ProgPath(ConfClass):
-    pdfreader = "acroread"
-    psreader = "gv"
+    pdfreader = "xdg-open"
+    psreader = "xdg-open"
     dot = "dot"
     display = "display"
     tcpdump = "tcpdump"
```



Discussion:
Hi, and thanks for reporting !
We're working on it in https://github.com/secdev/scapy/pull/1122

Resolving patch:
diff --git a/scapy/config.py b/scapy/config.py
--- a/scapy/config.py
+++ b/scapy/config.py
@@ -11,12 +11,13 @@
 from __future__ import print_function
 import os,time,socket,sys
 
-from scapy import VERSION
-from scapy.data import *
-from scapy import base_classes
-from scapy.themes import NoTheme, apply_ipython_style
+from scapy import VERSION, base_classes
+from scapy.consts import DARWIN
+from scapy.data import ETHER_TYPES, IP_PROTOS, TCP_SERVICES, UDP_SERVICES, \
+    MANUFDB
 from scapy.error import log_scapy
-import scapy.modules.six as six
+from scapy.modules import six
+from scapy.themes import NoTheme, apply_ipython_style
 
 ############
 ## Config ##
@@ -60,8 +61,8 @@ def __set__(self, obj, val):
 
     
 class ProgPath(ConfClass):
-    pdfreader = "acroread"
-    psreader = "gv"
+    pdfreader = "open" if DARWIN else "xdg-open"
+    psreader = "open" if DARWIN else "xdg-open"
     dot = "dot"
     display = "display"
     tcpdump = "tcpdump"
@@ -236,7 +237,7 @@ def keys(self):
         return [k for k in six.iterkeys(self.__dict__) if t0-self._timetable[k] < self.timeout]
     def values(self):
         if self.timeout is None:
-            return six.values(self)
+            return list(six.itervalues(self))
         t0=time.time()
         return [v for (k,v) in six.iteritems(self.__dict__) if t0-self._timetable[k] < self.timeout]
     def __len__(self):


Test patch:
Repository: secdev/scapy

Issue:
PacketList misses proper pickle support
#### Brief description

Pickling & unpickling PacketList causes RecursionError.

[Error initially reported](https://github.com/secdev/scapy/issues/1369) by @zlatdev (but closed cause of no response/further explanation).

#### Environment

- Scapy version: 2.4.0, 927c157b
- Python version: 3.5
- Operating System: Debian 9.3

#### How to reproduce

```
import pickle

frm = Ether(src='00:11:22:33:44:55', dst='00:11:22:33:44:55')/Raw()
pl = PacketList(res=[frm, frm])
pickled = pickle.dumps(pl)
pl = pickle.loads(pickled)
pl.show()
```

#### Actual result

```
...
RecursionError: maximum recursion depth exceeded
```

#### Expected result

Should show single frame like
```
0000 Ether / IP / TCP 127.0.0.1:ftp_data > 127.0.0.1:http S
```

*Edit: changed bug description as it turned out the issue is related to pickling (used by the SimpleQueue used by the initial error reporter)*



Discussion:
fix is on the way.

Resolving patch:
diff --git a/scapy/plist.py b/scapy/plist.py
--- a/scapy/plist.py
+++ b/scapy/plist.py
@@ -85,6 +85,27 @@ def __repr__(self):
                                s,
                                ct.punct(">"))
 
+    def __getstate__(self):
+        """
+        create a basic representation of the instance, used in conjunction with __setstate__() e.g. by pickle
+        :return: dict representing this instance
+        """
+        state = {
+            'res': self.res,
+            'stats': self.stats,
+            'listname': self.listname
+        }
+        return state
+
+    def __setstate__(self, state):
+        """
+        set instance attributes to values given by state, used in conjunction with __getstate__() e.g. by pickle
+        :param state: dict representing this instance
+        """
+        self.res = state['res']
+        self.stats = state['stats']
+        self.listname = state['listname']
+
     def __getattr__(self, attr):
         return getattr(self.res, attr)
 


Test patch:
diff --git a/test/regression.uts b/test/regression.uts
--- a/test/regression.uts
+++ b/test/regression.uts
@@ -10160,6 +10160,20 @@ if PYX:
     assert(os.path.exists(filename))
     os.unlink(filename)
 
+= __getstate__ / __setstate__ (used by pickle)
+
+import pickle
+
+frm = Ether(src='00:11:22:33:44:55', dst='00:22:33:44:55:66')/Raw()
+pl = PacketList(res=[frm, frm], name='WhatAGreatName')
+pickled = pickle.dumps(pl)
+pl = pickle.loads(pickled)
+assert(pl.listname == "WhatAGreatName")
+assert(len(pl) == 2)
+assert(pl[0][Ether].src == '00:11:22:33:44:55')
+assert(pl[1][Ether].dst == '00:22:33:44:55:66')
+
+
 ############
 ############
 + Scapy version
Repository: secdev/scapy

Issue:
man page spelling error
intances should be instances.

It would be nice if this wasn't gz compressed in the source, otherwise I'd have done a pull request.


Discussion:
Thanks for reporting the issue. I don’t think that there is a need to have that file compressed. We could remove it and apply your changes.

Great thanks. man also throws an error on Debian when compiling the man page, but I've not investigated because it's a compressed file and not easily patched in the Debian package. If it's not compressed in the next release, I'll investigate that and hopefully make a pull request.

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -63,7 +63,7 @@ def make_ezipfile(base_name, base_dir, verbose=0, dry_run=0, **kwargs):
         'scapy/tools',
     ],
     scripts=SCRIPTS,
-    data_files=[('share/man/man1', ["doc/scapy.1.gz"])],
+    data_files=[('share/man/man1', ["doc/scapy.1"])],
     package_data={
         'scapy': ['VERSION'],
     },


Test patch:
Repository: secdev/scapy

Issue:
Exception raised when ._fix() is called on fuzzed TCP flags
#### Brief description

An exception raised when ._fix() is called on fuzzed TCP flags. 

TCP is affected by this. 

#### Environment

- Scapy version: 2.4.0.dev115
- Python version: Python 3.6.5rc1
- Operating System: Kali Linux

#### How to reproduce

```
ubuntu:/$ scapy
... (welcome info omitted)
>>> p = IP()/TCP()
>>> p = fuzz(p)
>>> p["IP"].show()
###[ IP ]###
  version= <RandNum>
  ihl= None
  tos= 98
  len= None
  id= <RandShort>
  flags= DF+evil
  frag= 0
  ttl= <RandByte>
  proto= tcp
  chksum= None
  src= 127.0.0.1
  dst= 127.0.0.1
  \options\
###[ TCP ]###
     sport= <RandShort>
     dport= <RandShort>
     seq= <RandInt>
     ack= <RandInt>
     dataofs= None
     reserved= <RandNum>
     flags= SAUC
     window= <RandShort>
     chksum= None
     urgptr= <RandShort>
     options= []
# You can query flags repeatedly to see that it's indeed a random value
>>> p["TCP"].flags
<Flag 163 (FSUC)>
>>> p["TCP"].flags
<Flag 414 (SRPACN)>
# But if you try to _fix() it, like you can with other parts of the packet:
>>> p["TCP"].flags._fix()
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/scapy/fields.py", line 1497, in __getattr__
    for flag in attr)
  File "/usr/local/lib/python3.6/dist-packages/scapy/fields.py", line 1497, in <genexpr>
    for flag in attr)
ValueError: substring not found

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python3.6/dist-packages/scapy/fields.py", line 1499, in __getattr__
    return super(FlagValue, self).__getattr__(attr)
AttributeError: 'super' object has no attribute '__getattr__'
```

#### Actual result

AttributeError/ValueError is raised.

#### Expected result

The expected result is just a fixed integer or string value, representing what a random flag value is. 

Let me know if I'm just doing something stupid, or if there's any other info I can provide!


Discussion:
The problem is `p.flags` should return a volatile value instead of a value. I'll have a look.

Resolving patch:
diff --git a/scapy/fields.py b/scapy/fields.py
--- a/scapy/fields.py
+++ b/scapy/fields.py
@@ -1890,6 +1890,8 @@ def m2i(self, pkt, x):
         return self._fixup_val(super(FlagsField, self).m2i(pkt, x))
 
     def i2h(self, pkt, x):
+        if isinstance(x, VolatileValue):
+            return super(FlagsField, self).i2h(pkt, x)
         return self._fixup_val(super(FlagsField, self).i2h(pkt, x))
 
     def i2repr(self, pkt, x):


Test patch:
diff --git a/test/regression.uts b/test/regression.uts
--- a/test/regression.uts
+++ b/test/regression.uts
@@ -495,6 +495,9 @@ x.show2()
 x = IP(raw(x))
 assert NTP in x
 
+= fuzz on packets with FlagsField
+assert isinstance(fuzz(TCP()).flags, VolatileValue)
+
 = Building some packets
 ~ basic IP TCP UDP NTP LLC SNAP Dot11
 IP()/TCP()
Repository: secdev/scapy

Issue:
sniff enables PROMISC mode temporarily when sniff_promisc is False (SOLUTION INCLUDED)
OS: Linux (other UNIXes too?)
NOTE: I'm too lazy to clone it, make the mods, issue a pull request etc; the fix is quick.

The problem: calls to sniff() enter promiscuous mode very shortly even if conf.sniff_promisc is disabled, when 'filter' is given to sniff(). This is because the call to the L2 socket routines call attach_filter in arch/linux.py, which is calling os.popen() with tcpdump in order to open the tcpdump process and get some information for the rest of the function. As a result, the desired device(s) go into promiscuous mode very shortly until tcpdump exits.  This is seen simply by tail'ing the kernel log and executing the sniff(iface='whatever', filter='dst port 1000') function.

The fix: In the call to os.popen() that executes tcpdump, add the argument "-p" to the parameters if sniff_promisc is disabled. '-p' tells tcpdump to not go into PROMISC mode. NOTE: the position of the promisc setting in 'conf' might need to be changed too.

They generate the same output, except with -p promiscuous mode is never entered and has the programmer's desired intention translated over to that short tcpdump execution.


Discussion:

Resolving patch:
diff --git a/scapy/arch/bpf/core.py b/scapy/arch/bpf/core.py
--- a/scapy/arch/bpf/core.py
+++ b/scapy/arch/bpf/core.py
@@ -102,7 +102,8 @@ def attach_filter(fd, iface, bpf_filter_string):
     """Attach a BPF filter to the BPF file descriptor"""
 
     # Retrieve the BPF byte code in decimal
-    command = "%s -i %s -ddd -s 1600 '%s'" % (conf.prog.tcpdump, iface, bpf_filter_string)  # noqa: E501
+    cmd_fmt = "%s -p -i %s -ddd -s 1600 '%s'"
+    command = cmd_fmt % (conf.prog.tcpdump, iface, bpf_filter_string)
     try:
         f = os.popen(command)
     except OSError as msg:
diff --git a/scapy/arch/linux.py b/scapy/arch/linux.py
--- a/scapy/arch/linux.py
+++ b/scapy/arch/linux.py
@@ -149,7 +149,7 @@ def attach_filter(s, bpf_filter, iface):
     if not TCPDUMP:
         return
     try:
-        f = os.popen("%s -i %s -ddd -s %d '%s'" % (
+        f = os.popen("%s -p -i %s -ddd -s %d '%s'" % (
             conf.prog.tcpdump,
             conf.iface if iface is None else iface,
             MTU,


Test patch:
Repository: secdev/scapy

Issue:
Missing ICMP Types
Enhancement. Support for further ICMP Types is needed. For example ICMP Type 40 (Security Failure), 55/56 (Domain Name Request/Reply) and 30 (Traceroute) are not supported.

If no one working on it, I can implement the mentioned types.


Discussion:
You can do it. Please have a look at CONTRIBUTING.md.

Resolving patch:
diff --git a/scapy/layers/inet.py b/scapy/layers/inet.py
--- a/scapy/layers/inet.py
+++ b/scapy/layers/inet.py
@@ -697,7 +697,19 @@ def mysummary(self):
              15: "information-request",
              16: "information-response",
              17: "address-mask-request",
-             18: "address-mask-reply"}
+             18: "address-mask-reply",
+             30: "traceroute",
+             31: "datagram-conversion-error",
+             32: "mobile-host-redirect",
+             33: "ipv6-where-are-you",
+             34: "ipv6-i-am-here",
+             35: "mobile-registration-request",
+             36: "mobile-registration-reply",
+             37: "domain-name-request",
+             38: "domain-name-reply",
+             39: "skip",
+             40: "photuris"}
+
 
 icmpcodes = {3: {0: "network-unreachable",
                     1: "host-unreachable",
@@ -721,7 +733,13 @@ def mysummary(self):
              11: {0: "ttl-zero-during-transit",
                   1: "ttl-zero-during-reassembly", },
              12: {0: "ip-header-bad",
-                  1: "required-option-missing", }, }
+                  1: "required-option-missing", },
+             40: {0: "bad-spi",
+                  1: "authentication-failed",
+                  2: "decompression-failed",
+                  3: "decryption-failed",
+                  4: "need-authentification",
+                  5: "need-authorization", }, }
 
 
 class ICMP(Packet):
@@ -752,14 +770,14 @@ def post_build(self, p, pay):
         return p
 
     def hashret(self):
-        if self.type in [0, 8, 13, 14, 15, 16, 17, 18]:
+        if self.type in [0, 8, 13, 14, 15, 16, 17, 18, 33, 34, 35, 36, 37, 38]:
             return struct.pack("HH", self.id, self.seq) + self.payload.hashret()  # noqa: E501
         return self.payload.hashret()
 
     def answers(self, other):
         if not isinstance(other, ICMP):
             return 0
-        if ((other.type, self.type) in [(8, 0), (13, 14), (15, 16), (17, 18)] and  # noqa: E501
+        if ((other.type, self.type) in [(8, 0), (13, 14), (15, 16), (17, 18), (33, 34), (35, 36), (37, 38)] and  # noqa: E501
             self.id == other.id and
                 self.seq == other.seq):
             return 1


Test patch:
Repository: secdev/scapy

Issue:
Scapy crashes when tcpdump is not in $PATH
Here is the fix:

```diff
git diff scapy/arch/common.py
diff --git a/scapy/arch/common.py b/scapy/arch/common.py
index 9da19141..f103bebe 100644
--- a/scapy/arch/common.py
+++ b/scapy/arch/common.py
@@ -27,8 +27,11 @@ import scapy.modules.six as six
 
 def _check_tcpdump():
     with open(os.devnull, 'wb') as devnull:
-        proc = subprocess.Popen([conf.prog.tcpdump, "--version"],
-                                stdout=devnull, stderr=subprocess.STDOUT)
+        try:
+            proc = subprocess.Popen([conf.prog.tcpdump, "--version"],
+                                    stdout=devnull, stderr=subprocess.STDOUT)
+        except OSError:
+            return False
     return proc.wait() == 0
```


Discussion:

Resolving patch:
diff --git a/scapy/arch/common.py b/scapy/arch/common.py
--- a/scapy/arch/common.py
+++ b/scapy/arch/common.py
@@ -26,9 +26,15 @@
 
 
 def _check_tcpdump():
+    """
+    Return True if the tcpdump command can be started
+    """
     with open(os.devnull, 'wb') as devnull:
-        proc = subprocess.Popen([conf.prog.tcpdump, "--version"],
-                                stdout=devnull, stderr=subprocess.STDOUT)
+        try:
+            proc = subprocess.Popen([conf.prog.tcpdump, "--version"],
+                                    stdout=devnull, stderr=subprocess.STDOUT)
+        except OSError:
+            return False
     return proc.wait() == 0
 
 


Test patch:
diff --git a/test/linux.uts b/test/linux.uts
--- a/test/linux.uts
+++ b/test/linux.uts
@@ -344,3 +344,12 @@ if six.PY3:
         l3ps.send(IP(dst="8.8.8.8")/ICMP())
         return True
     assert test_L3PacketSocket_sendto_python3()
+
+= Test _check_tcpdump()
+
+from scapy.arch.common import _check_tcpdump
+
+saved_conf_prog_tcpdump = conf.prog.tcpdump
+conf.prog.tcpdump = "does_not_exist"
+assert _check_tcpdump() == False
+conf.prog.tcpdump = saved_conf_prog_tcpdump
Repository: secdev/scapy

Issue:
Version comparison not tolerant for development package version.
https://github.com/secdev/scapy/blob/0cd9b58d04b9c2ec7b65c9e8f73a89d095c39913/scapy/config.py#L368
It results in following error: ` ValueError: invalid literal for int() with base 10: ''` when used for package with not standardized version, such as `2.4.dev0` because splitting by "." returns last element as an empty string: `''`. One way of fixing that is by adding `version_tags = filter(None, version_tags)` before mentioned line, but I am not sure if it's right thing to do as I am not fluent in regular expressions, maybe it could be altered instead.


Discussion:
Hi, sorry for the delay. This is indeed a bug, thanks for reporting

Resolving patch:
diff --git a/scapy/config.py b/scapy/config.py
--- a/scapy/config.py
+++ b/scapy/config.py
@@ -361,7 +361,8 @@ def _version_checker(module, minver):
      - minver: a tuple of versions
     """
     # We could use LooseVersion, but distutils imports imp which is deprecated
-    version_tags = re.match(r'[a-z]?((?:\d|\.)+)', module.__version__)
+    version_regexp = r'[a-z]?((?:\d|\.)+\d+)(?:\.dev[0-9]+)?'
+    version_tags = re.match(version_regexp, module.__version__)
     if not version_tags:
         return False
     version_tags = version_tags.group(1).split(".")


Test patch:
diff --git a/test/regression.uts b/test/regression.uts
--- a/test/regression.uts
+++ b/test/regression.uts
@@ -23,6 +23,9 @@ class FakeModule(object):
 class FakeModule2(object):
     __version__ = "5.143.3.12"
 
+class FakeModule3(object):
+    __version__ = "v2.4.2.dev42"
+
 from scapy.config import _version_checker
 
 assert _version_checker(FakeModule, (1,11,5))
@@ -31,6 +34,8 @@ assert not _version_checker(FakeModule, (1,13))
 assert _version_checker(FakeModule2, (5, 1))
 assert not _version_checker(FakeModule2, (5, 143, 4))
 
+assert _version_checker(FakeModule3, (2, 4, 2))
+
 = List layers
 ~ conf command
 ls()
Repository: secdev/scapy

Issue:
Dot11Beacon network_stats bugs with Python3
Getting network statistics from Dot11Beacon packets thanks to `network_stats` with Python3 raises an error.

#### Environment

- Scapy version: 2.4.2
- Python version: 3.7.2
- Operating system : Arch Linux

#### How to reproduce

Put your wireless card in monitor mode then listen for beacon frames:

```python
from scapy.all import *
import six


def filter_beacon(p):
    """ Filter WiFi beacon and probe response packets. """
    return p.haslayer(Dot11Beacon)


def print_ap(p):
    """ Print access point. """
    netstats = p[Dot11Beacon].network_stats()

    # Get AP details
    bssid    = p.addr3
    ssid     = netstats['ssid']
    channel  = netstats['channel']
    crypto   = '/'.join(netstats['crypto'])

    # Print discovered AP
    print(ssid + " (" + bssid + ") on channel " + str(channel) + " with crypto " + crypto)


""" Refresh APs list. """
sniff(iface="mon0", lfilter=filter_beacon, prn=print_ap)
```
#### Actual result with Python2

```
Livebox-1B23 (a4:3e:51:0b:1b:23) on channel 6 with crypto WPA2/WPA
Livebox-1B23 (a4:3e:51:0b:1b:23) on channel 6 with crypto WPA2/WPA
...
```

#### Actual result with Python3

```
Traceback (most recent call last):
  File "min_script.py", line 25, in <module>
    sniff(iface="mon0", lfilter=filter_beacon, prn=print_ap)
  File "/usr/lib/python3.7/site-packages/scapy/sendrecv.py", line 886, in sniff
    r = prn(p)
  File "min_script.py", line 12, in print_ap
    netstats = p[Dot11Beacon].network_stats()
  File "/usr/lib/python3.7/site-packages/scapy/layers/dot11.py", line 430, in network_stats
    p.info.startswith('\x00P\xf2\x01\x01\x00'):
TypeError: startswith first arg must be bytes or a tuple of bytes, not str
```

#### Expected result

As in Python2



Discussion:

Resolving patch:
diff --git a/scapy/layers/dot11.py b/scapy/layers/dot11.py
--- a/scapy/layers/dot11.py
+++ b/scapy/layers/dot11.py
@@ -427,7 +427,7 @@ def network_stats(self):
                 crypto.add("WPA2")
             elif p.ID == 221:
                 if isinstance(p, Dot11EltMicrosoftWPA) or \
-                        p.info.startswith('\x00P\xf2\x01\x01\x00'):
+                        p.info.startswith(b'\x00P\xf2\x01\x01\x00'):
                     crypto.add("WPA")
             p = p.payload
         if not crypto:


Test patch:
Repository: secdev/scapy

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.
        """
```


Discussion:
Thanks for this report. This regression was introduced by 8329256dcaefb0aa7e1c9ec95e15abdd7607362a
Thanks for confirmation, I'll provide a PR.

Resolving patch:
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 @@ def igmpize(self):
                 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


Test patch: