DTRACE_IP(4)

✨ DTRACE_IP(4) ✨ β€” the Kernel Interfaces Manual one, bestie πŸ’–

okay so. picture this: you're in the kernel, packets are flying everywhere, and you're just standing there like πŸ‘οΈπŸ‘„πŸ‘οΈ. enter dtrace_ip, aka the girl who tells you everything about IPv4 and IPv6 events. this is the manual page for it, rewritten with love and zero cap. let's go πŸ¦‹


🌸 NAME 🌸

dtrace_ip β€” a DTrace provider for tracing events related to the IPv4 and IPv6 protocols. yes she does both. versatile queen πŸ‘‘


πŸŽ€ SYNOPSIS πŸŽ€

ip:::receive(pktinfo_t *, csinfo_t *, ipinfo_t *, ifinfo_t *,
    ipv4info_t *, ipv6info_t *);

ip:::send(pktinfo_t *, csinfo_t *, ipinfo_t *, ifinfo_t *, ipv4info_t *,
    ipv6info_t *);

look at her. six arguments, no notes. πŸ’…


πŸ’« DESCRIPTION πŸ’«

the DTrace ip provider lets you trace events inside the ip(4) and ip6(4) protocol implementations. two probes, two moods:

  • ip:::send() fires whenever the kernel is about to transmit an IP packet. it's giving "outbox" πŸ“€
  • ip:::receive() fires whenever the kernel receives an IP packet. it's giving "inbox" πŸ“₯

the arguments to these probes let you pull detailed info about the IP headers of the packet in question, plus the network interface it was sent or received on. truly a full package.

now here's the plot twist πŸ‘€ β€” unlike the dtrace_tcp(4) and dtrace_udp(4) providers, ip provider probes get triggered by forwarded packets. meaning: these probes fire on packets that are not destined to the local host. not everything is about you, bestie, and that's the whole point. πŸ’€


🧚 ARGUMENTS 🧚

πŸ“ the pktinfo_t argument

currently unimplemented β€” she's here for compatibility with other implementations of this provider, and honestly? respect the hustle. her fields:

  • uintptr_t pkt_addr β€” always set to 0. every single time. iconic consistency.

πŸ“ the csinfo_t argument

also currently unimplemented, also just here for compatibility with other implementations of this provider. her fields:

  • uintptr_t cs_addr β€” always set to 0.
  • uint64_t cs_cid β€” a pointer to the struct inpcb for this packet, or NULL.
  • pid_t cs_pid β€” always set to 0.

🌈 the ipinfo_t argument

this one's the main character πŸ’– she holds the IP fields common to both IPv4 and IPv6 packets. her fields:

  • uint8_t ip_ver β€” IP version of the packet: 4 for IPv4 packets, 6 for IPv6 packets.
  • uint32_t ip_plength β€” IP payload size. heads up: this does not include the size of the IP header or IPv6 option headers.
  • string ip_saddr β€” IP source address.
  • string ip_daddr β€” IP destination address.

🌈 the ifinfo_t argument

describes the outgoing and incoming interfaces for the packet in the ip:::send() and ip:::receive() probes respectively. her fields:

  • string if_name β€” the interface name.
  • int8_t if_local β€” a boolean value indicating whether or not the interface is a loopback interface.
  • uintptr_t if_addr β€” a pointer to the struct ifnet which describes the interface. see the ifnet(9) manual page.

🌈 the ipv4info_t argument

contains the fields of the IP header for IPv4 packets. this argument is NULL for IPv6 packets. DTrace scripts should use the ip_ver() field in the ipinfo_t argument to determine whether to use this argument. her fields:

  • uint8_t ipv4_ver β€” IP version. this will always be 4 for IPv4 packets.
  • uint8_t ipv4_ihl β€” the IP header length, including options, in 32-bit words.
  • uint8_t ipv4_tos β€” IP type of service field.
  • uint16_t ipv4_length β€” the total packet length, including the header, in bytes.
  • uint16_t ipv4_ident β€” identification field.
  • uint8_t ipv4_flags β€” the IP flags.
  • uint16_t ipv4_offset β€” the fragment offset of the packet.
  • uint8_t ipv4_ttl β€” time to live field.
  • uint8_t ipv4_protocol β€” next-level protocol ID.
  • string ipv4_protostr β€” a string containing the name of the encapsulated protocol. the protocol strings are defined in the protocol array in /usr/lib/dtrace/ip.d.
  • uint16_t ipv4_checksum β€” the IP checksum.
  • ipaddr_t ipv4_src β€” IPv4 source address.
  • ipaddr_t ipv4_dst β€” IPv4 destination address.
  • string ipv4_saddr β€” a string representation of the source address.
  • string ipv4_daddr β€” a string representation of the destination address.
  • ipha_t *ipv4_hdr β€” a pointer to the raw IPv4 header.

