> 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/4.3-bsd-unix-cao-zuo-xi-tong-she-ji-yu-shi-xian/di-si-bu-fen-jin-cheng-jian-tong-xin/12.10.-shi-le-wang-luo-xi-tong-tong-xin-yu.md).

# 12.10 施乐网络系统通信域（XNS）

施乐网络系统（Xerox Network Systems，NS）通信域支持三个通信协议。*IDP* 是网际数据报协议（Internetwork Datagram Protocol），构成 NS 体系结构 1 级传输协议的基础，负责网际分组格式、网际编址和路由。*顺序分组协议*（Sequenced Packet Protocol，SPP）是叠在 IDP 之上的 2 级传输协议，提供可靠、不重复、有流控的消息传输。第三个是 *错误协议*（Error Protocol），报告错误；它既用作诊断工具，也用作改进性能的手段，通常不供用户访问。

SPP 用来支持 NS 域中创建的流套接字和顺序分组套接字。标准数据报服务称为分组交换（Packet Exchange，PEX），由一个使用 IDP 数据报套接字的用户级库实现。经 **裸套接字** 可以直接访问错误协议和 IDP 协议。

每个基于 SPP 或 IDP 的套接字创建一个 NS 协议控制块，装与 Internet 协议控制块中类似的 NS 信息。与 TCP 一样，SPP 另外创建一个 SPP 控制块，装实现所需的协议状态信息。与 Internet 域不同，NS 域全部协议的 NS 协议控制块维护在 **一条** 双向链表上：NS 域中，网络协议级的分组多路分解先按网络地址和端口号、再按通信协议进行。套接字数据结构与协议专有数据结构之间的链接与 Internet 通信域中的完全相同。

NS 与 Internet 协议的实现相似。于是，理解一个协议族的数据结构、组织和算法，另一个就好懂得多。

SPP 协议输出例程用如下约定：

```c
error = spp_output(spcb, m);
    struct sppcb *spcb;
    struct mbuf *m;
```

其中 `spcb` 是 SPP 协议控制块，`m` 是装待发数据的 mbuf 链。

IDP 协议用类似约定：

```c
error = idp_output(nsp, m);
    struct nspcb *nsp;
    struct mbuf *m;
```

只是换用 NS 协议控制块。SPP 和 IDP 都把分组交给做分组传输的公共 NS 模块：

```c
error = ns_output(m, ro, flags);
    struct mbuf *m;
    struct route *ro;
    int flags;
```

与前例一样，`m` 参数是装待传消息的 mbuf 链。`ro` 参数用于做路由决定（IDP 恒为零，它不在传输的分组之间保留路由信息）。`flags` 参数指明是否允许用户发送广播分组、是否做路由。如前所述，底层硬件不支持广播概念时，广播标志可能无关紧要。所有输出例程成功返回 0，立即检测到失败时返回 UNIX 错误号。

所有 NS 协议输入都由 NS 中断例程 `nsintr()` 接收——网络接口收到待 NS 协议模块处理的消息时，它在软件中断级被调用。中断例程对分组做一致性检查，然后决定接收、转发还是丢弃。分组要接收时，`nsintr()` 按发送者地址和目的端口号定位接收套接字的 NS 协议控制块，再把分组交给接收协议。

IDP 和 SPP 用如下调用约定：

```c
(void) (*pr_input)(m, nsp, ifp);
	struct mbuf *m;
	struct nspcb *nsp;
	struct ifnet *ifp;
```

每条 mbuf 链是协议模块待处理的一个分组；收到分组的接口作为最后一个参数传递。

IDP 的 `pr_ctlinput()` 例程主要用于把控制信息从错误协议的输入例程传给 IDP 和 SPP 协议模块（NS 封装在 IP 内时，Internet 的 ICMP 模块也可能调用它）。该例程的常用调用约定是：

```c
(void) (*pr_ctlinput)(req, arg);
	int req;
	caddr_t arg;
```

`req` 通常取表 11.4 中的值，尽管 `ns_err_input()` 只从错误协议代码映射其中受限的子集。给出映射请求时 `arg` 参数是指向错误协议分组的指针，否则是指向套接字地址结构的指针。

**XNS 控制操作**

SPP 和 IDP 的 `pr_ctloutput()` 例程提供对 NS 专有选项的访问，这些选项控制 SPP 和/或 IDP 处理经套接字收发数据的行为。SPP 和 IDP 协议都可用的选项有：SO\_HEADERS\_ON\_INPUT——随每条带数据的消息返回协议头；SO\_MTU——设置将发送或接收的消息的最大大小；SO\_DEFAULT\_HEADERS——为外出消息建立默认头部。


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://book.bsdcn.org/4.3-bsd-unix-cao-zuo-xi-tong-she-ji-yu-shi-xian/di-si-bu-fen-jin-cheng-jian-tong-xin/12.10.-shi-le-wang-luo-xi-tong-tong-xin-yu.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
