> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/man/man4/dtrace_ip.4.md).

# dtrace\_ip.4

`dtrace_ip` — 用于跟踪 IPv4 和 IPv6 协议相关事件的 DTrace 提供者

## 名称

`dtrace_ip`

## 概要

`Fn ip:::receive pktinfo_t * csinfo_t * ipinfo_t * ifinfo_t * \ "ipv4info_t *" "ipv6info_t *" Fn ip:::send pktinfo_t * csinfo_t * ipinfo_t * ifinfo_t * \ "ipv4info_t *" "ipv6info_t *"`

## 描述

DTrace `ip` 提供者允许用户跟踪 [ip(4)](/man/man4/ip.4.md) 和 [ip6(4)](/man/man4/ip6.4.md) 协议实现中的事件。Fn ip:::send 探测在内核准备传输 IP 数据包时触发，Fn ip:::receive 探测在内核接收 IP 数据包时触发。这些探测的参数可用于获取相应数据包 IP 头的详细信息，以及发送或接收数据包的网络接口。与 [dtrace\_tcp(4)](/man/man4/dtrace_tcp.4.md) 和 [dtrace\_udp(4)](/man/man4/dtrace_udp.4.md) 提供者不同，`ip` 提供者的探测由转发的数据包触发。也就是说，探测将在非发往本地主机的数据包上触发。

## 参数

`pktinfo_t` 参数目前未实现，仅为与此提供者的其他实现兼容而包含。其字段为：

**`uintptr_t pkt_addr`** 始终设置为 0。

`csinfo_t` 参数目前未实现，仅为与此提供者的其他实现兼容而包含。其字段为：

**`uintptr_t cs_addr`** 始终设置为 0。

**`uint64_t cs_cid`** 指向此数据包的 `struct inpcb` 的指针，或 `NULL`。

**`pid_t cs_pid`** 始终设置为 0。

`ipinfo_t` 参数包含 IPv4 和 IPv6 数据包共有的 IP 字段。其字段为：

**`uint8_t ip_ver`** 数据包的 IP 版本，IPv4 数据包为 4，IPv6 数据包为 6。

**`uint32_t ip_plength`** IP 负载大小。不包括 IP 头或 IPv6 选项头的大小。

**`string ip_saddr`** IP 源地址。

**`string ip_daddr`** IP 目标地址。

`ifinfo_t` 参数分别描述 Fn ip:::send 和 Fn ip:::receive 探测中数据包的传出和传入接口。其字段为：

**`string if_name`** 接口名称。

**`int8_t if_local`** 指示接口是否为环回接口的布尔值。

**`uintptr_t if_addr`** 指向描述该接口的 `struct ifnet` 的指针。参见 [ifnet(9)](/man/man9/ifnet.9.md) 手册页。

`ipv4info_t` 参数包含 IPv4 数据包 IP 头的字段。对于 IPv6 数据包，此参数为 `NULL`。DTrace 脚本应使用 `ipinfo_t` 参数中的 Fn ip\_ver 字段来确定是否使用此参数。其字段为：

**`uint8_t ipv4_ver`** IP 版本。对于 IPv4 数据包始终为 4。

**`uint8_t ipv4_ihl`** IP 头长度，包括选项，以 32 位字为单位。

**`uint8_t ipv4_tos`** IP 服务类型字段。

**`uint16_t ipv4_length`** 数据包总长度，包括头，以字节为单位。

**`uint16_t ipv4_ident`** 标识字段。

**`uint8_t ipv4_flags`** IP 标志。

**`uint16_t ipv4_offset`** 数据包的分片偏移量。

**`uint8_t ipv4_ttl`** 生存时间字段。

**`uint8_t ipv4_protocol`** 下一层协议 ID。

**`string ipv4_protostr`** 包含封装协议名称的字符串。协议字符串定义在 **/usr/lib/dtrace/ip.d** 中的 `protocol` 数组中

**`uint16_t ipv4_checksum`** IP 校验和。

**`ipaddr_t ipv4_src`** IPv4 源地址。

**`ipaddr_t ipv4_dst`** IPv4 目标地址。

**`string ipv4_saddr`** 源地址的字符串表示。

**`string ipv4_daddr`** 目标地址的字符串表示。

**`ipha_t *ipv4_hdr`** 指向原始 IPv4 头的指针。

`ipv6info_t` 参数包含 IPv6 数据包 IP 头的字段。对于 IPv4 数据包其字段未设置；与 `ipv4info_t` 参数一样，应使用 Fn ip\_ver 字段确定此参数是否有效。其字段为：

**`uint8_t ipv6_ver`** IP 版本。对于 IPv6 数据包始终为 6。

**`uint8_t ipv6_tclass`** 流量类别，用于设置差异化服务代码点和扩展拥塞通知标志。

**`uint32_t ipv6_flow`** 数据包的流标签。

**`uint16_t ipv6_plen`** IP 负载大小，包括扩展头，以字节为单位。

**`uint8_t ipv6_nexthdr`** 下一头类型的标识符。

**`string ipv6_nextstr`** 下一头类型的字符串表示。

**`uint8_t ipv6_hlim`** 跳数限制。

**`ip6_addr_t *ipv6_src`** IPv6 源地址。

**`ip6_addr_t *ipv6_dst`** IPv6 目标地址。

**`string ipv6_saddr`** 源地址的字符串表示。

**`string ipv6_daddr`** 目标地址的字符串表示。

**`struct ip6_hdr *ipv6_hdr`** 指向原始 IPv6 头的指针。

## 文件

**`/usr/lib/dtrace/ip.d`** `ip` 提供者的 DTrace 类型和转换器定义。

## 实例

以下脚本按远程主机地址统计接收的数据包。

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

此脚本将打印内核发送或接收的每个 IP 数据包的一些详细信息：

```sh
#pragma D option quiet
#pragma D option switchrate=10Hz
dtrace:::BEGIN
{
        printf(" %10s %30s    %-30s %8s %6sn", "DELTA(us)", "SOURCE",
            "DEST", "INT", "BYTES");
        last = timestamp;
}
ip:::send
{
        this->elapsed = (timestamp - last) / 1000;
        printf(" %10d %30s -> %-30s %8s %6dn", 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 %6dn", this->elapsed,
            args[2]->ip_daddr, args[2]->ip_saddr, args[3]->if_name,
            args[2]->ip_plength);
        last = timestamp;
}
```

## 兼容性

此提供者与 Solaris 和 Darwin 中的 `ip` 提供者兼容。

## 参见

[dtrace(1)](/man/man1/dtrace.1.md), [dtrace\_mib(4)](/man/man4/dtrace_mib.4.md), [dtrace\_tcp(4)](/man/man4/dtrace_tcp.4.md), [dtrace\_udp(4)](/man/man4/dtrace_udp.4.md), [ip(4)](/man/man4/ip.4.md), [ip6(4)](/man/man4/ip6.4.md), [ifnet(9)](/man/man9/ifnet.9.md), [SDT(9)](https://github.com/FreeBSD-Ask/freebsd-man-sc/tree/main/man9/sdt.9.md)

## 历史

`ip` 提供者首次出现于 FreeBSD 10.0。

## 作者

本手册页由 Mark Johnston <markj@FreeBSD.org> 编写。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/man/man4/dtrace_ip.4.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
