IT'S RIGHT

This commit is contained in:
2025-10-12 18:06:55 -04:00
parent fe166d2106
commit d6da3cd31b
3 changed files with 73 additions and 70 deletions

View File

@@ -5,8 +5,8 @@ rand: Random,
wrapped: *Writer, wrapped: *Writer,
interface: Writer, interface: Writer,
pub fn init(w: *Writer) !NetWriter { pub fn init(w: *Writer, buffer: []u8) !NetWriter {
std.debug.assert(w.buffer.len > @sizeOf(EthernetHeaders) + @sizeOf(IpHeaders) + @sizeOf(UdpHeaders)); std.debug.assert(buffer.len > @sizeOf(EthernetHeaders) + @sizeOf(IpHeaders) + @sizeOf(UdpHeaders));
var prng = Random.DefaultPrng.init(blk: { var prng = Random.DefaultPrng.init(blk: {
var seed: u64 = undefined; var seed: u64 = undefined;
@@ -20,33 +20,34 @@ pub fn init(w: *Writer) !NetWriter {
.interface = .{ .interface = .{
.vtable = &.{ .vtable = &.{
.drain = drain, .drain = drain,
.flush = flush, // .flush = flush,
}, },
.buffer = &.{}, .buffer = buffer,
}, },
}; };
} }
fn drain(io_w: *Writer, data: []const []const u8, splat: usize) Writer.Error!usize { fn drain(io_w: *Writer, data: []const []const u8, splat: usize) Writer.Error!usize {
const w: *NetWriter = @alignCast(@fieldParentPtr("interface", io_w)); const w: *NetWriter = @alignCast(@fieldParentPtr("interface", io_w));
const headers_byte_len = comptime (EthernetHeaders.byte_len + IpHeaders.byte_len + UdpHeaders.byte_len);
var res: usize = 0; const headers: [headers_byte_len]u8 = blk: {
if (io_w.end == 0) {
const ether_headers: EthernetHeaders = .{ const ether_headers: EthernetHeaders = .{
.dest_mac = .{ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff }, .dest_mac = .{ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff },
.src_mac = blk: { .src_mac = src_blk: {
var output_bytes: [6]u8 = undefined; var output_bytes: [6]u8 = undefined;
output_bytes[0] = 0xee; output_bytes[0] = 0xee;
w.rand.bytes(output_bytes[1..]); w.rand.bytes(output_bytes[1..]);
break :blk output_bytes; break :src_blk output_bytes;
}, },
.ether_type = 0x0800, .ether_type = 0x0800,
}; };
const total_len = Writer.countSplat(data, splat) + w.interface.end;
const ip_headers: IpHeaders = .{ const ip_headers: IpHeaders = .{
.total_length = @intCast(res - 92), // length of the packet minus eth header
.ttl = 0x64, .total_length = @intCast(headers_byte_len + total_len - EthernetHeaders.byte_len), //@intCast(total_len),
.ttl = 64,
.protocol = 0x11, .protocol = 0x11,
.src_ip = .{ 0xff, 0x02, 0x03, 0x04 }, .src_ip = .{ 0xff, 0x02, 0x03, 0x04 },
.dest_ip = .{ 0xff, 0xff, 0xff, 0xff }, .dest_ip = .{ 0xff, 0xff, 0xff, 0xff },
@@ -55,23 +56,35 @@ fn drain(io_w: *Writer, data: []const []const u8, splat: usize) Writer.Error!usi
const udp_headers: UdpHeaders = .{ const udp_headers: UdpHeaders = .{
.src_port = 0xbbbb, .src_port = 0xbbbb,
.dest_port = 8888, .dest_port = 8888,
.length = @intCast(res), .length = @intCast(total_len + UdpHeaders.byte_len),
}; };
res += try ether_headers.write(w.wrapped); var buf: [headers_byte_len]u8 = undefined;
res += try ip_headers.write(w.wrapped); var buf_w = Writer.fixed(&buf);
res += try udp_headers.write(w.wrapped);
}
res += try w.wrapped.writeSplat(data, splat); _ = try ether_headers.write(&buf_w);
return res; _ = try ip_headers.write(&buf_w);
} std.debug.print("after ip: {x}\n", .{buf_w.buffered()});
_ = try udp_headers.write(&buf_w);
std.debug.print("after udp: {x}\n", .{buf_w.buffered()});
break :blk buf;
};
_ = try w.wrapped.write(&headers);
const total_len = try w.wrapped.writeSplatHeader(w.interface.buffered(), data, splat);
std.debug.print("total splat: {}\theaders.len: {}\tsplat: {}\n", .{ total_len, headers.len, splat });
fn flush(io_w: *Writer) Writer.Error!void {
const w: *NetWriter = @alignCast(@fieldParentPtr("interface", io_w));
try w.wrapped.flush(); try w.wrapped.flush();
return total_len - w.interface.consumeAll();
} }
// fn flush(io_w: *Writer) Writer.Error!void {
// const w: *NetWriter = @alignCast(@fieldParentPtr("interface", io_w));
// try io_w.defaultFlush();
// }
const EthernetHeaders = struct { const EthernetHeaders = struct {
dest_mac: @Vector(6, u8), dest_mac: @Vector(6, u8),
@@ -80,21 +93,19 @@ const EthernetHeaders = struct {
ether_type: u16, ether_type: u16,
fn write(hdr: EthernetHeaders, writer: *std.Io.Writer) Writer.Error!usize { fn write(hdr: EthernetHeaders, writer: *std.Io.Writer) Writer.Error!usize {
comptime var res: usize = 0;
res += @sizeOf(u48);
try writer.writeInt(u48, @bitCast(hdr.dest_mac), .big); try writer.writeInt(u48, @bitCast(hdr.dest_mac), .big);
res += @sizeOf(u48);
try writer.writeInt(u48, @bitCast(hdr.src_mac), .big); try writer.writeInt(u48, @bitCast(hdr.src_mac), .big);
res += @sizeOf(u16);
try writer.writeInt(u16, hdr.ether_type, .big); try writer.writeInt(u16, hdr.ether_type, .big);
return byte_len;
return res;
} }
const byte_len = @bitSizeOf(EthernetHeaders) / 8; const byte_len = blk: {
var res: usize = 0;
res += @bitSizeOf(u48) / 8;
res += @bitSizeOf(u48) / 8;
res += @bitSizeOf(u16) / 8;
break :blk res;
};
fn bytes(hdr: EthernetHeaders) [byte_len]u8 { fn bytes(hdr: EthernetHeaders) [byte_len]u8 {
var res: [byte_len]u8 = undefined; var res: [byte_len]u8 = undefined;
@@ -120,42 +131,33 @@ const IpHeaders = struct {
dest_ip: @Vector(4, u8), dest_ip: @Vector(4, u8),
fn write(hdr: @This(), writer: *std.Io.Writer) Writer.Error!usize { fn write(hdr: @This(), writer: *std.Io.Writer) Writer.Error!usize {
comptime var res: usize = 0;
res += @sizeOf(u8);
try writer.writeInt(u8, 0x45, .big); // ip version and header length try writer.writeInt(u8, 0x45, .big); // ip version and header length
res += @sizeOf(u8);
try writer.writeByte(hdr.type_of_service); try writer.writeByte(hdr.type_of_service);
res += @sizeOf(u16);
try writer.writeInt(u16, hdr.total_length, .big); try writer.writeInt(u16, hdr.total_length, .big);
res += @sizeOf(u16);
try writer.writeInt(u16, hdr.identification, .big); try writer.writeInt(u16, hdr.identification, .big);
res += @sizeOf(u16);
try writer.writeInt(u16, 0x00, .big); // ethernet flags and fragment offset try writer.writeInt(u16, 0x00, .big); // ethernet flags and fragment offset
res += @sizeOf(u8);
try writer.writeByte(hdr.ttl); try writer.writeByte(hdr.ttl);
res += @sizeOf(u8);
try writer.writeByte(hdr.protocol); try writer.writeByte(hdr.protocol);
res += @sizeOf(u16);
try writer.writeInt(u16, @bitCast(hdr.header_checksum), .big); try writer.writeInt(u16, @bitCast(hdr.header_checksum), .big);
res += @sizeOf(u32);
try writer.writeInt(u32, @bitCast(hdr.src_ip), .big); try writer.writeInt(u32, @bitCast(hdr.src_ip), .big);
res += @sizeOf(u32);
try writer.writeInt(u32, @bitCast(hdr.dest_ip), .big); try writer.writeInt(u32, @bitCast(hdr.dest_ip), .big);
return byte_len;
return res;
} }
const byte_len = @bitSizeOf(IpHeaders) / 8; const byte_len = blk: {
var res: usize = 0;
res += @sizeOf(u8);
res += @sizeOf(u8);
res += @sizeOf(u16);
res += @sizeOf(u16);
res += @sizeOf(u16);
res += @sizeOf(u8);
res += @sizeOf(u8);
res += @sizeOf(u16);
res += @sizeOf(u32);
res += @sizeOf(u32);
break :blk res;
};
fn bytes(hdr: IpHeaders) [byte_len]u8 { fn bytes(hdr: IpHeaders) [byte_len]u8 {
var res: [byte_len]u8 = undefined; var res: [byte_len]u8 = undefined;
@@ -171,24 +173,21 @@ const UdpHeaders = packed struct {
checksum: @Vector(2, u8) = .{ 0, 0 }, checksum: @Vector(2, u8) = .{ 0, 0 },
fn write(hdr: @This(), writer: *std.Io.Writer) Writer.Error!usize { fn write(hdr: @This(), writer: *std.Io.Writer) Writer.Error!usize {
comptime var res: usize = 0;
res += @sizeOf(u16);
try writer.writeInt(u16, hdr.src_port, .big); try writer.writeInt(u16, hdr.src_port, .big);
res += @sizeOf(u16);
try writer.writeInt(u16, hdr.dest_port, .big); try writer.writeInt(u16, hdr.dest_port, .big);
res += @sizeOf(u16);
try writer.writeInt(u16, hdr.length, .big); try writer.writeInt(u16, hdr.length, .big);
res += @sizeOf(u16);
try writer.writeInt(u16, @bitCast(hdr.checksum), .big); try writer.writeInt(u16, @bitCast(hdr.checksum), .big);
return byte_len;
return res;
} }
const byte_len = @bitSizeOf(UdpHeaders) / 8; const byte_len = blk: {
var res: usize = 0;
res += @sizeOf(u16);
res += @sizeOf(u16);
res += @sizeOf(u16);
res += @sizeOf(u16);
break :blk res;
};
fn bytes(hdr: UdpHeaders) [byte_len]u8 { fn bytes(hdr: UdpHeaders) [byte_len]u8 {
var res: [byte_len]u8 = undefined; var res: [byte_len]u8 = undefined;

View File

@@ -8,12 +8,14 @@ interface: Writer,
socket: gcat.nic.RawSocket, socket: gcat.nic.RawSocket,
fn drain(io_w: *std.Io.Writer, data: []const []const u8, splat: usize) Writer.Error!usize { fn drain(io_w: *std.Io.Writer, data: []const []const u8, splat: usize) Writer.Error!usize {
std.debug.print("in drain\n", .{});
const w: *RawSocketWriter = @alignCast(@fieldParentPtr("interface", io_w)); const w: *RawSocketWriter = @alignCast(@fieldParentPtr("interface", io_w));
const rem_buf = io_w.unusedCapacitySlice(); const rem_buf = io_w.unusedCapacitySlice();
var rem_w = Writer.fixed(rem_buf); var rem_w = Writer.fixed(rem_buf);
const res = rem_w.writeSplat(data, splat) catch rem_buf.len; const res = rem_w.writeSplat(data, splat) catch rem_buf.len;
io_w.advance(res); io_w.advance(res);
const buffered = io_w.buffered(); const buffered = io_w.buffered();
std.debug.print("buffer: {x}\n", .{buffered});
w.socket.linkLayer().send(buffered) catch return error.WriteFailed; w.socket.linkLayer().send(buffered) catch return error.WriteFailed;
_ = io_w.consumeAll(); _ = io_w.consumeAll();
@@ -21,6 +23,7 @@ fn drain(io_w: *std.Io.Writer, data: []const []const u8, splat: usize) Writer.Er
} }
pub fn init(interface_name: [:0]const u8, buffer: []u8) !RawSocketWriter { pub fn init(interface_name: [:0]const u8, buffer: []u8) !RawSocketWriter {
std.debug.assert(buffer.len > 0);
return .{ return .{
.interface = .{ .interface = .{
.vtable = &.{ .drain = drain }, .vtable = &.{ .drain = drain },

View File

@@ -46,9 +46,10 @@ pub fn main() !void {
return clap.helpToFile(.stderr(), clap.Help, &params, .{}); return clap.helpToFile(.stderr(), clap.Help, &params, .{});
} }
var sock_buffer: [2048]u8 = undefined; var sock_buffer: [1500]u8 = undefined;
var raw_socket_writer: RawSocketWriter = try .init("enp7s0", &sock_buffer); // /proc/net/dev var raw_socket_writer: RawSocketWriter = try .init("enp7s0", &sock_buffer); // /proc/net/dev
var net_writer: NetWriter = try .init(&raw_socket_writer.interface); var net_buffer: [1500]u8 = undefined;
var net_writer: NetWriter = try .init(&raw_socket_writer.interface, &net_buffer);
var client = try SaprusClient.init(&net_writer.interface); var client = try SaprusClient.init(&net_writer.interface);
defer client.deinit(); defer client.deinit();