mirror of
https://git.robbyzambito.me/zaprus/
synced 2026-02-04 11:44:49 +00:00
Detect interface and use real mac
This commit is contained in:
102
src/main.zig
102
src/main.zig
@@ -147,13 +147,16 @@ pub fn main(init: std.process.Init) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn setPayloadLen(self: *@This(), len: usize) void {
|
fn setPayloadLen(self: *@This(), len: usize) void {
|
||||||
self.ip.len = @intCast(len + @sizeOf(@TypeOf(self.udp)) + @sizeOf(@TypeOf(self.ip)));
|
self.ip.len = @intCast(len + (@bitSizeOf(@TypeOf(self.udp)) / 8) + (@bitSizeOf(@TypeOf(self.ip)) / 8));
|
||||||
self.udp.len = @intCast(len + @sizeOf(@TypeOf(self.udp)));
|
self.udp.len = @intCast(len + (@bitSizeOf(@TypeOf(self.udp)) / 8));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var socket: RawSocket = try .init();
|
||||||
|
defer socket.deinit();
|
||||||
|
|
||||||
var headers: EthIpUdp = .{
|
var headers: EthIpUdp = .{
|
||||||
.src_mac = undefined, // TODO: REAL MAC
|
.src_mac = socket.mac,
|
||||||
.ip = .{
|
.ip = .{
|
||||||
.id = 0,
|
.id = 0,
|
||||||
.src_addr = rand.int(u32),
|
.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});
|
std.debug.print("full message = {any}\n", .{full_msg});
|
||||||
|
|
||||||
var socket: RawSocket = try .init("enp7s0");
|
|
||||||
defer socket.deinit();
|
|
||||||
try socket.send(full_msg);
|
try socket.send(full_msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -229,8 +230,6 @@ pub fn main(init: std.process.Init) !void {
|
|||||||
|
|
||||||
std.debug.print("full message = {any}\n", .{full_msg});
|
std.debug.print("full message = {any}\n", .{full_msg});
|
||||||
|
|
||||||
var socket: RawSocket = try .init("enp7s0");
|
|
||||||
defer socket.deinit();
|
|
||||||
try socket.send(full_msg);
|
try socket.send(full_msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -268,47 +267,90 @@ const SOCK = std.os.linux.SOCK;
|
|||||||
const RawSocket = struct {
|
const RawSocket = struct {
|
||||||
fd: i32,
|
fd: i32,
|
||||||
sockaddr_ll: std.posix.sockaddr.ll,
|
sockaddr_ll: std.posix.sockaddr.ll,
|
||||||
|
mac: [6]u8,
|
||||||
|
|
||||||
fn init(ifname: []const u8) !RawSocket {
|
const IFF_LOOPBACK = 0x8;
|
||||||
const socket: i32 = @intCast(std.os.linux.socket(AF.PACKET, SOCK.RAW, 0));
|
|
||||||
|
|
||||||
var ifr: std.posix.ifreq = std.mem.zeroInit(std.posix.ifreq, .{});
|
const ifconf = extern struct {
|
||||||
@memcpy(ifr.ifrn.name[0..ifname.len], ifname);
|
ifc_len: i32,
|
||||||
ifr.ifrn.name[ifname.len] = 0;
|
ifc_ifcu: extern union {
|
||||||
try std.posix.ioctl_SIOCGIFINDEX(socket, &ifr);
|
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;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
const ifindex: i32 = ifr.ifru.ivalue;
|
||||||
|
|
||||||
var rval = std.posix.errno(std.os.linux.ioctl(socket, std.os.linux.SIOCGIFFLAGS, @intFromPtr(&ifr)));
|
// 3. Get Real MAC Address
|
||||||
switch (rval) {
|
if (std.os.linux.ioctl(socket, std.os.linux.SIOCGIFHWADDR, @intFromPtr(&ifr)) != 0) {
|
||||||
.SUCCESS => {},
|
return error.NicError;
|
||||||
else => {
|
}
|
||||||
|
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;
|
return error.NicError;
|
||||||
},
|
|
||||||
}
|
}
|
||||||
ifr.ifru.flags.BROADCAST = true;
|
ifr.ifru.flags.BROADCAST = true;
|
||||||
ifr.ifru.flags.PROMISC = true;
|
ifr.ifru.flags.PROMISC = true;
|
||||||
rval = std.posix.errno(std.os.linux.ioctl(socket, std.os.linux.SIOCSIFFLAGS, @intFromPtr(&ifr)));
|
if (std.os.linux.ioctl(socket, std.os.linux.SIOCSIFFLAGS, @intFromPtr(&ifr)) != 0) {
|
||||||
switch (rval) {
|
|
||||||
.SUCCESS => {},
|
|
||||||
else => {
|
|
||||||
return error.NicError;
|
return error.NicError;
|
||||||
},
|
|
||||||
}
|
}
|
||||||
std.debug.print("ifindex: {}\n", .{ifindex});
|
|
||||||
const sockaddr_ll = std.posix.sockaddr.ll{
|
const sockaddr_ll = std.posix.sockaddr.ll{
|
||||||
.family = std.posix.AF.PACKET,
|
.family = std.posix.AF.PACKET,
|
||||||
.ifindex = ifindex,
|
.ifindex = ifindex,
|
||||||
.protocol = std.mem.nativeToBig(u16, @as(u16, std.os.linux.ETH.P.IP)),
|
.protocol = std.mem.nativeToBig(u16, @as(u16, std.os.linux.ETH.P.IP)),
|
||||||
.halen = 0, //not used
|
.halen = 0,
|
||||||
.addr = .{ 0, 0, 0, 0, 0, 0, 0, 0 }, //not used
|
.addr = .{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
.pkttype = 0, //not used
|
.pkttype = 0,
|
||||||
.hatype = 0, //not used
|
.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 .{
|
return .{
|
||||||
.fd = socket,
|
.fd = socket,
|
||||||
.sockaddr_ll = sockaddr_ll,
|
.sockaddr_ll = sockaddr_ll,
|
||||||
|
.mac = mac,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,7 +375,7 @@ const RawSocket = struct {
|
|||||||
self.fd,
|
self.fd,
|
||||||
buf.ptr,
|
buf.ptr,
|
||||||
buf.len,
|
buf.len,
|
||||||
0, // flags
|
0,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user