82 lines
2.4 KiB
Zig
82 lines
2.4 KiB
Zig
const std = @import("std");
|
|
|
|
const linux = std.os.linux;
|
|
|
|
pub const Address = extern union {
|
|
any: linux.sockaddr,
|
|
in: linux.sockaddr.in,
|
|
in6: linux.sockaddr.in6,
|
|
un: linux.sockaddr.un,
|
|
|
|
pub fn initIp4(addr: [4]u8, port: u16) Address {
|
|
return .{
|
|
.in = .{
|
|
.addr = @bitCast(addr),
|
|
.port = std.mem.nativeToBig(u16, port),
|
|
},
|
|
};
|
|
}
|
|
|
|
pub fn initIp6(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) Address {
|
|
return .{
|
|
.in6 = .{
|
|
.addr = addr,
|
|
.port = std.mem.nativeToBig(u16, port),
|
|
.flowinfo = flowinfo,
|
|
.scope_id = scope_id,
|
|
},
|
|
};
|
|
}
|
|
|
|
pub fn initUnix(path: []const u8) !Address {
|
|
var un: linux.sockaddr.un = .{
|
|
.path = @splat(0),
|
|
};
|
|
|
|
// Ensure there is space for null terminator; already present by
|
|
// initializing the path to zeroes above.
|
|
if (path.len + 1 > un.path.len) return error.NameTooLong;
|
|
|
|
@memcpy(&un.path[0..path.len], path);
|
|
|
|
return .{ .un = un };
|
|
}
|
|
|
|
pub fn getOsSockLen(self: Address) linux.socklen_t {
|
|
return switch (self.any.family) {
|
|
linux.AF.INET => @sizeOf(linux.sockaddr.in),
|
|
linux.AF.INET6 => @sizeOf(linux.sockaddr.in6),
|
|
// NOTE According to zig's 0.15.2 stdlib, this is technically always
|
|
// correct especially since we ensure there is a space for a null
|
|
// terminator in init.
|
|
linux.AF.UNIX => @sizeOf(linux.sockaddr.un),
|
|
else => unreachable,
|
|
};
|
|
}
|
|
|
|
pub fn format(self: *const Address, writer: *std.Io.Writer) std.Io.Writer.Error!void {
|
|
switch (self.any.family) {
|
|
linux.AF.INET => {
|
|
const addr: std.Io.net.Ip4Address = .{
|
|
.bytes = @bitCast(self.in.addr),
|
|
.port = std.mem.bigToNative(u16, self.in.port),
|
|
};
|
|
|
|
try addr.format(writer);
|
|
},
|
|
linux.AF.INET6 => {
|
|
const addr: std.Io.net.Ip6Address.Unresolved = .{
|
|
.bytes = self.in6.addr,
|
|
.interface_name = null,
|
|
};
|
|
|
|
try addr.format(writer);
|
|
},
|
|
linux.AF.UNIX => {
|
|
try writer.writeAll(std.mem.sliceTo(&self.un.path, 0));
|
|
},
|
|
else => unreachable,
|
|
}
|
|
}
|
|
};
|