summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.zig106
1 files changed, 74 insertions, 32 deletions
diff --git a/src/main.zig b/src/main.zig
index 24b24fa..3d58f66 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -147,13 +147,16 @@ pub fn main(init: std.process.Init) !void {
}
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)));
+ self.ip.len = @intCast(len + (@bitSizeOf(@TypeOf(self.udp)) / 8) + (@bitSizeOf(@TypeOf(self.ip)) / 8));
+ self.udp.len = @intCast(len + (@bitSizeOf(@TypeOf(self.udp)) / 8));
}
};
+ var socket: RawSocket = try .init();
+ defer socket.deinit();
+
var headers: EthIpUdp = .{
- .src_mac = undefined, // TODO: REAL MAC
+ .src_mac = socket.mac,
.ip = .{
.id = 0,
.src_addr = rand.int(u32),
@@ -191,8 +194,6 @@ pub fn main(init: std.process.Init) !void {
std.debug.print("full message = {any}\n", .{full_msg});
- var socket: RawSocket = try .init("enp7s0");
- defer socket.deinit();
try socket.send(full_msg);
return;
}
@@ -229,8 +230,6 @@ pub fn main(init: std.process.Init) !void {
std.debug.print("full message = {any}\n", .{full_msg});
- var socket: RawSocket = try .init("enp7s0");
- defer socket.deinit();
try socket.send(full_msg);
return;
}
@@ -268,47 +267,90 @@ const SOCK = std.os.linux.SOCK;
const RawSocket = struct {
fd: i32,
sockaddr_ll: std.posix.sockaddr.ll,
+ mac: [6]u8,
+
+ const IFF_LOOPBACK = 0x8;
+
+ const ifconf = extern struct {
+ ifc_len: i32,
+ ifc_ifcu: extern union {
+ ifcu_buf: ?[*]u8,
+ ifcu_req: ?[*]std.os.linux.ifreq,
+ },
+ };
+
+ fn init() !RawSocket {
+ const socket: i32 = @intCast(std.os.linux.socket(std.posix.AF.PACKET, std.posix.SOCK.RAW, 0));
+ if (socket < 0) return error.SocketError;
- fn init(ifname: []const u8) !RawSocket {
- const socket: i32 = @intCast(std.os.linux.socket(AF.PACKET, SOCK.RAW, 0));
+ // 1. Enumerate interfaces
+ var ifreq_storage: [16]std.os.linux.ifreq = undefined;
+ var ifc = ifconf{
+ .ifc_len = @sizeOf(@TypeOf(ifreq_storage)),
+ .ifc_ifcu = .{ .ifcu_req = &ifreq_storage },
+ };
+
+ if (std.os.linux.ioctl(socket, std.os.linux.SIOCGIFCONF, @intFromPtr(&ifc)) != 0) {
+ return error.NicError;
+ }
- var ifr: std.posix.ifreq = std.mem.zeroInit(std.posix.ifreq, .{});
- @memcpy(ifr.ifrn.name[0..ifname.len], ifname);
- ifr.ifrn.name[ifname.len] = 0;
- try std.posix.ioctl_SIOCGIFINDEX(socket, &ifr);
+ const count = @divExact(ifc.ifc_len, @sizeOf(std.os.linux.ifreq));
+ var target_ifr: ?std.os.linux.ifreq = null;
+
+ for (ifreq_storage[0..@intCast(count)]) |ifr| {
+ var temp_ifr = ifr;
+ if (std.os.linux.ioctl(socket, std.os.linux.SIOCGIFFLAGS, @intFromPtr(&temp_ifr)) == 0) {
+ // Cast the packed flags to u16 to match the kernel's ifr_flags size
+ const flags: u16 = @bitCast(temp_ifr.ifru.flags);
+ if (flags & IFF_LOOPBACK != 0) continue;
+
+ target_ifr = ifr;
+ break;
+ }
+ }
+
+ var ifr = target_ifr orelse return error.NoInterfaceFound;
+
+ // 2. Get Interface Index
+ if (std.os.linux.ioctl(socket, std.os.linux.SIOCGIFINDEX, @intFromPtr(&ifr)) != 0) {
+ return error.NicError;
+ }
const ifindex: i32 = ifr.ifru.ivalue;
- var rval = std.posix.errno(std.os.linux.ioctl(socket, std.os.linux.SIOCGIFFLAGS, @intFromPtr(&ifr)));
- switch (rval) {
- .SUCCESS => {},
- else => {
- return error.NicError;
- },
+ // 3. Get Real MAC Address
+ if (std.os.linux.ioctl(socket, std.os.linux.SIOCGIFHWADDR, @intFromPtr(&ifr)) != 0) {
+ return error.NicError;
+ }
+ var mac: [6]u8 = ifr.ifru.hwaddr.data[0..6].*;
+ std.mem.reverse(u8, &mac);
+
+ // 4. Set Flags (Promiscuous/Broadcast)
+ if (std.os.linux.ioctl(socket, std.os.linux.SIOCGIFFLAGS, @intFromPtr(&ifr)) != 0) {
+ return error.NicError;
}
ifr.ifru.flags.BROADCAST = true;
ifr.ifru.flags.PROMISC = true;
- rval = std.posix.errno(std.os.linux.ioctl(socket, std.os.linux.SIOCSIFFLAGS, @intFromPtr(&ifr)));
- switch (rval) {
- .SUCCESS => {},
- else => {
- return error.NicError;
- },
+ if (std.os.linux.ioctl(socket, std.os.linux.SIOCSIFFLAGS, @intFromPtr(&ifr)) != 0) {
+ return error.NicError;
}
- std.debug.print("ifindex: {}\n", .{ifindex});
+
const sockaddr_ll = std.posix.sockaddr.ll{
.family = std.posix.AF.PACKET,
.ifindex = ifindex,
.protocol = std.mem.nativeToBig(u16, @as(u16, std.os.linux.ETH.P.IP)),
- .halen = 0, //not used
- .addr = .{ 0, 0, 0, 0, 0, 0, 0, 0 }, //not used
- .pkttype = 0, //not used
- .hatype = 0, //not used
+ .halen = 0,
+ .addr = .{ 0, 0, 0, 0, 0, 0, 0, 0 },
+ .pkttype = 0,
+ .hatype = 0,
};
- _ = std.os.linux.bind(socket, @ptrCast(&sockaddr_ll), @sizeOf(@TypeOf(sockaddr_ll)));
+
+ const bind_ret = std.os.linux.bind(socket, @ptrCast(&sockaddr_ll), @sizeOf(@TypeOf(sockaddr_ll)));
+ if (bind_ret != 0) return error.BindError;
return .{
.fd = socket,
.sockaddr_ll = sockaddr_ll,
+ .mac = mac,
};
}
@@ -333,7 +375,7 @@ const RawSocket = struct {
self.fd,
buf.ptr,
buf.len,
- 0, // flags
+ 0,
null,
null,
);