commit 3cffe29adb1fab6e4887a095fd2b48a086bb4d16
parent d11b0f794ec768acf0468440dba1f74f3311c486
Author: Mykyta Holubakha <hilobakho@gmail.com>
Date: Sun, 28 Mar 2021 19:42:56 +0300
net::ip: add conversion to rt::sockaddr
Diffstat:
5 files changed, 49 insertions(+), 38 deletions(-)
diff --git a/net/ip/+linux.ha b/net/ip/+linux.ha
@@ -0,0 +1,17 @@
+use rt;
+use endian;
+
+export fn to_native(a: addr, port: u16) rt::sockaddr = {
+ return match (a) {
+ v4: addr4 => rt::sockaddr { in = rt::sockaddr_in {
+ sin_family = rt::AF_INET,
+ sin_port = endian::htonu16(port),
+ sin_addr = rt::in_addr { s_addr = *(&v4[0]: *void: *u32) },
+ } },
+ v6: addr6 => rt::sockaddr { in6 = rt::sockaddr_in6 {
+ sin6_family = rt::AF_INET6,
+ sin6_port = endian::htonu16(port),
+ sin6_addr = rt::in6_addr { s6_addr = v6 },
+ } },
+ };
+};
diff --git a/net/ip/+test.ha b/net/ip/+test.ha
@@ -61,7 +61,7 @@ fn subnet_test_simple(s: str) void = {
a: subnet => a,
* => return,
};
- let fmted = stringsubnet(net);
+ let fmted = string(net);
assert(fmted == s);
let netrp = parsecidr(fmted);
assert(netrp is subnet);
diff --git a/net/ip/ip.ha b/net/ip/ip.ha
@@ -44,7 +44,7 @@ export fn equal(l: addr, r: addr) bool = {
};
};
-export fn parsev4(st: str) (addr4 | invalid) = {
+fn parsev4(st: str) (addr4 | invalid) = {
let ret: addr4 = [0...];
let tok = strings::tokenize(st, ".");
let i = 0z;
@@ -108,8 +108,9 @@ fn parsev6(st: str) (addr6 | invalid) = {
return invalid;
};
if (ells >= 0) {
- if (i >= 15)
+ if (i >= 15) {
return invalid;
+ };
rt::memcpy(
&ret[16 - (i - ells)],
&ret[ells], (i - ells): size);
@@ -134,7 +135,7 @@ export fn parse(s: str) (addr | invalid) = {
return invalid;
};
-fn fmtv4(a: addr4, s: *io::stream) (io::error | size) = {
+fn fmtv4(s: *io::stream, a: addr4) (io::error | size) = {
let ret = 0z;
for (let i = 0; i < 4; i += 1) {
if (i > 0) {
@@ -145,7 +146,7 @@ fn fmtv4(a: addr4, s: *io::stream) (io::error | size) = {
return ret;
};
-fn fmtv6(a: addr6, s: *io::stream) (io::error | size) = {
+fn fmtv6(s: *io::stream, a: addr6) (io::error | size) = {
let ret = 0z;
let zstart: int = -1;
let zend: int = -1;
@@ -182,25 +183,6 @@ fn fmtv6(a: addr6, s: *io::stream) (io::error | size) = {
return ret;
};
-// Formats an IP address
-export fn fmt(addr: addr, s: *io::stream) (io::error | size) = {
- return match (addr) {
- v4: addr4 => fmtv4(v4, s)?,
- v6: addr6 => fmtv6(v6, s)?,
- };
-};
-
-// Formats an [addr] as a string. The return value is statically
-// allocated and will be overwritten on subsequent calls; see
-// [strings::dup] to extend its lifetime.
-export fn string(addr: addr) str = {
- // Maximum length of an IPv6 address is 45 chars
- static let buf: [46]u8 = [0...];
- let stream = strio::fixed(buf);
- fmt(addr, stream) as size;
- return strio::string(stream);
-};
-
// Fills a netmask according to the CIDR value
// e.g. 23 -> [0xFF, 0xFF, 0xFD, 0x00]
fn fillmask(mask: []u8, val: u8) void = {
@@ -281,7 +263,7 @@ fn masklen(addr: []u8) (void | size) = {
return n;
};
-fn fmtmask(mask: addr, s: *io::stream) (io::error | size) = {
+fn fmtmask(s: *io::stream, mask: addr) (io::error | size) = {
let ret = 0z;
let slice = match (mask) {
v4: addr4 => v4[..],
@@ -301,23 +283,32 @@ fn fmtmask(mask: addr, s: *io::stream) (io::error | size) = {
return ret;
};
-// Format an IP subnet
-export fn fmtsubnet(subnet: subnet, s: *io::stream) (io::error | size) = {
+fn fmtsubnet(s: *io::stream, subnet: subnet) (io::error | size) = {
let ret = 0z;
- ret += fmt(subnet.addr, s)?;
+ ret += fmt(s, subnet.addr)?;
ret += fmt::fprintf(s, "/")?;
- ret += fmtmask(subnet.mask, s)?;
+ ret += fmtmask(s, subnet.mask)?;
return ret;
};
-// Formats a [subnet] as a string. The return value is statically
-// allocated and will be overwritten on subsequent calls; see
-// [strings::dup] to extend its lifetime.
-export fn stringsubnet(subnet: subnet) str = {
- static let buf: [66]u8 = [0...];
- let stream = strio::fixed(buf);
- fmtsubnet(subnet, stream) as size;
- return strio::string(stream);
+// Formats an [addr] or [subnet] and prints it to a stream.
+export fn fmt(s: *io::stream, item: (...addr | subnet)) (io::error | size) = {
+ return match (item) {
+ v4: addr4 => fmtv4(s, v4)?,
+ v6: addr6 => fmtv6(s, v6)?,
+ sub: subnet => fmtsubnet(s, sub),
+ };
+};
+
+// Formats an [addr] or [subnet] as a string. The return value is statically
+// allocated and will be overwritten on subsequent calls; see [strings::dup] to
+// extend its lifetime.
+export fn string(item: (...addr | subnet)) str = {
+ // Maximum length of an IPv6 address is 45 chars
+ static let buf: [46]u8 = [0...];
+ let stream = strio::fixed(buf);
+ fmt(stream, item) as size;
+ return strio::string(stream);
};
fn wanttoken(tok: *strings::tokenizer) (str | invalid) = {
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
@@ -397,6 +397,7 @@ linux_vdso() {
gensrcs_net_ip() {
gen_srcs net::ip \
ip.ha \
+ '$(PLATFORM).ha' \
$*
}
diff --git a/stdlib.mk b/stdlib.mk
@@ -504,7 +504,8 @@ $(HARECACHE)/linux/vdso/linux_vdso.ssa: $(stdlib_linux_vdso_srcs) $(stdlib_rt) $
# net::ip
stdlib_net_ip_srcs= \
- $(STDLIB)/net/ip/ip.ha
+ $(STDLIB)/net/ip/ip.ha \
+ $(STDLIB)/net/ip/$(PLATFORM).ha
$(HARECACHE)/net/ip/net_ip.ssa: $(stdlib_net_ip_srcs) $(stdlib_rt) $(stdlib_bytes) $(stdlib_io) $(stdlib_strconv) $(stdlib_strings) $(stdlib_strio)
@printf 'HAREC \t$@\n'
@@ -1216,6 +1217,7 @@ $(TESTCACHE)/linux/vdso/linux_vdso.ssa: $(testlib_linux_vdso_srcs) $(testlib_rt)
# net::ip
testlib_net_ip_srcs= \
$(STDLIB)/net/ip/ip.ha \
+ $(STDLIB)/net/ip/$(PLATFORM).ha \
$(STDLIB)/net/ip/+test.ha
$(TESTCACHE)/net/ip/net_ip.ssa: $(testlib_net_ip_srcs) $(testlib_rt) $(testlib_bytes) $(testlib_io) $(testlib_strconv) $(testlib_strings) $(testlib_strio)