Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter out non parseable lorawan packets #437

Merged
merged 7 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 39 additions & 20 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,50 +16,69 @@ members = ["lorawan"]

[workspace.dependencies]
byteorder = "1"
serde = {version = "1", features = ["rc", "derive"]}
rust_decimal = {version = "1", features = ["serde-with-float"]}
helium-proto = { git = "https://github.com/helium/proto", branch="master", features=["services"]}
serde = { version = "1", features = ["rc", "derive"] }
rust_decimal = { version = "1", features = ["serde-with-float"] }
helium-proto = { git = "https://github.com/helium/proto", branch = "master", features = [
"services",
] }
rand = "0.8"
base64 = ">=0.21"
sha2 = "0"
thiserror = "1.0"
prost = "0"

[dependencies]
clap = {version = "4", default-features=false, features = ["derive", "help", "std", "error-context"]}
clap = { version = "4", default-features = false, features = [
"derive",
"help",
"std",
"error-context",
] }
semver = "0"
config = {version="0", default-features=false, features=["toml"]}
serde = {workspace = true}
config = { version = "0", default-features = false, features = ["toml"] }
serde = { workspace = true }
serde_json = "1"
serde_urlencoded = "*"
http-serde = "1"
tokio = { version="1", default-features=false, features=["macros", "signal", "rt", "time", "sync"] }
tokio-stream = {version="0", default-features=false }
tokio = { version = "1", default-features = false, features = [
"macros",
"signal",
"rt",
"time",
"sync",
] }
tokio-stream = { version = "0", default-features = false }
futures = "*"
triggered = "0.1"
tracing = "0"
tracing-subscriber = {version = "0", default-features = false, features = ["smallvec", "fmt", "std"]}
tracing-subscriber = { version = "0", default-features = false, features = [
"smallvec",
"fmt",
"std",
] }
tracing-appender = "0"
thiserror = {workspace = true}
rand = {workspace = true}
prost = {workspace = true}
thiserror = { workspace = true }
rand = { workspace = true }
prost = { workspace = true }
tonic = "0"
http = "*"
sha2 = {workspace = true}
base64 = {workspace = true}
helium-proto = {workspace = true}
sha2 = { workspace = true }
base64 = { workspace = true }
helium-proto = { workspace = true }
signature = "2"
async-trait = "0"
angry-purple-tiger = "0"
lorawan = { package = "lorawan", path = "lorawan" }
beacon = { git = "https://github.com/helium/proto", branch="master" }
exponential-backoff = {git = "https://github.com/yoshuawuyts/exponential-backoff", branch = "master"}
semtech-udp = { version = ">=0.10.7", default-features=false, features=["server"] }
beacon = { git = "https://github.com/helium/proto", branch = "master" }
exponential-backoff = { git = "https://github.com/yoshuawuyts/exponential-backoff", branch = "master" }
semtech-udp = { version = ">=0.10.9", default-features = false, features = [
"server",
] }
helium-crypto = "0.6"

[features]
default = [ "ecc608" ]
ecc608 = [ "helium-crypto/ecc608" ]
default = ["ecc608"]
ecc608 = ["helium-crypto/ecc608"]
tpm = ["helium-crypto/tpm"]

[profile.release]
Expand Down
2 changes: 2 additions & 0 deletions lorawan/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{error::Error, fmt, io};
#[derive(Debug)]
pub enum LoraWanError {
InvalidPacketType(u8),
InvalidPacketVersion(u8),
InvalidFPortForFopts,
InvalidPacketSize(super::MType, usize),
Io(io::Error),
Expand All @@ -12,6 +13,7 @@ impl fmt::Display for LoraWanError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
LoraWanError::InvalidPacketType(v) => write!(f, "Invalid packet type: {v:#02x}"),
LoraWanError::InvalidPacketVersion(v) => write!(f, "Invalid packet version: {v:#02x}"),
LoraWanError::InvalidFPortForFopts => write!(f, "Invalid: fport 0 with fopts"),
LoraWanError::InvalidPacketSize(mtype, s) => {
write!(f, "Invalid packet size {s} for type {mtype:?}")
Expand Down
4 changes: 4 additions & 0 deletions lorawan/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ impl PHYPayload {

pub fn read(direction: Direction, reader: &mut dyn Buf) -> Result<Self, LoraWanError> {
let mhdr = MHDR::read(reader)?;
let version = mhdr.major();
if version != 0 {
return Err(LoraWanError::InvalidPacketVersion(version));
}
let packet_type = mhdr.mtype();
let mut data = reader.copy_to_bytes(reader.remaining());

Expand Down
7 changes: 6 additions & 1 deletion src/gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,12 @@ impl Gateway {
Ok(packet) if packet.is_potential_beacon() => {
self.handle_potential_beacon(packet).await;
}
Ok(packet) => self.handle_uplink(packet, Instant::now()).await,
Ok(packet) if packet.is_uplink() => {
self.handle_uplink(packet, Instant::now()).await
}
Ok(packet) => {
info!(%packet, "ignoring non-uplink packet");
}
Err(err) => {
warn!(%err, "ignoring push_data");
}
Expand Down
22 changes: 21 additions & 1 deletion src/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,23 @@ impl PacketUp {

pub fn is_potential_beacon(&self) -> bool {
Self::parse_header(self.payload())
.map(|header| header.mtype() == lorawan::MType::Proprietary)
.map(|header| {
header.mtype() == lorawan::MType::Proprietary
&& self.payload().len() >= beacon::BEACON_PAYLOAD_SIZE
madninja marked this conversation as resolved.
Show resolved Hide resolved
})
.unwrap_or(false)
}

pub fn is_uplink(&self) -> bool {
// An uplinkable packet is a parseable lorawan uplink frame which is not
// a proprietary frame
Self::parse_frame(Direction::Uplink, self.payload())
.map(|frame| {
!matches!(
frame,
PHYPayloadFrame::Proprietary(_) | PHYPayloadFrame::JoinAccept(_),
)
})
.unwrap_or(false)
}

Expand Down Expand Up @@ -266,6 +282,10 @@ pub(crate) mod datarate {
(SpreadingFactor::SF9, Bandwidth::BW500) => ProtoRate::Sf9bw500,
(SpreadingFactor::SF8, Bandwidth::BW500) => ProtoRate::Sf8bw500,
(SpreadingFactor::SF7, Bandwidth::BW500) => ProtoRate::Sf7bw500,

(SpreadingFactor::SF6, _) | (SpreadingFactor::SF5, _) => {
return Err(DecodeError::invalid_data_rate(rate.to_string()))
}
};
Ok(rate)
}
Expand Down
Loading