Skip to main content

raknet_rust/protocol/
primitives.rs

1use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
2
3use bytes::{Buf, BufMut};
4
5use crate::error::{DecodeError, EncodeError};
6
7use super::codec::RaknetCodec;
8use super::constants::Magic;
9
10pub struct U24Le(pub u32);
11
12impl RaknetCodec for U24Le {
13    fn encode_raknet(&self, dst: &mut impl BufMut) -> Result<(), EncodeError> {
14        let v = self.0 & 0x00FF_FFFF;
15        dst.put_u8((v & 0xFF) as u8);
16        dst.put_u8(((v >> 8) & 0xFF) as u8);
17        dst.put_u8(((v >> 16) & 0xFF) as u8);
18        Ok(())
19    }
20
21    fn decode_raknet(src: &mut impl Buf) -> Result<Self, DecodeError> {
22        if src.remaining() < 3 {
23            return Err(DecodeError::UnexpectedEof);
24        }
25        let b0 = src.get_u8() as u32;
26        let b1 = src.get_u8() as u32;
27        let b2 = src.get_u8() as u32;
28        Ok(Self(b0 | (b1 << 8) | (b2 << 16)))
29    }
30}
31
32impl RaknetCodec for bool {
33    fn encode_raknet(&self, dst: &mut impl BufMut) -> Result<(), EncodeError> {
34        dst.put_u8(u8::from(*self));
35        Ok(())
36    }
37
38    fn decode_raknet(src: &mut impl Buf) -> Result<Self, DecodeError> {
39        if !src.has_remaining() {
40            return Err(DecodeError::UnexpectedEof);
41        }
42        Ok(src.get_u8() == 1)
43    }
44}
45
46macro_rules! impl_codec_be_int {
47    ($ty:ty, $put:ident, $get:ident, $size:expr) => {
48        impl RaknetCodec for $ty {
49            fn encode_raknet(&self, dst: &mut impl BufMut) -> Result<(), EncodeError> {
50                dst.$put(*self as _);
51                Ok(())
52            }
53
54            fn decode_raknet(src: &mut impl Buf) -> Result<Self, DecodeError> {
55                if src.remaining() < $size {
56                    return Err(DecodeError::UnexpectedEof);
57                }
58                Ok(src.$get() as $ty)
59            }
60        }
61    };
62}
63
64impl_codec_be_int!(u8, put_u8, get_u8, 1);
65impl_codec_be_int!(u16, put_u16, get_u16, 2);
66impl_codec_be_int!(u32, put_u32, get_u32, 4);
67impl_codec_be_int!(u64, put_u64, get_u64, 8);
68impl_codec_be_int!(i16, put_i16, get_i16, 2);
69impl_codec_be_int!(i32, put_i32, get_i32, 4);
70impl_codec_be_int!(i64, put_i64, get_i64, 8);
71
72impl RaknetCodec for Magic {
73    fn encode_raknet(&self, dst: &mut impl BufMut) -> Result<(), EncodeError> {
74        dst.put_slice(self);
75        Ok(())
76    }
77
78    fn decode_raknet(src: &mut impl Buf) -> Result<Self, DecodeError> {
79        if src.remaining() < 16 {
80            return Err(DecodeError::UnexpectedEof);
81        }
82        let mut magic = [0u8; 16];
83        src.copy_to_slice(&mut magic);
84        Ok(magic)
85    }
86}
87
88impl RaknetCodec for SocketAddr {
89    fn encode_raknet(&self, dst: &mut impl BufMut) -> Result<(), EncodeError> {
90        match self {
91            SocketAddr::V4(addr) => {
92                dst.put_u8(4);
93                let ip = addr.ip().octets();
94                dst.put_u8(!ip[0]);
95                dst.put_u8(!ip[1]);
96                dst.put_u8(!ip[2]);
97                dst.put_u8(!ip[3]);
98                dst.put_u16(addr.port());
99            }
100            SocketAddr::V6(addr) => {
101                dst.put_u8(6);
102                dst.put_u16_le(23);
103                dst.put_u16(addr.port());
104                dst.put_u32(addr.flowinfo());
105                dst.put_slice(&addr.ip().octets());
106                dst.put_u32(addr.scope_id());
107            }
108        }
109        Ok(())
110    }
111
112    fn decode_raknet(src: &mut impl Buf) -> Result<Self, DecodeError> {
113        if !src.has_remaining() {
114            return Err(DecodeError::UnexpectedEof);
115        }
116
117        let version = src.get_u8();
118        match version {
119            4 => {
120                if src.remaining() < 6 {
121                    return Err(DecodeError::UnexpectedEof);
122                }
123                let ip = [!src.get_u8(), !src.get_u8(), !src.get_u8(), !src.get_u8()];
124                let port = src.get_u16();
125                Ok(SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::from(ip), port)))
126            }
127            6 => {
128                if src.remaining() < 28 {
129                    return Err(DecodeError::UnexpectedEof);
130                }
131                let _family = src.get_u16_le();
132                let port = src.get_u16();
133                let flow_info = src.get_u32();
134                let mut ip = [0u8; 16];
135                src.copy_to_slice(&mut ip);
136                let scope_id = src.get_u32();
137
138                Ok(SocketAddr::V6(SocketAddrV6::new(
139                    Ipv6Addr::from(ip),
140                    port,
141                    flow_info,
142                    scope_id,
143                )))
144            }
145            _ => Err(DecodeError::InvalidAddrVersion(version)),
146        }
147    }
148}