prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN 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
  ```
  
  --- 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/arch/common.py`
  Content:
  ```
  1 # This file is part of Scapy
  2 # See http://www.secdev.org/projects/scapy for more information
  3 # Copyright (C) Philippe Biondi <phil@secdev.org>
  4 # This program is published under a GPLv2 license
  5 
  6 """
  7 Functions common to different architectures
  8 """
  9 
  10 # Important Note: This file is not needed on Windows, and mustn't be loaded
  11 
  12 import socket
  13 import subprocess
  14 from fcntl import ioctl
  15 import os
  16 import struct
  17 import ctypes
  18 from ctypes import POINTER, Structure
  19 from ctypes import c_uint, c_uint32, c_ushort, c_ubyte
  20 from scapy.config import conf
  21 from scapy.data import MTU
  22 from scapy.error import Scapy_Exception
  23 import scapy.modules.six as six
  24 
  25 # BOOT
  26 
  27 
  28 def _check_tcpdump():
  29     with open(os.devnull, 'wb') as devnull:
  30         proc = subprocess.Popen([conf.prog.tcpdump, "--version"],
  31                                 stdout=devnull, stderr=subprocess.STDOUT)
  32     return proc.wait() == 0
  33 
  34 
  35 TCPDUMP = _check_tcpdump()
  36 
  37 # UTILS
  38 
  39 
  40 def get_if(iff, cmd):
  41     """Ease SIOCGIF* ioctl calls"""
  42 
  43     sck = socket.socket()
  44     ifreq = ioctl(sck, cmd, struct.pack("16s16x", iff.encode("utf8")))
  45     sck.close()
  46     return ifreq
  47 
  48 # BPF HANDLERS
  49 
  50 
  51 class bpf_insn(Structure):
  52     """"The BPF instruction data structure"""
  53     _fields_ = [("code", c_ushort),
  54                 ("jt", c_ubyte),
  55                 ("jf", c_ubyte),
  56                 ("k", c_uint32)]
  57 
  58 
  59 class bpf_program(Structure):
  60     """"Structure for BIOCSETF"""
  61     _fields_ = [("bf_len", c_uint),
  62                 ("bf_insns", POINTER(bpf_insn))]
  63 
  64 
  65 def _legacy_bpf_pointer(tcpdump_lines):
  66     """Get old-format BPF Pointer. Deprecated"""
  67     X86_64 = os.uname()[4] in ['x86_64', 'aarch64']
  68     size = int(tcpdump_lines[0])
  69     bpf = b""
  70     for l in tcpdump_lines[1:]:
  71         if six.PY2:
  72             int_type = long  # noqa: F821
  73         else:
  74             int_type = int
  75         bpf += struct.pack("HBBI", *map(int_type, l.split()))
  76 
  77     # Thanks to http://www.netprojects.de/scapy-with-pypy-solved/ for the pypy trick  # noqa: E501
  78     if conf.use_pypy:
  79         str_buffer = ctypes.create_string_buffer(bpf)
  80         return struct.pack('HL', size, ctypes.addressof(str_buffer))
  81     else:
  82         # XXX. Argl! We need to give the kernel a pointer on the BPF,
  83         # Python object header seems to be 20 bytes. 36 bytes for x86 64bits arch.  # noqa: E501
  84         if X86_64:
  85             return struct.pack("HL", size, id(bpf) + 36)
  86         else:
  87             return struct.pack("HI", size, id(bpf) + 20)
  88 
  89 
  90 def get_bpf_pointer(tcpdump_lines):
  91     """Create a BPF Pointer for TCPDump filter"""
  92     if conf.use_pypy:
  93         return _legacy_bpf_pointer(tcpdump_lines)
  94 
  95     # Allocate BPF instructions
  96     size = int(tcpdump_lines[0])
  97     bpf_insn_a = bpf_insn * size
  98     bip = bpf_insn_a()
  99 
  100     # Fill the BPF instruction structures with the byte code
  101     tcpdump_lines = tcpdump_lines[1:]
  102     i = 0
  103     for line in tcpdump_lines:
  104         values = [int(v) for v in line.split()]
  105         bip[i].code = c_ushort(values[0])
  106         bip[i].jt = c_ubyte(values[1])
  107         bip[i].jf = c_ubyte(values[2])
  108         bip[i].k = c_uint(values[3])
  109         i += 1
  110 
  111     # Create the BPF program
  112     return bpf_program(size, bip)
  113 
  114 
  115 def compile_filter(bpf_filter, iface=None):
  116     """Asks Tcpdump to parse the filter, then build the matching
  117     BPF bytecode using get_bpf_pointer.
  118     """
  119     if not TCPDUMP:
  120         raise Scapy_Exception("tcpdump is not available. Cannot use filter !")
  121     try:
  122         process = subprocess.Popen([
  123             conf.prog.tcpdump,
  124             "-p",
  125             "-i", (conf.iface if iface is None else iface),
  126             "-ddd",
  127             "-s", str(MTU),
  128             bpf_filter],
  129             stdout=subprocess.PIPE,
  130             stderr=subprocess.PIPE
  131         )
  132     except OSError as ex:
  133         raise Scapy_Exception("Failed to attach filter: %s" % ex)
  134     lines, err = process.communicate()
  135     ret = process.returncode
  136     if ret:
  137         raise Scapy_Exception(
  138             "Failed to attach filter: tcpdump returned: %s" % err
  139         )
  140     lines = lines.strip().split(b"\n")
  141     return get_bpf_pointer(lines)
  142
  ```
  --- 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()
  
  ```
  
golden_diff: 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
  
verification_info: {"golden_diff": "diff --git a/scapy/arch/common.py b/scapy/arch/common.py\n--- a/scapy/arch/common.py\n+++ b/scapy/arch/common.py\n@@ -26,9 +26,15 @@\n \n \n def _check_tcpdump():\n+    \"\"\"\n+    Return True if the tcpdump command can be started\n+    \"\"\"\n     with open(os.devnull, 'wb') as devnull:\n-        proc = subprocess.Popen([conf.prog.tcpdump, \"--version\"],\n-                                stdout=devnull, stderr=subprocess.STDOUT)\n+        try:\n+            proc = subprocess.Popen([conf.prog.tcpdump, \"--version\"],\n+                                    stdout=devnull, stderr=subprocess.STDOUT)\n+        except OSError:\n+            return False\n     return proc.wait() == 0\n", "issue": "Scapy crashes when tcpdump is not in $PATH\nHere is the fix:\r\n\r\n```diff\r\ngit diff scapy/arch/common.py\r\ndiff --git a/scapy/arch/common.py b/scapy/arch/common.py\r\nindex 9da19141..f103bebe 100644\r\n--- a/scapy/arch/common.py\r\n+++ b/scapy/arch/common.py\r\n@@ -27,8 +27,11 @@ import scapy.modules.six as six\r\n \r\n def _check_tcpdump():\r\n     with open(os.devnull, 'wb') as devnull:\r\n-        proc = subprocess.Popen([conf.prog.tcpdump, \"--version\"],\r\n-                                stdout=devnull, stderr=subprocess.STDOUT)\r\n+        try:\r\n+            proc = subprocess.Popen([conf.prog.tcpdump, \"--version\"],\r\n+                                    stdout=devnull, stderr=subprocess.STDOUT)\r\n+        except OSError:\r\n+            return False\r\n     return proc.wait() == 0\r\n```\n", "before_files": [{"content": "# This file is part of Scapy\n# See http://www.secdev.org/projects/scapy for more information\n# Copyright (C) Philippe Biondi <phil@secdev.org>\n# This program is published under a GPLv2 license\n\n\"\"\"\nFunctions common to different architectures\n\"\"\"\n\n# Important Note: This file is not needed on Windows, and mustn't be loaded\n\nimport socket\nimport subprocess\nfrom fcntl import ioctl\nimport os\nimport struct\nimport ctypes\nfrom ctypes import POINTER, Structure\nfrom ctypes import c_uint, c_uint32, c_ushort, c_ubyte\nfrom scapy.config import conf\nfrom scapy.data import MTU\nfrom scapy.error import Scapy_Exception\nimport scapy.modules.six as six\n\n# BOOT\n\n\ndef _check_tcpdump():\n    with open(os.devnull, 'wb') as devnull:\n        proc = subprocess.Popen([conf.prog.tcpdump, \"--version\"],\n                                stdout=devnull, stderr=subprocess.STDOUT)\n    return proc.wait() == 0\n\n\nTCPDUMP = _check_tcpdump()\n\n# UTILS\n\n\ndef get_if(iff, cmd):\n    \"\"\"Ease SIOCGIF* ioctl calls\"\"\"\n\n    sck = socket.socket()\n    ifreq = ioctl(sck, cmd, struct.pack(\"16s16x\", iff.encode(\"utf8\")))\n    sck.close()\n    return ifreq\n\n# BPF HANDLERS\n\n\nclass bpf_insn(Structure):\n    \"\"\"\"The BPF instruction data structure\"\"\"\n    _fields_ = [(\"code\", c_ushort),\n                (\"jt\", c_ubyte),\n                (\"jf\", c_ubyte),\n                (\"k\", c_uint32)]\n\n\nclass bpf_program(Structure):\n    \"\"\"\"Structure for BIOCSETF\"\"\"\n    _fields_ = [(\"bf_len\", c_uint),\n                (\"bf_insns\", POINTER(bpf_insn))]\n\n\ndef _legacy_bpf_pointer(tcpdump_lines):\n    \"\"\"Get old-format BPF Pointer. Deprecated\"\"\"\n    X86_64 = os.uname()[4] in ['x86_64', 'aarch64']\n    size = int(tcpdump_lines[0])\n    bpf = b\"\"\n    for l in tcpdump_lines[1:]:\n        if six.PY2:\n            int_type = long  # noqa: F821\n        else:\n            int_type = int\n        bpf += struct.pack(\"HBBI\", *map(int_type, l.split()))\n\n    # Thanks to http://www.netprojects.de/scapy-with-pypy-solved/ for the pypy trick  # noqa: E501\n    if conf.use_pypy:\n        str_buffer = ctypes.create_string_buffer(bpf)\n        return struct.pack('HL', size, ctypes.addressof(str_buffer))\n    else:\n        # XXX. Argl! We need to give the kernel a pointer on the BPF,\n        # Python object header seems to be 20 bytes. 36 bytes for x86 64bits arch.  # noqa: E501\n        if X86_64:\n            return struct.pack(\"HL\", size, id(bpf) + 36)\n        else:\n            return struct.pack(\"HI\", size, id(bpf) + 20)\n\n\ndef get_bpf_pointer(tcpdump_lines):\n    \"\"\"Create a BPF Pointer for TCPDump filter\"\"\"\n    if conf.use_pypy:\n        return _legacy_bpf_pointer(tcpdump_lines)\n\n    # Allocate BPF instructions\n    size = int(tcpdump_lines[0])\n    bpf_insn_a = bpf_insn * size\n    bip = bpf_insn_a()\n\n    # Fill the BPF instruction structures with the byte code\n    tcpdump_lines = tcpdump_lines[1:]\n    i = 0\n    for line in tcpdump_lines:\n        values = [int(v) for v in line.split()]\n        bip[i].code = c_ushort(values[0])\n        bip[i].jt = c_ubyte(values[1])\n        bip[i].jf = c_ubyte(values[2])\n        bip[i].k = c_uint(values[3])\n        i += 1\n\n    # Create the BPF program\n    return bpf_program(size, bip)\n\n\ndef compile_filter(bpf_filter, iface=None):\n    \"\"\"Asks Tcpdump to parse the filter, then build the matching\n    BPF bytecode using get_bpf_pointer.\n    \"\"\"\n    if not TCPDUMP:\n        raise Scapy_Exception(\"tcpdump is not available. Cannot use filter !\")\n    try:\n        process = subprocess.Popen([\n            conf.prog.tcpdump,\n            \"-p\",\n            \"-i\", (conf.iface if iface is None else iface),\n            \"-ddd\",\n            \"-s\", str(MTU),\n            bpf_filter],\n            stdout=subprocess.PIPE,\n            stderr=subprocess.PIPE\n        )\n    except OSError as ex:\n        raise Scapy_Exception(\"Failed to attach filter: %s\" % ex)\n    lines, err = process.communicate()\n    ret = process.returncode\n    if ret:\n        raise Scapy_Exception(\n            \"Failed to attach filter: tcpdump returned: %s\" % err\n        )\n    lines = lines.strip().split(b\"\\n\")\n    return get_bpf_pointer(lines)\n", "path": "scapy/arch/common.py"}], "after_files": [{"content": "# This file is part of Scapy\n# See http://www.secdev.org/projects/scapy for more information\n# Copyright (C) Philippe Biondi <phil@secdev.org>\n# This program is published under a GPLv2 license\n\n\"\"\"\nFunctions common to different architectures\n\"\"\"\n\n# Important Note: This file is not needed on Windows, and mustn't be loaded\n\nimport socket\nimport subprocess\nfrom fcntl import ioctl\nimport os\nimport struct\nimport ctypes\nfrom ctypes import POINTER, Structure\nfrom ctypes import c_uint, c_uint32, c_ushort, c_ubyte\nfrom scapy.config import conf\nfrom scapy.data import MTU\nfrom scapy.error import Scapy_Exception\nimport scapy.modules.six as six\n\n# BOOT\n\n\ndef _check_tcpdump():\n    \"\"\"\n    Return True if the tcpdump command can be started\n    \"\"\"\n    with open(os.devnull, 'wb') as devnull:\n        try:\n            proc = subprocess.Popen([conf.prog.tcpdump, \"--version\"],\n                                    stdout=devnull, stderr=subprocess.STDOUT)\n        except OSError:\n            return False\n    return proc.wait() == 0\n\n\nTCPDUMP = _check_tcpdump()\n\n# UTILS\n\n\ndef get_if(iff, cmd):\n    \"\"\"Ease SIOCGIF* ioctl calls\"\"\"\n\n    sck = socket.socket()\n    ifreq = ioctl(sck, cmd, struct.pack(\"16s16x\", iff.encode(\"utf8\")))\n    sck.close()\n    return ifreq\n\n# BPF HANDLERS\n\n\nclass bpf_insn(Structure):\n    \"\"\"\"The BPF instruction data structure\"\"\"\n    _fields_ = [(\"code\", c_ushort),\n                (\"jt\", c_ubyte),\n                (\"jf\", c_ubyte),\n                (\"k\", c_uint32)]\n\n\nclass bpf_program(Structure):\n    \"\"\"\"Structure for BIOCSETF\"\"\"\n    _fields_ = [(\"bf_len\", c_uint),\n                (\"bf_insns\", POINTER(bpf_insn))]\n\n\ndef _legacy_bpf_pointer(tcpdump_lines):\n    \"\"\"Get old-format BPF Pointer. Deprecated\"\"\"\n    X86_64 = os.uname()[4] in ['x86_64', 'aarch64']\n    size = int(tcpdump_lines[0])\n    bpf = b\"\"\n    for l in tcpdump_lines[1:]:\n        if six.PY2:\n            int_type = long  # noqa: F821\n        else:\n            int_type = int\n        bpf += struct.pack(\"HBBI\", *map(int_type, l.split()))\n\n    # Thanks to http://www.netprojects.de/scapy-with-pypy-solved/ for the pypy trick  # noqa: E501\n    if conf.use_pypy:\n        str_buffer = ctypes.create_string_buffer(bpf)\n        return struct.pack('HL', size, ctypes.addressof(str_buffer))\n    else:\n        # XXX. Argl! We need to give the kernel a pointer on the BPF,\n        # Python object header seems to be 20 bytes. 36 bytes for x86 64bits arch.  # noqa: E501\n        if X86_64:\n            return struct.pack(\"HL\", size, id(bpf) + 36)\n        else:\n            return struct.pack(\"HI\", size, id(bpf) + 20)\n\n\ndef get_bpf_pointer(tcpdump_lines):\n    \"\"\"Create a BPF Pointer for TCPDump filter\"\"\"\n    if conf.use_pypy:\n        return _legacy_bpf_pointer(tcpdump_lines)\n\n    # Allocate BPF instructions\n    size = int(tcpdump_lines[0])\n    bpf_insn_a = bpf_insn * size\n    bip = bpf_insn_a()\n\n    # Fill the BPF instruction structures with the byte code\n    tcpdump_lines = tcpdump_lines[1:]\n    i = 0\n    for line in tcpdump_lines:\n        values = [int(v) for v in line.split()]\n        bip[i].code = c_ushort(values[0])\n        bip[i].jt = c_ubyte(values[1])\n        bip[i].jf = c_ubyte(values[2])\n        bip[i].k = c_uint(values[3])\n        i += 1\n\n    # Create the BPF program\n    return bpf_program(size, bip)\n\n\ndef compile_filter(bpf_filter, iface=None):\n    \"\"\"Asks Tcpdump to parse the filter, then build the matching\n    BPF bytecode using get_bpf_pointer.\n    \"\"\"\n    if not TCPDUMP:\n        raise Scapy_Exception(\"tcpdump is not available. Cannot use filter !\")\n    try:\n        process = subprocess.Popen([\n            conf.prog.tcpdump,\n            \"-p\",\n            \"-i\", (conf.iface if iface is None else iface),\n            \"-ddd\",\n            \"-s\", str(MTU),\n            bpf_filter],\n            stdout=subprocess.PIPE,\n            stderr=subprocess.PIPE\n        )\n    except OSError as ex:\n        raise Scapy_Exception(\"Failed to attach filter: %s\" % ex)\n    lines, err = process.communicate()\n    ret = process.returncode\n    if ret:\n        raise Scapy_Exception(\n            \"Failed to attach filter: tcpdump returned: %s\" % err\n        )\n    lines = lines.strip().split(b\"\\n\")\n    return get_bpf_pointer(lines)\n", "path": "scapy/arch/common.py"}]}