summaryrefslogtreecommitdiff
path: root/src/Client.zig
diff options
context:
space:
mode:
authorRobby Zambito <contact@robbyzambito.me>2025-09-09 23:17:32 -0400
committerRobby Zambito <contact@robbyzambito.me>2025-09-23 13:33:17 -0400
commit30243db5c99ab6d485cca95d8b84c89e08f4431d (patch)
tree990b60f9e27c711f31a100c70c8559f07f7e5509 /src/Client.zig
parentc673401c2ad1c463153fe4dd7f2eb400459896b6 (diff)
Diffstat (limited to 'src/Client.zig')
-rw-r--r--src/Client.zig184
1 files changed, 156 insertions, 28 deletions
diff --git a/src/Client.zig b/src/Client.zig
index 37ef3ac..5c0e554 100644
--- a/src/Client.zig
+++ b/src/Client.zig
@@ -29,47 +29,175 @@ pub fn deinit(self: *Self) void {
/// Used for relay messages and connection handshake.
/// Assumes Client .init has been called.
fn broadcastInitialInterestMessage(self: *Self, msg_bytes: []align(@alignOf(SaprusMessage)) u8) !void {
- var packet_bytes: [max_message_size]u8 = comptime blk: {
- var b: [max_message_size]u8 = @splat(0);
+ const writer = self.writer;
- // Destination MAC addr to FF:FF:FF:FF:FF:FF
- for (0..6) |i| {
- b[i] = 0xff;
+ const UdpHeaders = packed struct {
+ dest_mac: u48, // [6]u8
+
+ src_mac: u48, // [6]u8
+
+ ether_type: u16,
+ ip_version: u4,
+ header_length: u4,
+ type_of_service: u8,
+ total_length: u16,
+
+ identification: u16,
+ ethernet_flags: u3,
+ fragment_offset: u13,
+ ttl: u8,
+ protocol: u8,
+
+ header_checksum: u16, // [2]u8
+ src_ip: u16, // [2]u8
+ dest_ip: u16, // [2]u8
+
+ src_port: u16, // [2]u8
+ dest_port: u16, // [2]u8
+ length: u16,
+
+ checksum: u16, // [2]u8
+
+ fn init(
+ in: struct {
+ dest_mac: [6]u8,
+ src_mac: [6]u8,
+ ether_type: u16,
+ ip_version: u4,
+ header_length: u4 = 0,
+ type_of_service: u4 = 0,
+ total_length: usize,
+ identification: u16 = 0,
+ ethernet_flags: u3 = 0,
+ fragment_offset: u13 = 0,
+ ttl: u8 = 0,
+ protocol: u8 = 0,
+ header_checksum: [2]u8 = .{ 0, 0 },
+ src_ip: [2]u8,
+ dest_ip: [2]u8,
+ src_port: [2]u8,
+ dest_port: [2]u8,
+ length: usize,
+ checksum: [2]u8 = .{ 0, 0 },
+ },
+ ) @This() {
+ return .{
+ .dest_mac = @bitCast(in.dest_mac),
+ .src_mac = @bitCast(in.src_mac),
+ .ether_type = in.ether_type,
+ .ip_version = in.ip_version,
+ .header_length = in.header_length,
+ .type_of_service = in.type_of_service,
+ .total_length = @intCast(in.total_length),
+ .identification = in.identification,
+ .ethernet_flags = in.ethernet_flags,
+ .fragment_offset = in.fragment_offset,
+ .ttl = in.ttl,
+ .protocol = in.protocol,
+ .header_checksum = @bitCast(in.header_checksum),
+ .src_ip = @bitCast(in.src_ip),
+ .dest_ip = @bitCast(in.dest_ip),
+ .src_port = @bitCast(in.src_port),
+ .dest_port = @bitCast(in.dest_port),
+ .length = @intCast(in.length),
+ .checksum = @bitCast(in.checksum),
+ };
}
+ };
+
+ const total_len = (@bitSizeOf(UdpHeaders) / 8) + msg_bytes.len;
+ std.debug.assert(writer.buffer.len >= total_len);
+ _ = writer.consumeAll();
+
+ const headers: UdpHeaders = .init(.{
+ .dest_mac = .{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
+ .src_mac = blk: {
+ const r_bytes = try writer.writableArray(6);
+ self.rand.bytes(r_bytes);
+ break :blk r_bytes.*;
+ },
+ .ether_type = 0x0800,
+ .ip_version = 0x4,
+ .header_length = 0x5,
+ .total_length = total_len - 8, // 8 is the ethernet frame length (macs + type)
+ .protocol = 0x11,
+ .src_ip = .{ 0, 0 },
+ .dest_ip = .{ 0, 0 },
+ .src_port = .{ 0, 0 },
+ .dest_port = .{ 0xb8, 0x22 },
+ .length = msg_bytes.len,
+ });
- // Set Ethernet type to IPv4
- b[0x0c] = 0x08;
- b[0x0d] = 0x00;
+ _ = try writer.write(&@as([@bitSizeOf(UdpHeaders) / 8]u8, @bitCast(headers)));
- // Set IPv4 version to 4
- b[0x0e] = 0x45;
+ // try writer.writeStruct(headers, .big);
- // Destination broadcast
- for (0x1e..0x22) |i| {
- b[i] = 0xff;
- }
+ // // Ensure buffer is large enough
+ // std.debug.assert(writer.buffer.len > 38 + msg_bytes.len);
- // Set TTL
- b[0x16] = 0x40;
+ // // Ensure writer is clean
+ // writer.consumeAll();
- // Set IPv4 protocol to UDP
- b[0x17] = 0x11;
+ // // Destination MAC addr to FF:FF:FF:FF:FF:FF
+ // try writer.write();
- // Set interest filter value to 8888.
- b[0x24] = 0x22;
- b[0x25] = 0xb8;
- break :blk b;
- };
+ // // Source MAC to random bytes
+ // {
+ // }
+
+ // // 96 bits
+
+ // // Set EtherType to IPv4
+ // try writer.write(.{ 0x08, 0x00 });
+
+ // // 112 bits
+
+ // // Set IPv4 version to 4
+ // try writer.writeByte(0x45);
+
+ // // 120 bits
+
+ // // Unset section (Version, IHL, ToS)
+ // writer.advance(2);
+
+ // // 136 bits
+
+ // // Total length
+ // try write.writeInt(u16, 38 + msg_bytes.len);
+
+ // // Destination broadcast
+ // writer.splatByte(0xff, 0x22 - 0x1e);
+
+ // var packet_bytes: [_]u8 = comptime blk: {
+ // var b: [max_message_size]u8 = @splat(0);
+
+ // for (0x1e..0x22) |i| {
+ // b[i] = 0xff;
+ // }
+
+ // // Set TTL
+ // b[0x16] = 0x40;
+
+ // // Set IPv4 protocol to UDP
+ // b[0x17] = 0x11;
+
+ // // Set interest filter value to 8888.
+ // b[0x24] = 0x22;
+ // b[0x25] = 0xb8;
+ // break :blk &b;
+ // };
var msg: *SaprusMessage = try .bytesAsValue(msg_bytes);
try msg.networkFromNativeEndian();
defer msg.nativeFromNetworkEndian() catch unreachable;
- // The byte position within the packet that the saprus message starts at.
- const saprus_start_byte = 42;
- @memcpy(packet_bytes[saprus_start_byte .. saprus_start_byte + msg_bytes.len], msg_bytes);
+ std.debug.print("headers: {x}\n", .{@as([@bitSizeOf(UdpHeaders) / 8]u8, @bitCast(headers))});
+ std.debug.print("bytes: {x}\n", .{writer.buffer[0..writer.end]});
+ _ = try writer.write(msg_bytes);
- const writer = self.writer;
- _ = try writer.write(packet_bytes[0 .. saprus_start_byte + msg_bytes.len]);
+ // The byte position within the packet that the saprus message starts at.
+ // const saprus_start_byte = 42;
+ // @memcpy(packet_bytes[saprus_start_byte .. saprus_start_byte + msg_bytes.len], msg_bytes);
+ // _ = try writer.write(packet_bytes[0 .. saprus_start_byte + msg_bytes.len]);
try writer.flush();
}