1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// Copyright (c) 2021 Ravi V <ravi.vantipalli@gmail.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! # packet_rs
//!
//! packet_rs is a rust based alternative to the popular python Scapy packet library. It tries to provide a scapy like API interface to define new headers and construct packets.
//!
//! * The [`headers`] module, defines commonly used network packet headers and allows for defining new header types
//! * The [`Packet`] struct, a convenient abstraction of a network packet and container to hold a group of headers
//! * The [`parser`] module, provides a super fast packet deserializer to compose Packets from slices
//!
//! ### Terminology
//! * Packet refers to a container which represents a network packet
//! * Headers are network headers like ARP, IP, Vxlan, etc
//! * Slice is a network packet represented as a series of u8 bytes
//!
//! ### Create a header
//! A header is a network protocol header and allows to individually get/set each field in the header
//! ```
//! # extern crate packet_rs;
//! # use packet_rs::headers::{Ether};
//! #
//! let mut eth = Ether::new();
//! eth.set_dst(0xaabbccddeeff);
//! println!("{}", eth.etype());
//! ```
//!
//! ### Create a Packet
//! A packet is an ordered list of headers.
//!
//! * Push or pop headers into the packet
//! * Mutably/immutably retrieve existing headers
//! * Set a custom payload
//! ```
//! # extern crate packet_rs;
//! # use packet_rs::Packet;
//! # use packet_rs::headers::{Ether, IPv4};
//! #
//! let mut pkt = Packet::new();
//! pkt.push(Ether::new());
//! pkt.push(IPv4::new());
//! pkt.push(Packet::udp(1023, 1234, 95));
//! ```
//!
//! ### Parse a byte stream
//! Parse a byte stream to generate a [`Packet`] or a [`PacketSlice`]
//!
//! * The parser fast module is zero-copy and generates a PacketSlice. PacketSlice has the same lifetime as the byte stream.
//! * The parser slow module creates a new packet from the byte stream.
//!
//! Both of the above parsing options provide full access to all the headers and each field within the header.
//! ```
//! # extern crate packet_rs;
//! # use packet_rs::Packet;
//! # use packet_rs::parser;
//! # use packet_rs::headers::*;
//! #
//! # let mut data = Packet::new();
//! # data.push(Ether::new());
//! # data.push(IPv4::new());
//! # data.push(TCP::new());
//! # let data = data.to_vec();
//!
//! let mut pkt: Packet = parser::slow::parse(&data.as_slice());
//! let eth: &mut Ether = (&mut pkt["Ether"]).into();
//! println!("{}", eth.etype());
//! ```
//! Similar semantics apply for fast parsing except where a PacketSlice is returned.
//! * [`parser::slow::parse_ethernet`] for parsing from an Ethernet header and below and then edit it
//! * [`parser::fast::parse_ipv4`] for parsing`] from an IPv4 and below and is read-only
//!
//! ### Define a header
//!
//! Define a header which can go into a new protocol stack
//!
//! ```ignore
//! # #[macro_use]
//! # extern crate packet_rs;
//! # use packet_rs::make_header;
//! make_header!(
//! MyHeader 4
//! (
//! field_1: 0-2,
//! field_2: 3-3,
//! field_3: 4-15,
//! field_4: 16-31
//! )
//! vec![0x0, 0xa, 0x8, 0x0] // <= optional default data
//! );
//!
//! // Create the custom header
//! let hdr = MyHeader::new();
//!
//! // make_header! generates helper methods and associated functions for each field in the header
//! println!("{}", hdr.field_2()); // fetch the field_2 value
//! hdr.set_field_2(1); // set the field_2 value
//! hdr.show(); // display the MyHeader header
//! ```
//!
//! ### Python support
//!
//! packet_rs supports Rust bindings for Python. All of the pre-defined header and Packet APIs are available as Python APIs
//! Please refer to examples/pkt.py and pyo3/maturin documentation on how to use the bindings.
//!
//! ```sh
//! cargo build --features python-module
//! ```
//!
pub
use *;
use *;
use *;
/// Structure used to hold an ordered list of headers
/// Structure used to hold an ordered list of header slices