🌈 the ipv6info_t argument

contains the fields of the IP header for IPv6 packets. her fields are not set for IPv4 packets; and just like with the ipv4info_t argument, you should use the ip_ver() field to figure out whether this argument is valid. her fields:

  • uint8_t ipv6_ver β€” IP version. this will always be 6 for IPv6 packets.
  • uint8_t ipv6_tclass β€” the traffic class, used to set the differentiated services codepoint and extended congestion notification flags.
  • uint32_t ipv6_flow β€” the flow label of the packet.
  • uint16_t ipv6_plen β€” the IP payload size, including extension headers, in bytes.
  • uint8_t ipv6_nexthdr β€” an identifier for the type of the next header.
  • string ipv6_nextstr β€” a string representation of the type of the next header.
  • uint8_t ipv6_hlim β€” the hop limit.
  • ip6_addr_t *ipv6_src β€” IPv6 source address.
  • ip6_addr_t *ipv6_dst β€” IPv6 destination address.
  • string ipv6_saddr β€” a string representation of the source address.
  • string ipv6_daddr β€” a string representation of the destination address.
  • struct ip6_hdr *ipv6_hdr β€” a pointer to the raw IPv6 header.

πŸ¦‹ FILES πŸ¦‹

  • /usr/lib/dtrace/ip.d β€” DTrace type and translator definitions for the ip provider. this file is doing the lord's work fr fr πŸ™

πŸ”₯ EXAMPLES πŸ”₯

example one: this script counts received packets by remote host address. so simple. so powerful. she ate.

ip:::receive
{
        @num[args[2]->ip_saddr] = count();
}

example two: this script prints some details of each IP packet as it's sent or received by the kernel. get you a script that does both πŸ’…

#pragma D option quiet
#pragma D option switchrate=10Hz

dtrace:::BEGIN
{
        printf(" %10s %30s    %-30s %8s %6s\n", "DELTA(us)", "SOURCE",
            "DEST", "INT", "BYTES");
        last = timestamp;
}

ip:::send
{
        this->elapsed = (timestamp - last) / 1000;
        printf(" %10d %30s -> %-30s %8s %6d\n", this->elapsed,
            args[2]->ip_saddr, args[2]->ip_daddr, args[3]->if_name,
            args[2]->ip_plength);
        last = timestamp;
}

ip:::receive
{
        this->elapsed = (timestamp - last) / 1000;
        printf(" %10d %30s <- %-30s %8s %6d\n", this->elapsed,
            args[2]->ip_daddr, args[2]->ip_saddr, args[3]->if_name,
            args[2]->ip_plength);
        last = timestamp;
}

πŸ’œ COMPATIBILITY πŸ’œ

this provider is compatible with the ip providers found in Solaris and Darwin. she gets along with everybody, no drama. 🀝


⭐ SEE ALSO ⭐

dtrace(1), dtrace_tcp(4), dtrace_udp(4), ip(4), ip6(4), ifnet(9), SDT(9)

go read those next, bestie, iykyk πŸ“š


🌟 HISTORY 🌟

the ip provider first appeared in FreeBSD 10.0. a true 2013-era legend. 🫢


πŸ‘‘ AUTHORS πŸ‘‘

this manual page was written by Mark Johnston <markj@FreeBSD.org>. thank you for your service, king 🫑


and that's the whole page!! this one came from the Debian crew and is dated September 14, 2015 β€” so yeah, it's been holding it down since before some of us could even read. mwah πŸ’‹ go trace some packets, you absolute icon. πŸŽ€βœ¨πŸ¦‹πŸ’–

πŸ“¦ where this page comes from