[DTrace-devel] [PATCH v2] Add support for inet_ntop() subroutine
Eugene Loh
eugene.loh at oracle.com
Thu Sep 14 19:56:38 UTC 2023
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
libdtrace/dt_cg.c | 69 +++++++++++-
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, 184 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 372694d8..0c518953 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -5986,6 +5986,73 @@ 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)
+{
+ dt_node_t *af = dnp->dn_args;
+ dt_node_t *addr = af->dn_list;
+ dt_node_t *tnp, *cnp, *lnp, *rnp, *anp, *xnp;;
+ dt_idsig_t *isp;
+ dt_decl_t *ddp;
+
+ /*
+ * Implement this subroutine as a ternary expression:
+ *
+ * af == AF_INET6 ? inet_ntoa6((typ1)addr) : inet_ntoa((typ2)addr)
+ *
+ * where typ1 is the datatype of the argument of inet_ntoa6()
+ * typ2 is the datatype of the argument of inet_ntoa()
+ */
+ cnp = dt_node_op2(DT_TOK_EQU, af, dt_node_int(AF_INET6));
+
+ /* Create a node for the function call: inet_ntoa6(addr) */
+ lnp = dt_node_func(dt_node_ident(strdup("inet_ntoa6")), addr);
+
+ /* Get the datatype of the argument of inet_ntoa6(). */
+ assert(lnp->dn_ident && lnp->dn_ident->di_data);
+ isp = lnp->dn_ident->di_data;
+ assert(isp->dis_args);
+ anp = &isp->dis_args[0];
+ ddp = dt_decl_alloc(ctf_type_kind(anp->dn_ctfp, anp->dn_type), NULL);
+ ddp->dd_ctfp = anp->dn_ctfp;
+ ddp->dd_type = anp->dn_type;
+ xnp = dt_node_type(ddp); /* frees ddp */
+ /* Create a node to represent: (type)addr */
+ xnp = dt_node_op2(DT_TOK_LPAR, xnp, addr);
+
+ lnp->dn_args = xnp; /* inet_ntoa6((type)addr) */
+
+ /* Create a node for the function call: inet_ntoa(addr) */
+ rnp = dt_node_func(dt_node_ident(strdup("inet_ntoa")), addr);
+
+ /* Get the datatype of the argument of inet_ntoa(). */
+ assert(rnp->dn_ident && rnp->dn_ident->di_data);
+ isp = rnp->dn_ident->di_data;
+ assert(isp->dis_args);
+ anp = &isp->dis_args[0];
+ ddp = dt_decl_alloc(ctf_type_kind(anp->dn_ctfp, anp->dn_type), NULL);
+ ddp->dd_ctfp = anp->dn_ctfp;
+ ddp->dd_type = anp->dn_type;
+ xnp = dt_node_type(ddp); /* frees ddp */
+
+ xnp = dt_node_op2(DT_TOK_LPAR, xnp, addr); /* (type)addr */
+ rnp->dn_args = xnp; /* inet_ntoa((type)addr) */
+
+ tnp = dt_node_op3(cnp, lnp, rnp); /* cnp ? lnp : rnp */
+
+ /* Finalize the node tree and generate code. */
+ dt_node_cook(tnp, 0);
+ dt_cg_node(tnp, dlp, drp);
+
+ /*
+ * Copy the result into dnp (register value and tstring). We need to
+ * clear the tstring from tnp once we move it to dnp.
+ */
+ dnp->dn_reg = tnp->dn_reg;
+ dnp->dn_tstring = tnp->dn_tstring;
+ tnp->dn_tstring = NULL;
+}
+
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] = {
@@ -6030,7 +6097,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.40.1
More information about the DTrace-devel
mailing list