[DTrace-devel] [PATCH 2/2] Support two representations for embedded IPv4 addresses

Kris Van Hees kris.van.hees at oracle.com
Fri Sep 15 20:27:47 UTC 2023


DTrace's inet_ntoa6() represents mapped and embedded IPv4 address
using the regular IPv4 representation, whereas inet_ntop() uses a
representation with a :: prefix followed by a regular IPv4 address.

The implementation uses an undocumented 2nd argument to inet_ntoa6()
to indicate whether prefix format should be generated or not.

Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 bpf/inet_ntoa6.S    | 33 +++++++++++++++++++++++++++++----
 libdtrace/dt_cg.c   | 10 ++++++----
 libdtrace/dt_open.c |  2 +-
 3 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/bpf/inet_ntoa6.S b/bpf/inet_ntoa6.S
index 3995b92a..878eb860 100644
--- a/bpf/inet_ntoa6.S
+++ b/bpf/inet_ntoa6.S
@@ -94,7 +94,7 @@ write_hex16:
 
 /*
  * void inet_ntoa6(const dt_dctx_t *dctx, const uint8_t *src, char *dst,
- *		   uint32 tbloff)
+ *		   uint32 tbloff, int is_ntop)
  */
 	.align	4
 	.global	dt_inet_ntoa6
@@ -121,6 +121,7 @@ dt_inet_ntoa6:
 	add	%r8, OUTPUT_LEN		/* %r8 = converted copy */
 	mov	%r6, %r1		/* %r6 = dctx */
 	stxw	[%fp + -4], %r4		/* store tbloff */
+	stxw	[%fp + -8], %r5		/* store is_ntop */
 
 	mov	%r3, %r2
 	mov	%r2, INPUT_LEN
@@ -198,12 +199,12 @@ dt_inet_ntoa6:
 	and	%r0, 0xf8
 	jne	%r0, 0, .Lnotipv4
 	ldxh	%r0, [%r8 + 10]
-	jeq	%r0, 0xffff, .Lipv4
+	jeq	%r0, 0xffff, .Lipv4_2
 	jne	%r0, 0, .Lnotipv4
 	ldxh	%r0, [%r8 + 12]
-	jne	%r0, 0, .Lipv4
+	jne	%r0, 0, .Lipv4_1
 	ldxh	%r0, [%r8 + 14]
-	jgt	%r0, 1, .Lipv4
+	jgt	%r0, 1, .Lipv4_1
 .Lnotipv4:
 
 	/*
@@ -335,6 +336,30 @@ dt_inet_ntoa6:
 	mov	%r0, 0
 	exit
 
+.Lipv4_1:
+	/* Output IPv4 address prefixed by :: (if is_ntop is set). */
+	ldxw	%r0, [%fp + -8]		/* restore is_ntop */
+	jeq	%r0, 0, .Lipv4
+	stb	[%r9 + 0], ':'
+	stb	[%r9 + 1], ':'
+	add	%r9, 2
+	ja	.Lipv4
+
+.Lipv4_2:
+	/* Output IPv4 address prefixed by ::ffff: (if is_ntop is set). */
+	ldxw	%r0, [%fp + -8]		/* restore is_ntop */
+	jeq	%r0, 0, .Lipv4
+	stb	[%r9 + 0], ':'
+	stb	[%r9 + 1], ':'
+	add	%r9, 2
+	mov	%r1, -1
+	mov	%r2, %r9
+	call	write_hex16
+	add	%r9, %r0
+	stb	[%r9 + 0], ':'
+	add	%r9, 1
+	ja	.Lipv4
+
 .Lipv4:
 	/* Output the last two words as an IPv4 address and return. */
 	mov	%r1, %r6
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index 56b59260..6c03a97f 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -5941,6 +5941,8 @@ static void
 dt_cg_subr_inet_ntoa6(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
 {
 	dtrace_hdl_t	*dtp = yypcb->pcb_hdl;
+	dt_node_t	*addr = dnp->dn_args;
+	dt_node_t	*flag = addr->dn_list;
 	ssize_t		tbloff;
 	/*
 	 * This table encodes the start and length of the longest run of 0 bits
@@ -5993,7 +5995,7 @@ dt_cg_subr_inet_ntoa6(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
 		longjmp(yypcb->pcb_jmpbuf, EDT_STR2BIG);
 
 	dt_cg_subr_arg_to_tstring(dnp, dlp, drp, "dt_inet_ntoa6",
-				  DT_ISIMM, tbloff, DT_IGNOR, 0);
+				  DT_ISIMM, tbloff, DT_ISIMM, flag ? 1 : 0);
 }
 
 static void
@@ -6027,8 +6029,9 @@ dt_cg_subr_inet_ntop(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
 	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);
+	xnp = dt_node_op2(DT_TOK_LPAR, xnp, addr); /* (type)addr */
+	xnp->dn_list = dt_node_int(1);
+
 	lnp->dn_args = xnp;			/* inet_ntoa6((type)addr) */
 
 	/* Create a node for the function call: inet_ntoa(addr) */
@@ -6043,7 +6046,6 @@ dt_cg_subr_inet_ntop(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
 	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) */
 
diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
index 2db8ec38..31cc2e54 100644
--- a/libdtrace/dt_open.c
+++ b/libdtrace/dt_open.c
@@ -202,7 +202,7 @@ static const dt_ident_t _dtrace_globals[] = {
 { "inet_ntoa", DT_IDENT_FUNC, DT_IDFLG_DPTR, DIF_SUBR_INET_NTOA, DT_ATTR_STABCMN,
 	DT_VERS_1_5, &dt_idops_func, "string(void *)" }, /* FIXME should be ipaddr_t* */
 { "inet_ntoa6", DT_IDENT_FUNC, DT_IDFLG_DPTR, DIF_SUBR_INET_NTOA6, DT_ATTR_STABCMN,
-	DT_VERS_1_5, &dt_idops_func, "string(struct in6_addr *)" },
+	DT_VERS_1_5, &dt_idops_func, "string(struct in6_addr *, [int])" },
 { "inet_ntop", DT_IDENT_FUNC, DT_IDFLG_DPTR, DIF_SUBR_INET_NTOP, DT_ATTR_STABCMN,
 	DT_VERS_1_5, &dt_idops_func, "string(int, void *)" },
 { "ipl", DT_IDENT_SCALAR, 0, DIF_VAR_IPL, DT_ATTR_STABCMN, DT_VERS_1_0,
-- 
2.40.1




More information about the DTrace-devel mailing list