[DTrace-devel] [PATCH 2/2] Add support for inet_ntop() subroutine
eugene.loh at oracle.com
eugene.loh at oracle.com
Mon Aug 28 19:08:00 UTC 2023
From: Eugene Loh <eugene.loh at oracle.com>
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
libdtrace/dt_cg.c | 85 +++++++++++++-
test/unittest/funcs/tst.inet_ntop.d | 1 -
.../unittest/funcs/tst.inet_ntop_runtime_af.d | 104 ++++++++++++++++++
.../unittest/funcs/tst.inet_ntop_runtime_af.r | 12 ++
4 files changed, 200 insertions(+), 2 deletions(-)
create mode 100644 test/unittest/funcs/tst.inet_ntop_runtime_af.d
create mode 100644 test/unittest/funcs/tst.inet_ntop_runtime_af.r
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index afd272d7..bb73efd7 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -5956,6 +5956,89 @@ dt_cg_subr_inet_ntoa6(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
DT_ISIMM, tbloff);
}
+static void
+dt_cg_subr_inet_ntop(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_node_t *af = dnp->dn_args;
+ dt_node_t *addr = af->dn_list;
+ uint_t Lipv6 = dt_irlist_label(dlp);
+ uint_t Ldone = dt_irlist_label(dlp);
+ uint64_t tstring_offset;
+
+ /* Determine address family af. */
+ dt_cg_node(af, dlp, drp);
+
+ /* Move addr into dnp->dn_args so we can call inet_ntoa[6]. */
+ dnp->dn_args = addr;
+
+ /* Execute a runtime branch depending on af. */
+ emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, af->dn_reg, AF_INET6, Lipv6));
+
+ /*
+ * The code generator needs to know where the results will be.
+ * So allocate somewhere for the results. Each runtime branch
+ * will copy to this location.
+ */
+ tstring_offset = dt_cg_tstring_xalloc(yypcb);
+
+ /* The ipv4 case. */
+ dt_cg_subr_inet_ntoa(dnp, dlp, drp);
+
+ /* Copy the results out. */
+ if (dt_regset_xalloc_args(drp) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ emit(dlp, BPF_MOV_REG(BPF_REG_3, dnp->dn_reg));
+ emit(dlp, BPF_MOV_IMM(BPF_REG_2, dtp->dt_options[DTRACEOPT_STRSIZE]));
+ emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_FP, DT_STK_DCTX));
+ emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_1, DCTX_MEM));
+ emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, tstring_offset));
+ dt_regset_xalloc(drp, BPF_REG_0);
+ emit(dlp, BPF_CALL_HELPER(dtp->dt_bpfhelper[BPF_FUNC_probe_read_kernel]));
+ dt_regset_free(drp, BPF_REG_0);
+ dt_regset_free_args(drp);
+
+ /* Free resources. */
+ dt_regset_free(drp, dnp->dn_reg);
+ dt_cg_tstring_free(yypcb, dnp); // FIXME but dnp->dn_tstring is still there?
+
+ /* Jump to end. */
+ emit(dlp, BPF_JUMP(Ldone));
+
+ /* The ipv6 case. */
+ emitl(dlp, Lipv6,
+ BPF_NOP());
+ dt_cg_subr_inet_ntoa6(dnp, dlp, drp);
+
+ /* Copy the results out. */
+ if (dt_regset_xalloc_args(drp) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ emit(dlp, BPF_MOV_REG(BPF_REG_3, dnp->dn_reg));
+ emit(dlp, BPF_MOV_IMM(BPF_REG_2, dtp->dt_options[DTRACEOPT_STRSIZE]));
+ emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_FP, DT_STK_DCTX));
+ emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_1, DCTX_MEM));
+ emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, tstring_offset));
+ dt_regset_xalloc(drp, BPF_REG_0);
+ emit(dlp, BPF_CALL_HELPER(dtp->dt_bpfhelper[BPF_FUNC_probe_read_kernel]));
+ dt_regset_free(drp, BPF_REG_0);
+ dt_regset_free_args(drp);
+
+ /* Free resources. */
+ dt_regset_free(drp, dnp->dn_reg);
+ dt_cg_tstring_free(yypcb, dnp); // FIXME but dnp->dn_tstring is still there?
+
+ /* Done with both branches. Save the results to dnp. */
+ emitl(dlp, Ldone,
+ BPF_NOP());
+
+ /* We still have af->dn_reg, so use it for dnp. */
+ dnp->dn_reg = af->dn_reg;
+ dnp->dn_tstring->dn_value = tstring_offset;
+ emit(dlp, BPF_LOAD(BPF_DW, dnp->dn_reg, BPF_REG_FP, DT_STK_DCTX));
+ emit(dlp, BPF_LOAD(BPF_DW, dnp->dn_reg, dnp->dn_reg, DCTX_MEM));
+ emit(dlp, BPF_ALU64_IMM(BPF_ADD, dnp->dn_reg, tstring_offset));
+}
+
typedef void dt_cg_subr_f(dt_node_t *, dt_irlist_t *, dt_regset_t *);
static dt_cg_subr_f *_dt_cg_subr[DIF_SUBR_MAX + 1] = {
@@ -6000,7 +6083,7 @@ static dt_cg_subr_f *_dt_cg_subr[DIF_SUBR_MAX + 1] = {
[DIF_SUBR_NTOHS] = &dt_cg_subr_htons,
[DIF_SUBR_NTOHL] = &dt_cg_subr_htonl,
[DIF_SUBR_NTOHLL] = &dt_cg_subr_htonll,
- [DIF_SUBR_INET_NTOP] = NULL,
+ [DIF_SUBR_INET_NTOP] = &dt_cg_subr_inet_ntop,
[DIF_SUBR_INET_NTOA] = &dt_cg_subr_inet_ntoa,
[DIF_SUBR_INET_NTOA6] = &dt_cg_subr_inet_ntoa6,
[DIF_SUBR_D_PATH] = NULL,
diff --git a/test/unittest/funcs/tst.inet_ntop.d b/test/unittest/funcs/tst.inet_ntop.d
index 234effb2..e2f00356 100644
--- a/test/unittest/funcs/tst.inet_ntop.d
+++ b/test/unittest/funcs/tst.inet_ntop.d
@@ -4,7 +4,6 @@
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
-/* @@xfail: dtv2 */
#pragma D option quiet
diff --git a/test/unittest/funcs/tst.inet_ntop_runtime_af.d b/test/unittest/funcs/tst.inet_ntop_runtime_af.d
new file mode 100644
index 00000000..7843a4ea
--- /dev/null
+++ b/test/unittest/funcs/tst.inet_ntop_runtime_af.d
@@ -0,0 +1,104 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Licensed under the Universal Permissive License v 1.0 as shown at
+ * http://oss.oracle.com/licenses/upl.
+ */
+
+/*
+ * Check that inet_ntop(af, addr) works even if af is not known until runtime.
+ */
+
+#pragma D option quiet
+
+ipaddr_t *ip4a;
+ipaddr_t *ip4b;
+ipaddr_t *ip4c;
+ipaddr_t *ip4d;
+struct in6_addr *ip6a;
+struct in6_addr *ip6b;
+struct in6_addr *ip6c;
+struct in6_addr *ip6d;
+struct in6_addr *ip6e;
+struct in6_addr *ip6f;
+struct in6_addr *ip6g;
+
+BEGIN
+{
+ this->buf4a = alloca(sizeof(ipaddr_t));
+ this->buf4b = alloca(sizeof(ipaddr_t));
+ this->buf4c = alloca(sizeof(ipaddr_t));
+ this->buf4d = alloca(sizeof(ipaddr_t));
+ this->buf6a = alloca(sizeof(struct in6_addr));
+ this->buf6b = alloca(sizeof(struct in6_addr));
+ this->buf6c = alloca(sizeof(struct in6_addr));
+ this->buf6d = alloca(sizeof(struct in6_addr));
+ this->buf6e = alloca(sizeof(struct in6_addr));
+ this->buf6f = alloca(sizeof(struct in6_addr));
+ this->buf6g = alloca(sizeof(struct in6_addr));
+ ip4a = this->buf4a;
+ ip4b = this->buf4b;
+ ip4c = this->buf4c;
+ ip4d = this->buf4d;
+ ip6a = this->buf6a;
+ ip6b = this->buf6b;
+ ip6c = this->buf6c;
+ ip6d = this->buf6d;
+ ip6e = this->buf6e;
+ ip6f = this->buf6f;
+ ip6g = this->buf6g;
+
+ *ip4a = htonl(0xc0a80117);
+ *ip4b = htonl(0x7f000001);
+ *ip4c = htonl(0xffffffff);
+ *ip4d = htonl(0x00000000);
+
+ ip6a->in6_u.u6_addr8[0] = 0xfe;
+ ip6a->in6_u.u6_addr8[1] = 0x80;
+ ip6a->in6_u.u6_addr8[8] = 0x02;
+ ip6a->in6_u.u6_addr8[9] = 0x14;
+ ip6a->in6_u.u6_addr8[10] = 0x4f;
+ ip6a->in6_u.u6_addr8[11] = 0xff;
+ ip6a->in6_u.u6_addr8[12] = 0xfe;
+ ip6a->in6_u.u6_addr8[13] = 0x0b;
+ ip6a->in6_u.u6_addr8[14] = 0x76;
+ ip6a->in6_u.u6_addr8[15] = 0xc8;
+ ip6b->in6_u.u6_addr8[0] = 0x10;
+ ip6b->in6_u.u6_addr8[1] = 0x80;
+ ip6b->in6_u.u6_addr8[10] = 0x08;
+ ip6b->in6_u.u6_addr8[11] = 0x08;
+ ip6b->in6_u.u6_addr8[13] = 0x20;
+ ip6b->in6_u.u6_addr8[13] = 0x0c;
+ ip6b->in6_u.u6_addr8[14] = 0x41;
+ ip6b->in6_u.u6_addr8[15] = 0x7a;
+ ip6c->in6_u.u6_addr8[15] = 0x01;
+ ip6e->in6_u.u6_addr8[12] = 0x7f;
+ ip6e->in6_u.u6_addr8[15] = 0x01;
+ ip6f->in6_u.u6_addr8[10] = 0xff;
+ ip6f->in6_u.u6_addr8[11] = 0xff;
+ ip6f->in6_u.u6_addr8[12] = 0x7f;
+ ip6f->in6_u.u6_addr8[15] = 0x01;
+ ip6g->in6_u.u6_addr8[10] = 0xff;
+ ip6g->in6_u.u6_addr8[11] = 0xfe;
+ ip6g->in6_u.u6_addr8[12] = 0x7f;
+ ip6g->in6_u.u6_addr8[15] = 0x01;
+
+ v = 4;
+ af = (v == 4 ? AF_INET : (v == 6 ? AF_INET6 : -1));
+ printf("%s\n", inet_ntop(af, ip4a));
+ printf("%s\n", inet_ntop(af, ip4b));
+ printf("%s\n", inet_ntop(af, ip4c));
+ printf("%s\n", inet_ntop(af, ip4d));
+
+ v = 6;
+ af = (v == 4 ? AF_INET : (v == 6 ? AF_INET6 : -1));
+ printf("%s\n", inet_ntop(af, ip6a));
+ printf("%s\n", inet_ntop(af, ip6b));
+ printf("%s\n", inet_ntop(af, ip6c));
+ printf("%s\n", inet_ntop(af, ip6d));
+ printf("%s\n", inet_ntop(af, ip6e));
+ printf("%s\n", inet_ntop(af, ip6f));
+ printf("%s\n", inet_ntop(af, ip6g));
+
+ exit(0);
+}
diff --git a/test/unittest/funcs/tst.inet_ntop_runtime_af.r b/test/unittest/funcs/tst.inet_ntop_runtime_af.r
new file mode 100644
index 00000000..913eff77
--- /dev/null
+++ b/test/unittest/funcs/tst.inet_ntop_runtime_af.r
@@ -0,0 +1,12 @@
+192.168.1.23
+127.0.0.1
+255.255.255.255
+0.0.0.0
+fe80::214:4fff:fe0b:76c8
+1080::808:c:417a
+::1
+::
+127.0.0.1
+127.0.0.1
+::fffe:7f00:1
+
--
2.18.4
More information about the DTrace-devel
mailing list