From b5efbd6e16b67629231e3bf87abae5d4454b59d0 Mon Sep 17 00:00:00 2001 From: Robby Zambito Date: Tue, 23 Sep 2025 13:39:03 -0400 Subject: Write ether headers properly --- src/Client.zig | 126 +++++++++++++++++++++++---------------------------------- 1 file changed, 50 insertions(+), 76 deletions(-) diff --git a/src/Client.zig b/src/Client.zig index 5c0e554..b200e6a 100644 --- a/src/Client.zig +++ b/src/Client.zig @@ -1,6 +1,8 @@ const base64Enc = std.base64.Base64Encoder.init(std.base64.standard_alphabet_chars, '='); const base64Dec = std.base64.Base64Decoder.init(std.base64.standard_alphabet_chars, '='); +const native_endian = @import("builtin").cpu.arch.endian(); + rand: Random, writer: *std.Io.Writer, @@ -31,106 +33,78 @@ pub fn deinit(self: *Self) void { fn broadcastInitialInterestMessage(self: *Self, msg_bytes: []align(@alignOf(SaprusMessage)) u8) !void { const writer = self.writer; - const UdpHeaders = packed struct { - dest_mac: u48, // [6]u8 + const EthernetHeaders = packed struct { + dest_mac: @Vector(6, u8), - src_mac: u48, // [6]u8 + src_mac: @Vector(6, u8), ether_type: u16, + }; + + const IpHeaders = packed struct { ip_version: u4, - header_length: u4, - type_of_service: u8, + header_length: u4 = 0, + type_of_service: u8 = 0, total_length: u16, - identification: u16, - ethernet_flags: u3, - fragment_offset: u13, - ttl: u8, - protocol: u8, + identification: u16 = 0, + ethernet_flags: u3 = 0, + fragment_offset: u13 = 0, + ttl: u8 = 0, + protocol: u8 = 0, - header_checksum: u16, // [2]u8 - src_ip: u16, // [2]u8 - dest_ip: u16, // [2]u8 + header_checksum: @Vector(2, u8) = .{ 0, 0 }, + src_ip: @Vector(4, u8), - src_port: u16, // [2]u8 - dest_port: u16, // [2]u8 - length: u16, + dest_ip: @Vector(4, u8), + }; + + const UdpHeaders = packed struct { + src_port: @Vector(2, u8), - 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), - }; - } + dest_port: @Vector(2, u8), + length: u16, + checksum: @Vector(2, u8) = .{ 0, 0 }, }; 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 }, + var ether_headers: EthernetHeaders = .{ + .dest_mac = .{ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff }, + // .src_mac = .{ 0xee, 0xee, 0xee, 0xee, 0xee, 0xee }, .src_mac = blk: { - const r_bytes = try writer.writableArray(6); - self.rand.bytes(r_bytes); - break :blk r_bytes.*; + var output_bytes: [6]u8 = undefined; + // const r_bytes = try writer.writableArray(6); + self.rand.bytes(&output_bytes); + break :blk output_bytes; }, .ether_type = 0x0800, + }; + + const ip_headers: IpHeaders = .{ .ip_version = 0x4, .header_length = 0x5, - .total_length = total_len - 8, // 8 is the ethernet frame length (macs + type) + .total_length = @intCast(total_len - 8), // 8 is the ethernet frame length (macs + type) .protocol = 0x11, - .src_ip = .{ 0, 0 }, - .dest_ip = .{ 0, 0 }, + .src_ip = .{ 0, 0, 0, 0 }, + .dest_ip = .{ 0, 0, 0, 0 }, + }; + + const udp_headers: UdpHeaders = .{ .src_port = .{ 0, 0 }, .dest_port = .{ 0xb8, 0x22 }, - .length = msg_bytes.len, - }); + .length = @intCast(msg_bytes.len), + }; + _ = ip_headers; + _ = udp_headers; + _ = ðer_headers; - _ = try writer.write(&@as([@bitSizeOf(UdpHeaders) / 8]u8, @bitCast(headers))); + // _ = try writer.write(&@as([@bitSizeOf(UdpHeaders) / 8]u8, @bitCast(headers))); - // try writer.writeStruct(headers, .big); + std.mem.byteSwapAllFields(EthernetHeaders, ðer_headers); + try writer.writeStruct(ether_headers, native_endian); // // Ensure buffer is large enough // std.debug.assert(writer.buffer.len > 38 + msg_bytes.len); @@ -190,7 +164,7 @@ fn broadcastInitialInterestMessage(self: *Self, msg_bytes: []align(@alignOf(Sapr try msg.networkFromNativeEndian(); defer msg.nativeFromNetworkEndian() catch unreachable; - std.debug.print("headers: {x}\n", .{@as([@bitSizeOf(UdpHeaders) / 8]u8, @bitCast(headers))}); + // 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); -- cgit