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

View File

@@ -8,12 +8,14 @@ interface: Writer,
socket: gcat.nic.RawSocket,
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 rem_buf = io_w.unusedCapacitySlice();
var rem_w = Writer.fixed(rem_buf);
const res = rem_w.writeSplat(data, splat) catch rem_buf.len;
io_w.advance(res);
const buffered = io_w.buffered();
std.debug.print("buffer: {x}\n", .{buffered});
w.socket.linkLayer().send(buffered) catch return error.WriteFailed;
_ = 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 {
std.debug.assert(buffer.len > 0);
return .{
.interface = .{
.vtable = &.{ .drain = drain },

View File

@@ -46,9 +46,10 @@ pub fn main() !void {
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 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);
defer client.deinit();