summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobby Zambito <contact@robbyzambito.me>2026-01-19 12:27:24 -0500
committerRobby Zambito <contact@robbyzambito.me>2026-01-19 12:30:08 -0500
commitd7dedd243ec7a933d2b671b51328d8a1072305eb (patch)
treeb283aeb01227df842531a02e0d0aa42055bc6781
parent9947c21b4cdc8dea7ee456cdf76226807614d091 (diff)
construct full message
-rw-r--r--src/main.zig102
1 files changed, 63 insertions, 39 deletions
diff --git a/src/main.zig b/src/main.zig
index d128e33..3a22a01 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -99,36 +99,40 @@ pub fn main(init: std.process.Init) !void {
// std.debug.print("Interface: {s}\n", .{(try net_interface.name(init.io)).toSlice()});
const EthIpUdp = packed struct(u336) { // 42 bytes * 8 bits = 336
// --- UDP (Last in memory, defined first for LSB->MSB) ---
- checksum: u16 = 0,
- udp_len: u16,
- dst_port: u16,
- src_port: u16,
+ udp: packed struct {
+ checksum: u16 = 0,
+ len: u16,
+ dst_port: u16,
+ src_port: u16,
+ },
// --- IP ---
- dst_addr: u32,
- src_addr: u32,
- header_checksum: u16 = 0,
- protocol: u8 = 17, // udp
- ttl: u8 = 0x40,
-
- // fragment_offset (13 bits) + flags (3 bits) = 16 bits
- // In Big Endian, flags are the high bits of the first byte.
- // To have flags appear first in the stream, define them last here.
- fragment_offset: u13 = 0,
- flags: packed struct(u3) {
- reserved: u1 = 0,
- dont_fragment: u1 = 0,
- more_fragments: u1 = 0,
- } = .{},
-
- id: u16,
- total_length: u16,
- tos: u8 = undefined,
-
- // ip_version (4 bits) + ihl (4 bits) = 8 bits
- // To have version appear first (high nibble), define it last.
- ihl: u4 = 5,
- ip_version: u4 = 4,
+ ip: packed struct {
+ dst_addr: u32,
+ src_addr: u32,
+ header_checksum: u16 = 0,
+ protocol: u8 = 17, // udp
+ ttl: u8 = 0x40,
+
+ // fragment_offset (13 bits) + flags (3 bits) = 16 bits
+ // In Big Endian, flags are the high bits of the first byte.
+ // To have flags appear first in the stream, define them last here.
+ fragment_offset: u13 = 0,
+ flags: packed struct(u3) {
+ reserved: u1 = 0,
+ dont_fragment: u1 = 0,
+ more_fragments: u1 = 0,
+ } = .{},
+
+ id: u16,
+ len: u16,
+ tos: u8 = undefined,
+
+ // ip_version (4 bits) + ihl (4 bits) = 8 bits
+ // To have version appear first (high nibble), define it last.
+ ihl: u4 = 5,
+ ip_version: u4 = 4,
+ },
// --- Ethernet ---
eth_type: u16 = std.os.linux.ETH.P.IP,
@@ -141,18 +145,26 @@ pub fn main(init: std.process.Init) !void {
w.writeStruct(self, .big) catch unreachable;
return res;
}
+
+ fn setPayloadLen(self: *@This(), len: usize) void {
+ self.ip.len = @intCast(len + @sizeOf(@TypeOf(self.udp)) + @sizeOf(@TypeOf(self.ip)));
+ self.udp.len = @intCast(len + @sizeOf(@TypeOf(self.udp)));
+ }
};
- const headers: EthIpUdp = .{
+ var headers: EthIpUdp = .{
.src_mac = @splat(0x0e),
- .id = 0,
- .src_addr = 0,
- .dst_addr = @bitCast([_]u8{ 255, 255, 255, 255 }),
- .src_port = undefined, // TODO: change this?
- .dst_port = 8888,
-
- .total_length = undefined,
- .udp_len = undefined,
+ .ip = .{
+ .id = 0,
+ .src_addr = 0,
+ .dst_addr = @bitCast([_]u8{ 255, 255, 255, 255 }),
+ .len = undefined,
+ },
+ .udp = .{
+ .src_port = undefined, // TODO: change this?
+ .dst_port = 8888,
+ .len = undefined,
+ },
};
std.debug.print("headers: {any}\n", .{&headers.toBytes()});
@@ -163,8 +175,20 @@ pub fn main(init: std.process.Init) !void {
},
};
- var relay_bytes: [2048]u8 = undefined;
- std.debug.print("payload: {any}\n", .{relay.toBytes(&relay_bytes)});
+ var relay_buf: [2048]u8 = undefined;
+ const relay_bytes = relay.toBytes(&relay_buf);
+ std.debug.print("payload: {any}\n", .{relay_bytes});
+ headers.setPayloadLen(relay_bytes.len);
+
+ const full_msg = blk: {
+ var msg_buf: [2048]u8 = undefined;
+ var msg_w: Writer = .fixed(&msg_buf);
+ msg_w.writeAll(&headers.toBytes()) catch unreachable;
+ msg_w.writeAll(relay_bytes) catch unreachable;
+ break :blk msg_w.buffered();
+ };
+
+ std.debug.print("full message = {any}\n", .{full_msg});
}
fn parseDest(in: ?[]const u8) [4]u8 {