• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# How to contribute
2
3Contributors are essential to Scapy (as they are to most open source
4projects). Here is some advice to help you help the project!
5
6## Project objectives
7
8We try to keep Scapy as powerful as possible, to support as many
9protocols and platforms as possible, to keep and make the code (and
10the commit history) as clean as possible.
11
12Since Scapy can be slow and memory consuming, we try to limit CPU and
13memory usage, particularly in parts of the code often called.
14
15## What to contribute
16
17You want to spend time working on Scapy but have no (or little)
18idea what to do? You can look for open issues
19[labeled "contributions wanted"](https://github.com/secdev/scapy/labels/contributions%20wanted), or look at the [contributions roadmap](https://github.com/secdev/scapy/issues/399)
20
21If you have any ideas of useful contributions that you cannot (or do
22not want to) do yourself, open an issue and include
23"contributions wanted" in the title.
24
25Once you have chosen a contribution, open an issue to let other people
26know you're working on it (or assign the existing issue to yourself)
27and track your progress. You might want to ask whether you're working
28in an appropriate direction, to avoid the frustration of seeing your
29contribution rejected after a lot of work.
30
31## Reporting issues
32
33### Bugs
34
35If you have installed Scapy through a package manager (from your Linux
36or BSD system, from PyPI, etc.), please get and install the current
37development code, and check that the bug still exists before
38submitting an issue.
39
40If you're not sure whether a behavior is a bug or not, submit an issue
41and ask, don't be shy!
42
43### Enhancements / feature requests
44
45If you want a feature in Scapy, but cannot implement it yourself or
46want some hints on how to do that, open an issue and include
47"enhancement" in the title.
48
49Explain if possible the API you would like to have (e.g., give examples
50of function calls, packet creations, etc.).
51
52## Submitting pull requests
53
54### Coding style & conventions
55
56-   The code should be PEP-8 compliant; you can check your code with
57    [pep8](https://pypi.python.org/pypi/pep8) and the command `tox -e flake8`
58
59-   [Pylint](http://www.pylint.org/) can help you write good Python
60    code (even if respecting Pylint rules is sometimes either too hard
61    or even undesirable; human brain needed!).
62
63-   [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html)
64    is a nice read!
65
66-   Avoid creating unnecessary `list` objects, particularly if they
67    can be huge (e.g., when possible, use `for line in fdesc` instead of
68    `for line in fdesc.readlines()`; more generally prefer generators over
69    lists).
70
71### Tests
72
73Please consider adding tests for your new features or that trigger the
74bug you are fixing. This will prevent a regression from being
75unnoticed. Do not use the variable `_`  in your tests, as it could break them.
76
77If you find yourself in a situation where your tests locally succeed  but
78fail if executed on the CI, try to enable the debugging option for the
79dissector by setting `conf.debug_dissector = 1`.
80
81### New protocols
82
83New protocols can go either in `scapy/layers` or to
84`scapy/contrib`. Protocols in `scapy/layers` should be usually found
85on common networks, while protocols in `scapy/contrib` should be
86uncommon or specific.
87
88To be precise, `scapy/layers` protocols should not be importing `scapy/contrib`
89protocols, whereas `scapy/contrib` protocols may import both `scapy/contrib` and
90`scapy/layers` protocols.
91
92The detailed requirements are explained in [Design patterns](https://scapy.readthedocs.io/en/latest/build_dissect.html#design-patterns) on Scapy's doc.
93
94### Features
95
96Protocol-related features should be implemented within the same module
97as the protocol layers(s) (e.g., `traceroute()` is implemented in
98`scapy/layers/inet.py`).
99
100Other features may be implemented in a module (`scapy/modules`) or a
101contribution (`scapy/contrib`).
102
103### Core
104
105If you contribute to Scapy's core (e.g., `scapy/base_classes.py`,
106`scapy/packet.py`, etc.), please be very careful with performances and
107memory footprint, as it is easy to write Python code that wastes
108memory or CPU cycles.
109
110As an example, `Packet().__init__()` is called each time a **layer** is
111parsed from a string (during a network capture or a PCAP file
112read). Adding inefficient code here will have a disastrous effect on
113Scapy's performances.
114
115### Logging
116
117Scapy has an internal logging system based on `logging`.
118
119In the past, Scapy was generally too verbose on packet dissection,
120leading many new users to disable all logs, which makes it harder for them
121to find real issues afterwards. You should comply with these guidelines to
122make sure logging in Scapy remains helpful.
123
124-  If you want the log message to only be displayed when using Scapy through
125   the interactive console, use `scapy.error.log_interactive`. You are free to
126   use any log level.
127-  Otherwise, always use `scapy.error.log_runtime`.
128   -  On **packet dissection**, of *packet layers*
129      you should remain **AT OR BELOW the `logging.INFO` level**, unless the
130      issue is critical or tied to security.
131      For instance: "DNS Decompression loop detected !" is allowed as WARNING,
132      but "Could not dissect packet" or "Invalid value detected" are not.
133   -  On **packet build** or **any command** or function that is called by the
134      user or the root program, you are **free and welcomed** to use the WARNING
135      or ERROR levels, to signal that a packet was wrongly built for instance.
136-  If you are working on Scapy's core, you may use: `scapy.error.log_loading`
137   only while Scapy is loading, to display import errors for instance.
138
139
140### Python 2 and 3 compatibility
141
142The project aims to provide code that works both on Python 2 and Python 3. Therefore, some rules need to be applied to achieve compatibility:
143
144-   byte-string must be defined as `b"\x00\x01\x02"`
145-   exceptions must comply with the new Python 3 format: `except SomeError as e:`
146-   lambdas must be written using a single argument when using tuples: use `lambda x, y: x + f(y)` instead of `lambda (x, y): x + f(y)`.
147-   use int instead of long
148-   use list comprehension instead of map() and filter()
149-   `__bool__ = __nonzero__` must be used when declaring `__nonzero__` methods
150-   `__next__ = next` must be used when declaring `next` methods in iterators
151-   `StopIteration` must NOT be used in generators (but it can still be used in iterators)
152-   `io.BytesIO` must be used instead of `StringIO` when using bytes
153-   `__cmp__` must not be used.
154
155### Code review
156
157Maintainers tend to be picky, and you might feel frustrated that your
158code (which is perfectly working in your use case) is not merged
159faster.
160
161Please don't be offended, and keep in mind that maintainers are
162concerned about code maintainability and readability, commit history
163(we use the history a lot, for example to find regressions or
164understand why certain decisions have been made), performances,
165integration in Scapy, API consistency (so that someone who knows how
166to use Scapy will know how to use your code), etc.
167
168**Thanks for reading, happy hacking!**
169