Skip to content

Commit d6f815f

Browse files
committed
Add udp::unicast() and udp::broadcast()
udp::broadcast() is not yet super useful since there's no way to set the source ethernet address if source IP address isn't set
1 parent b859967 commit d6f815f

5 files changed

Lines changed: 119 additions & 41 deletions

File tree

examples/dhcp.rsyn

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,14 @@ import ipv4;
22
import dhcp;
33
import arp;
44

5-
let client = 192.168.238.112;
6-
let server = 142.250.207.36;
7-
8-
let dhcp = ipv4::udp::flow(
9-
client/dhcp::CLIENT_PORT,
10-
server/dhcp::SERVER_PORT,
11-
);
5+
let client = 192.168.238.112/dhcp::CLIENT_PORT;
6+
let server = 142.250.207.36/dhcp::SERVER_PORT;
127

138
# There is a low-level DNS API which you can use to construct exact queries,
149
# and even malformed queries
15-
dhcp.client_dgram(
10+
ipv4::udp::broadcast(
11+
src: 0.0.0.0/dhcp::CLIENT_PORT,
12+
dst: 255.255.255.255/dhcp::SERVER_PORT,
1613
dhcp::hdr(
1714
opcode: dhcp::opcode::REQUEST,
1815
xid: 0xdeadbeef,
@@ -45,7 +42,9 @@ dhcp.client_dgram(
4542
dhcp::opt::END,
4643
);
4744

48-
dhcp.server_dgram(
45+
ipv4::udp::unicast(
46+
src: server,
47+
dst: client,
4948
dhcp::hdr(
5049
opcode: dhcp::opcode::REPLY,
5150
xid: 0xdeadbeef,

ezpkt/src/udp4.rs

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const UDP_DGRAM_OVERHEAD: usize =
1818
/// Helper for creating UDP datagrams
1919
pub struct UdpDgram {
2020
pkt: Packet,
21+
eth: Hdr<eth_hdr>,
2122
ip: Hdr<ip_hdr>,
2223
udp: Hdr<udp_hdr>,
2324
tot_len: usize,
@@ -26,31 +27,25 @@ pub struct UdpDgram {
2627

2728
impl UdpDgram {
2829
#[must_use]
29-
pub fn with_capacity(src: SocketAddrV4, dst: SocketAddrV4, payload_sz: usize) -> Self {
30+
pub fn with_capacity(payload_sz: usize) -> Self {
3031
let mut pkt = Packet::with_capacity(UDP_DGRAM_OVERHEAD + payload_sz);
3132

3233
let eth: Hdr<eth_hdr> = pkt.push_hdr();
3334
pkt.get_mut_hdr(&eth)
34-
.dst_from_ip(*dst.ip())
35-
.src_from_ip(*src.ip())
3635
.proto(0x0800);
3736

3837
let ip: Hdr<ip_hdr> = pkt.push_hdr();
3938
pkt.get_mut_hdr(&ip)
4039
.init()
41-
.protocol(17)
42-
.saddr(*src.ip())
43-
.daddr(*dst.ip());
40+
.protocol(17);
4441

4542
let udp: Hdr<udp_hdr> = pkt.push_hdr();
46-
pkt.get_mut_hdr(&udp)
47-
.sport(src.port())
48-
.dport(dst.port());
4943

5044
let tot_len = ip.len() + udp.len();
5145

5246
let ret = Self {
5347
pkt,
48+
eth,
5449
ip,
5550
udp,
5651
tot_len,
@@ -61,15 +56,38 @@ impl UdpDgram {
6156
}
6257

6358
#[must_use]
64-
pub fn new(src: SocketAddrV4, dst: SocketAddrV4) -> Self {
65-
Self::with_capacity(src, dst, 0)
59+
pub fn new() -> Self {
60+
Self::with_capacity(0)
6661
}
6762

6863
#[must_use]
69-
pub fn push(mut self, bytes: &[u8]) -> Self {
70-
self.pkt.push_bytes(bytes);
71-
self.tot_len += bytes.len();
72-
self.dgram_len += bytes.len();
64+
pub fn src(mut self, src: SocketAddrV4) -> Self {
65+
self.pkt.get_mut_hdr(&self.eth).src_from_ip(*src.ip());
66+
self.pkt.get_mut_hdr(&self.ip).saddr(*src.ip());
67+
self.pkt.get_mut_hdr(&self.udp).sport(src.port());
68+
self
69+
}
70+
71+
#[must_use]
72+
pub fn dst(mut self, dst: SocketAddrV4) -> Self {
73+
self.pkt.get_mut_hdr(&self.eth).dst_from_ip(*dst.ip());
74+
self.pkt.get_mut_hdr(&self.ip).daddr(*dst.ip());
75+
self.pkt.get_mut_hdr(&self.udp).dport(dst.port());
76+
self
77+
}
78+
79+
#[must_use]
80+
pub fn broadcast(mut self) -> Self {
81+
self.pkt.get_mut_hdr(&self.eth).broadcast();
82+
self
83+
}
84+
85+
#[must_use]
86+
pub fn push<T: AsRef<[u8]>>(mut self, bytes: T) -> Self {
87+
let buf = bytes.as_ref();
88+
self.pkt.push_bytes(buf);
89+
self.tot_len += buf.len();
90+
self.dgram_len += buf.len();
7391
self.update_tot_len().update_dgram_len()
7492
}
7593

@@ -88,8 +106,14 @@ impl UdpDgram {
88106
}
89107
}
90108

109+
impl Default for UdpDgram {
110+
fn default() -> Self {
111+
Self::new()
112+
}
113+
}
114+
91115
impl From<UdpDgram> for Packet {
92-
fn from(seg: UdpDgram) -> Self{
116+
fn from(seg: UdpDgram) -> Self {
93117
seg.pkt
94118
}
95119
}
@@ -104,11 +128,11 @@ impl UdpFlow {
104128
}
105129

106130
fn clnt(&self) -> UdpDgram {
107-
UdpDgram::new(self.cl, self.sv)
131+
UdpDgram::new().src(self.cl).dst(self.sv)
108132
}
109133

110134
fn srvr(&self) -> UdpDgram {
111-
UdpDgram::new(self.sv, self.cl)
135+
UdpDgram::new().src(self.sv).dst(self.cl)
112136
}
113137

114138
pub fn client_dgram(&mut self, bytes: &[u8]) -> Packet {

ezpkt/src/vxlan.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,10 @@ pub struct VxlanDgram {
1818
impl VxlanDgram {
1919
fn new(src: SocketAddrV4, dst: SocketAddrV4, vni: u32) -> Self {
2020
Self {
21-
outer: UdpDgram::with_capacity(
22-
src,
23-
dst,
24-
std::mem::size_of::<vxlan_hdr>(),
25-
).push(
26-
vxlan_hdr::with_vni(vni).as_bytes()
27-
),
21+
outer: UdpDgram::with_capacity(std::mem::size_of::<vxlan_hdr>())
22+
.src(src)
23+
.dst(dst)
24+
.push(vxlan_hdr::with_vni(vni).as_bytes()),
2825
}
2926
}
3027

pkt/src/eth.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ pub struct eth_hdr {
1414
pub proto: u16,
1515
}
1616

17+
pub const BROADCAST: [u8; 6] = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
18+
1719
impl eth_hdr {
1820
pub fn dst_from_ip(&mut self, addr: Ipv4Addr) -> &mut Self {
1921
let ip = addr.octets();
@@ -31,4 +33,9 @@ impl eth_hdr {
3133
self.proto = proto.to_be();
3234
self
3335
}
36+
37+
pub fn broadcast(&mut self) -> &mut Self {
38+
self.dst.octets = BROADCAST;
39+
self
40+
}
3441
}

src/stdlib/ipv4/udp.rs

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,62 @@
11
use phf::{phf_map, phf_ordered_map};
22

3+
use pkt::Packet;
4+
use ezpkt::{UdpDgram, UdpFlow};
5+
36
use crate::val::{ValType, Val};
47
use crate::str::Buf;
58
use crate::libapi::{FuncDef, ArgDecl, Class};
69
use crate::sym::Symbol;
7-
use ezpkt::UdpFlow;
810
use crate::func_def;
911

10-
const UDP_CL_DGRAM: FuncDef = func_def!(
12+
const BROADCAST: FuncDef = func_def!(
13+
"ipv4::udp::broadcast";
14+
ValType::Pkt;
15+
16+
"src" => ValType::Sock4,
17+
"dst" => ValType::Sock4,
18+
=>
19+
=>
20+
ValType::Str;
21+
22+
|mut args| {
23+
let src = args.next();
24+
let dst = args.next();
25+
let buf: Buf = args.join_extra(b"").into();
26+
let dgram: Packet = UdpDgram::with_capacity(buf.len())
27+
.src(src.into())
28+
.dst(dst.into())
29+
.broadcast()
30+
.push(buf)
31+
.into();
32+
Ok(dgram.into())
33+
}
34+
);
35+
36+
const UNICAST: FuncDef = func_def!(
37+
"ipv4::udp::unicast";
38+
ValType::Pkt;
39+
40+
"src" => ValType::Sock4,
41+
"dst" => ValType::Sock4,
42+
=>
43+
=>
44+
ValType::Str;
45+
46+
|mut args| {
47+
let src = args.next();
48+
let dst = args.next();
49+
let buf: Buf = args.join_extra(b"").into();
50+
let dgram: Packet = UdpDgram::with_capacity(buf.len())
51+
.src(src.into())
52+
.dst(dst.into())
53+
.push(buf)
54+
.into();
55+
Ok(dgram.into())
56+
}
57+
);
58+
59+
const CL_DGRAM: FuncDef = func_def!(
1160
"ipv4::udp::flow.client_dgram";
1261
ValType::Pkt;
1362

@@ -24,7 +73,7 @@ const UDP_CL_DGRAM: FuncDef = func_def!(
2473
}
2574
);
2675

27-
const UDP_SV_DGRAM: FuncDef = func_def!(
76+
const SV_DGRAM: FuncDef = func_def!(
2877
"ipv4::udp::flow.server_dgram";
2978
ValType::Pkt;
3079

@@ -44,8 +93,8 @@ const UDP_SV_DGRAM: FuncDef = func_def!(
4493
impl Class for UdpFlow {
4594
fn symbols(&self) -> phf::Map<&'static str, Symbol> {
4695
phf_map! {
47-
"client_dgram" => Symbol::Func(&UDP_CL_DGRAM),
48-
"server_dgram" => Symbol::Func(&UDP_SV_DGRAM),
96+
"client_dgram" => Symbol::Func(&CL_DGRAM),
97+
"server_dgram" => Symbol::Func(&SV_DGRAM),
4998
}
5099
}
51100

@@ -54,7 +103,7 @@ impl Class for UdpFlow {
54103
}
55104
}
56105

57-
const UDP_FLOW: FuncDef = func_def!(
106+
const FLOW: FuncDef = func_def!(
58107
"flow";
59108
ValType::Obj;
60109

@@ -72,6 +121,8 @@ const UDP_FLOW: FuncDef = func_def!(
72121
);
73122

74123
pub const UDP4: phf::Map<&'static str, Symbol> = phf_map! {
75-
"flow" => Symbol::Func(&UDP_FLOW),
124+
"flow" => Symbol::Func(&FLOW),
125+
"broadcast" => Symbol::Func(&BROADCAST),
126+
"unicast" => Symbol::Func(&UNICAST),
76127
};
77128

0 commit comments

Comments
 (0)