diff --git a/cddl/lib/libdtrace/Makefile b/cddl/lib/libdtrace/Makefile index ff1a220..bb7801d 100644 --- a/cddl/lib/libdtrace/Makefile +++ b/cddl/lib/libdtrace/Makefile @@ -51,6 +51,7 @@ DSRCS= errno.d \ ip.d \ psinfo.d \ signal.d \ + udp.d \ unistd.d WARNS?= 1 diff --git a/cddl/lib/libdtrace/ip.d b/cddl/lib/libdtrace/ip.d index c898397..48fcc10 100644 --- a/cddl/lib/libdtrace/ip.d +++ b/cddl/lib/libdtrace/ip.d @@ -170,6 +170,9 @@ inline short IPPROTO_SCTP = 132; #pragma D binding "1.0" IPPROTO_RAW inline short IPPROTO_RAW = 255; +inline uint8_t INP_IPV4 = 0x01; +inline uint8_t INP_IPV6 = 0x02; + #pragma D binding "1.0" protocols inline string protocols[int proto] = proto == IPPROTO_IP ? "IP" : diff --git a/cddl/lib/libdtrace/udp.d b/cddl/lib/libdtrace/udp.d new file mode 100644 index 0000000..9e24704 --- /dev/null +++ b/cddl/lib/libdtrace/udp.d @@ -0,0 +1,81 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + */ +/* + * Copyright (c) 2013 Mark Johnston + */ + +#pragma D depends_on library ip.d +#pragma D depends_on provider udp + +/* + * udpsinfo contains stable UDP details. + */ +typedef struct udpsinfo { + uintptr_t udps_addr; + uint16_t udps_lport; /* local port */ + uint16_t udps_rport; /* remote port */ + string udps_laddr; /* local address, as a string */ + string udps_raddr; /* remote address, as a string */ +} udpsinfo_t; + +/* + * udpinfo is the UDP header fields. + */ +typedef struct udpinfo { + uint16_t udp_sport; /* source port */ + uint16_t udp_dport; /* destination port */ + uint16_t udp_length; /* total length */ + uint16_t udp_checksum; /* headers + data checksum */ + struct udphdr *udp_hdr; /* raw UDP header */ +} udpinfo_t; + +/* The translator for struct mbuf * to ipinfo_t * is in ip.d. */ + +#pragma D binding "1.0" translator +translator udpsinfo_t < struct inpcb *p > { + udps_addr = (uintptr_t)p; + udps_lport = p == NULL ? 0 : ntohs(p->inp_inc.inc_ie.ie_lport); + udps_rport = p == NULL ? 0 : ntohs(p->inp_inc.inc_ie.ie_fport); + udps_laddr = p == NULL ? "" : + p->inp_vflag == INP_IPV4 ? + inet_ntoa(&p->inp_inc.inc_ie.ie_dependladdr.ie46_local.ia46_addr4.s_addr) : + p->inp_vflag == INP_IPV6 ? + inet_ntoa6(&p->inp_inc.inc_ie.ie_dependladdr.ie6_local) : + ""; + udps_raddr = p == NULL ? "" : + p->inp_vflag == INP_IPV4 ? + inet_ntoa(&p->inp_inc.inc_ie.ie_dependfaddr.ie46_foreign.ia46_addr4.s_addr) : + p->inp_vflag == INP_IPV6 ? + inet_ntoa6(&p->inp_inc.inc_ie.ie_dependfaddr.ie6_foreign) : + ""; +}; + +#pragma D binding "1.0" translator +translator udpinfo_t < struct udphdr *p > { + udp_sport = p == NULL ? 0 : ntohs(p->uh_sport); + udp_dport = p == NULL ? 0 : ntohs(p->uh_dport); + udp_length = p == NULL ? 0 : ntohs(p->uh_ulen); + udp_checksum = p == NULL ? 0 : ntohs(p->uh_sum); + udp_hdr = p; +}; diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/sdt_subr.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/sdt_subr.c index ef938d4..a1fc2b1 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/sdt_subr.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/sdt_subr.c @@ -92,6 +92,7 @@ sdt_provider_t sdt_providers[] = { { "proc", "__proc_", &stab_attr, 0 }, { "io", "__io_", &stab_attr, 0 }, { "ip", "__ip_", &stab_attr, 0 }, + { "udp", "__udp_", &stab_attr, 0 }, { "mib", "__mib_", &stab_attr, 0 }, { "fsinfo", "__fsinfo_", &fsinfo_attr, 0 }, { "nfsv3", "__nfsv3_", &stab_attr, 0 }, @@ -801,6 +802,16 @@ sdt_argdesc_t sdt_args[] = { { "ip", "receive", 3, 3, "struct ifnet *", "ifinfo_t *" }, { "ip", "receive", 4, 4, "struct ip *", "ipv4info_t *" }, { "ip", "receive", 5, 5, "struct ip6_hdr *", "ipv6info_t *" }, + { "udp", "send", 0, 0, "void *", "void *" }, + { "udp", "send", 1, 1, "void *", "void *" }, + { "udp", "send", 2, 2, "struct mbuf *", "ipinfo_t *" }, + { "udp", "send", 3, 3, "struct inpcb *", "udpsinfo_t *" }, + { "udp", "send", 4, 4, "struct udphdr *", "udpinfo_t *" }, + { "udp", "receive", 0, 0, "void *", "void *" }, + { "udp", "receive", 1, 1, "void *", "void *" }, + { "udp", "receive", 2, 2, "struct mbuf *", "ipinfo_t *" }, + { "udp", "receive", 3, 3, "struct inpcb *", "udpsinfo_t *" }, + { "udp", "receive", 4, 4, "struct udphdr *", "udpinfo_t *" }, { "sysevent", "post", 0, 0, "evch_bind_t *", "syseventchaninfo_t *" }, { "sysevent", "post", 1, 1, "sysevent_impl_t *", "syseventinfo_t *" }, diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index b6297dc..597f77f 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" +#include "opt_kdtrace.h" #include #include @@ -54,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -163,6 +165,13 @@ static struct mbuf *udp4_espdecap(struct inpcb *, struct mbuf *, int); #endif /* IPSEC_NAT_T */ #endif /* IPSEC */ +SDT_PROVIDER_DEFINE(udp); + +SDT_PROBE_DEFINE5(udp, , , send, send, "void *", "void *", "struct mbuf *", + "struct inpcb *", "struct udphdr *"); +SDT_PROBE_DEFINE5(udp, , , receive, receive, "void *", "void *", + "struct mbuf *", "struct inpcb *", "struct udphdr *"); + static void udp_zone_change(void *tag) { @@ -370,6 +379,8 @@ udp_input(struct mbuf *m, int off) } uh = (struct udphdr *)((caddr_t)ip + iphlen); + SDT_PROBE5(udp, , , receive, 0, ip, m, ip, uh); + /* * Destination port of 0 is illegal, based on RFC768. */ @@ -1190,6 +1201,7 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, */ ui = mtod(m, struct udpiphdr *); bzero(ui->ui_x1, sizeof(ui->ui_x1)); /* XXX still needed? */ + ui->ui_v = IPVERSION << 4; ui->ui_pr = IPPROTO_UDP; ui->ui_src = laddr; ui->ui_dst = faddr; @@ -1240,6 +1252,7 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, INP_HASH_WUNLOCK(&V_udbinfo); else if (unlock_udbinfo == UH_RLOCKED) INP_HASH_RUNLOCK(&V_udbinfo); + SDT_PROBE5(udp, , , send, 0, inp, m, inp, &ui->ui_u); error = ip_output(m, inp->inp_options, NULL, ipflags, inp->inp_moptions, inp); if (unlock_udbinfo == UH_WLOCKED) diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h index e4a6668..683affe 100644 --- a/sys/netinet/udp_var.h +++ b/sys/netinet/udp_var.h @@ -42,6 +42,7 @@ struct udpiphdr { struct udphdr ui_u; /* udp header */ }; #define ui_x1 ui_i.ih_x1 +#define ui_v ui_i.ih_x1[0] #define ui_pr ui_i.ih_pr #define ui_len ui_i.ih_len #define ui_src ui_i.ih_src diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 200fd68..79df47b 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet6.h" #include "opt_ipfw.h" #include "opt_ipsec.h" +#include "opt_kdtrace.h" #include #include @@ -82,6 +83,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -120,6 +122,11 @@ __FBSDID("$FreeBSD$"); #include +SDT_PROVIDER_DECLARE(udp); + +SDT_PROBE_DECLARE(udp, , , receive); +SDT_PROBE_DECLARE(udp, , , send); + /* * UDP protocol implementation. * Per RFC 768, August, 1980. @@ -377,6 +384,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) INP_RLOCK(last); INP_INFO_RUNLOCK(&V_udbinfo); up = intoudpcb(last); + SDT_PROBE5(udp, , , receive, 0, last, m, last, uh); if (up->u_tun_func == NULL) { udp6_append(last, m, off, &fromsa); } else { @@ -455,6 +463,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) } INP_RLOCK_ASSERT(inp); up = intoudpcb(inp); + SDT_PROBE5(udp, , , receive, 0, inp, m, inp, uh); if (up->u_tun_func == NULL) { udp6_append(inp, m, off, &fromsa); } else { @@ -785,6 +794,7 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6, flags = 0; + SDT_PROBE5(udp, , , send, 0, inp, m, inp, udp6); UDPSTAT_INC(udps_opackets); error = ip6_output(m, optp, NULL, flags, inp->in6p_moptions, NULL, inp);