diff options
| author | Robby Zambito <contact@robbyzambito.me> | 2025-09-09 23:17:32 -0400 |
|---|---|---|
| committer | Robby Zambito <contact@robbyzambito.me> | 2025-09-23 13:33:17 -0400 |
| commit | 30243db5c99ab6d485cca95d8b84c89e08f4431d (patch) | |
| tree | 990b60f9e27c711f31a100c70c8559f07f7e5509 /src | |
| parent | c673401c2ad1c463153fe4dd7f2eb400459896b6 (diff) | |
Diffstat (limited to 'src')
| -rw-r--r-- | src/Client.zig | 184 |
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(); } |
