diff options
Diffstat (limited to 'src/Client.zig')
| -rw-r--r-- | src/Client.zig | 238 |
1 files changed, 97 insertions, 141 deletions
diff --git a/src/Client.zig b/src/Client.zig index 0c82129..86b08d4 100644 --- a/src/Client.zig +++ b/src/Client.zig @@ -30,166 +30,60 @@ 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 { +fn broadcastInitialInterestMessage(self: *Self, msg_bytes: []u8) !void { const writer = self.writer; - // const EthernetHeaders = packed struct { - // dest_mac: @Vector(6, u8), - - // src_mac: @Vector(6, u8), - - // ether_type: u16, - // }; - - const IpHeaders = packed struct { - _: u8 = 0x45, - // ip_version: u4, - // header_length: u4 = 0, - type_of_service: u8 = 0, - total_length: u16 = 0x04, - - identification: u16 = 0, - __: u16 = 0x0, - // ethernet_flags: u3 = 0, - // fragment_offset: u13 = 0, - ttl: u8 = 0, - protocol: u8 = 0, - - header_checksum: @Vector(2, u8) = .{ 0, 0 }, - src_ip: @Vector(4, u8), - - dest_ip: @Vector(4, u8), - }; - - const UdpHeaders = packed struct { - src_port: @Vector(2, u8), - - dest_port: @Vector(2, u8), - length: u16, - checksum: @Vector(2, u8) = .{ 0, 0 }, - }; - - // const total_len = ((@bitSizeOf(IpHeaders) + @bitSizeOf(UdpHeaders)) / 8) + msg_bytes.len; - const total_len = 130; + const total_len = ((@bitSizeOf(EthernetHeaders) + @bitSizeOf(IpHeaders) + @bitSizeOf(UdpHeaders)) / 8) + msg_bytes.len; std.debug.assert(writer.buffer.len >= total_len); _ = writer.consumeAll(); - // var ether_headers: EthernetHeaders = .{ - // .dest_mac = .{ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff }, - // // .src_mac = .{ 0xee, 0xee, 0xee, 0xee, 0xee, 0xee }, - // .src_mac = blk: { - // 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, - // }; - - var ip_headers: IpHeaders = .{ + const ether_headers: EthernetHeaders = .{ + .dest_mac = .{ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff }, + .src_mac = .{ 0xee, 0xee, 0xee, 0xee, 0xee, 0xee }, + // .src_mac = blk: { + // 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, + }; + + // @compileLog((@bitSizeOf(EthernetHeaders) / 8)); + const ip_headers: IpHeaders = .{ // .ip_version = 0x4, // .header_length = 0x5, - // .total_length = 130, //@intCast(total_len - 8), // 8 is the ethernet frame length (macs + type) - .total_length = 0x00, + .total_length = @intCast(total_len - 92), .ttl = 0x64, .protocol = 0x11, .src_ip = .{ 0xff, 0x02, 0x03, 0x04 }, .dest_ip = .{ 0xff, 0xff, 0xff, 0xff }, }; - var udp_headers: UdpHeaders = .{ - .src_port = .{ 0, 0x01 }, - .dest_port = .{ 0xb8, 0x22 }, + const udp_headers: UdpHeaders = .{ + .src_port = 0xbbbb, + .dest_port = 8888, .length = @intCast(msg_bytes.len), }; - _ = &ip_headers; - _ = &udp_headers; - // _ = ðer_headers; - - // _ = try writer.write(&@as([@bitSizeOf(UdpHeaders) / 8]u8, @bitCast(headers))); - - // std.mem.byteSwapAllFields(EthernetHeaders, ðer_headers); - // try writer.writeStruct(ether_headers, native_endian); - - std.mem.byteSwapAllFields(IpHeaders, &ip_headers); - try writer.writeStruct(ip_headers, native_endian); - - // std.mem.byteSwapAllFields(UdpHeaders, &udp_headers); - // try writer.writeStruct(udp_headers, native_endian); - - // // Ensure buffer is large enough - // std.debug.assert(writer.buffer.len > 38 + msg_bytes.len); - - // // Ensure writer is clean - // writer.consumeAll(); - - // // Destination MAC addr to FF:FF:FF:FF:FF:FF - // try writer.write(); - - // // Source MAC to random bytes - // { - // } - - // // 96 bits - - // // Set EtherType to IPv4 - // try writer.write(.{ 0x08, 0x00 }); - // // 112 bits + try ether_headers.write(writer); + try ip_headers.write(writer); + try udp_headers.write(writer); - // // Set IPv4 version to 4 - // try writer.writeByte(0x45); + // Saprus + const msg_target_bytes = try writer.writableSlice(msg_bytes.len); + @memcpy(msg_target_bytes, msg_bytes); + var msg_target: *align(1) SaprusMessage = try .bytesAsValue(msg_target_bytes); + try msg_target.networkFromNativeEndian(); - // // 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; - - // 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); - - // 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(); } // fn broadcastSaprusMessage(msg_bytes: []align(@alignOf(SaprusMessage)) u8) !void {} -fn broadcastSaprusMessage(msg_bytes: []align(@alignOf(SaprusMessage)) u8, udp_port: u16) !void { - const msg: *SaprusMessage = try .bytesAsValue(msg_bytes); +fn broadcastSaprusMessage(msg_bytes: []u8, udp_port: u16) !void { + const msg: *align(1) SaprusMessage = try .bytesAsValue(msg_bytes); try msg.networkFromNativeEndian(); defer msg.nativeFromNetworkEndian() catch unreachable; @@ -222,7 +116,7 @@ pub fn sendRelay(self: *Self, payload: []const u8, dest: [4]u8) !void { .relay, base64Enc.calcSize(payload.len), )]; - const msg: *SaprusMessage = .init(.relay, msg_bytes); + const msg: *align(1) SaprusMessage = .init(.relay, msg_bytes); const relay = (try msg.getSaprusTypePayload()).relay; relay.dest = dest; @@ -238,15 +132,15 @@ fn randomPort(self: Self) u16 { pub fn sendInitialConnection( self: Self, payload: []const u8, - output_bytes: []align(@alignOf(SaprusMessage)) u8, + output_bytes: []u8, initial_port: u16, -) !*SaprusMessage { +) !*align(1) SaprusMessage { const dest_port = self.randomPort(); const msg_bytes = output_bytes[0..try SaprusMessage.calcSize( .connection, base64Enc.calcSize(payload.len), )]; - const msg: *SaprusMessage = .init(.connection, msg_bytes); + const msg: *align(1) SaprusMessage = .init(.connection, msg_bytes); const connection = (try msg.getSaprusTypePayload()).connection; connection.src_port = initial_port; @@ -261,7 +155,7 @@ pub fn sendInitialConnection( pub fn connect(self: Self, payload: []const u8) !?SaprusConnection { const initial_port = self.randomPort(); - var initial_conn_res: ?*SaprusMessage = null; + var initial_conn_res: ?*align(1) SaprusMessage = null; var sock = try network.Socket.create(.ipv4, .udp); defer sock.close(); @@ -294,6 +188,68 @@ pub fn connect(self: Self, payload: []const u8) !?SaprusConnection { return null; } +const EthernetHeaders = struct { + dest_mac: @Vector(6, u8), + + src_mac: @Vector(6, u8), + + ether_type: u16, + + fn write(hdr: @This(), writer: *std.Io.Writer) !void { + try writer.writeInt(u48, @bitCast(hdr.dest_mac), .big); + try writer.writeInt(u48, @bitCast(hdr.src_mac), .big); + try writer.writeInt(u16, hdr.ether_type, .big); + } +}; + +const IpHeaders = struct { + _: u8 = 0x45, + // ip_version: u4, + // header_length: u4 = 0, + type_of_service: u8 = 0, + total_length: u16 = 0x04, + + identification: u16 = 0, + __: u16 = 0x0, + // ethernet_flags: u3 = 0, + // fragment_offset: u13 = 0, + ttl: u8 = 0, + protocol: u8 = 0, + + header_checksum: @Vector(2, u8) = .{ 0, 0 }, + src_ip: @Vector(4, u8), + + dest_ip: @Vector(4, u8), + + fn write(hdr: @This(), writer: *std.Io.Writer) !void { + try writer.writeInt(u8, 0x45, .big); // ip version and header length + try writer.writeByte(hdr.type_of_service); + try writer.writeInt(u16, hdr.total_length, .big); + try writer.writeInt(u16, hdr.identification, .big); + try writer.writeInt(u16, 0x00, .big); // ethernet flags and fragment offset + try writer.writeByte(hdr.ttl); + try writer.writeByte(hdr.protocol); + try writer.writeInt(u16, @bitCast(hdr.header_checksum), .big); + try writer.writeInt(u32, @bitCast(hdr.src_ip), .big); + try writer.writeInt(u32, @bitCast(hdr.dest_ip), .big); + } +}; + +const UdpHeaders = packed struct { + src_port: u16, + + dest_port: u16, + length: u16, + checksum: @Vector(2, u8) = .{ 0, 0 }, + + fn write(hdr: @This(), writer: *std.Io.Writer) !void { + try writer.writeInt(u16, hdr.src_port, .big); + try writer.writeInt(u16, hdr.dest_port, .big); + try writer.writeInt(u16, hdr.length, .big); + try writer.writeInt(u16, @bitCast(hdr.checksum), .big); + } +}; + const SaprusMessage = @import("message.zig").Message; const SaprusConnection = @import("Connection.zig"); |
