+ union addr addr; /* The address */
+ unsigned port; /* The port, in /host/ byte order */
+};
+
+/* An address pattern consists of an address and a prefix length: the
+ * pattern matches an address if they agree in the first LEN bits.
+ */
+struct addrpat {
+ union addr addr; /* The base address */
+ unsigned len; /* The prefix length */
+};
+
+/* A port pattern matches a port if the port is within the stated (inclusive)
+ * bounds.
+ */
+struct portpat {
+ unsigned lo, hi;
+};
+
+/* A socket pattern consists simply of an address pattern and a port pattern:
+ * it matches a socket componentwise.
+ */
+struct sockpat {
+ struct addrpat addr;
+ struct portpat port;
+};
+
+/* The table of address-type operations. Each address family has one of
+ * these, so that most of the program doesn't need to worry about these
+ * details.
+ */
+struct addrops {
+ int af; /* The AF_* constant */
+ const char *name; /* Name of the protocol, for logs */
+ unsigned len; /* Length of an address, in bits */
+ const union addr *any; /* A wildcard address */
+ const struct addrops_sys *sys; /* Pointer to system-specific ops */
+
+ int (*addreq)(const union addr *, const union addr *);
+ /* Return nonzero if the two addresses are equal. */
+
+ int (*match_addrpat)(const struct addrpat *, const union addr *);
+ /* Return nonzero if the pattern matches the address. */
+
+ void (*socket_to_sockaddr)(const struct socket *s, void *, size_t *);
+ /* Convert a socket structure to a `struct sockaddr', and return the
+ * size of the latter.
+ */
+
+ void (*sockaddr_to_addr)(const void *, union addr *);
+ /* Extract the address from a `struct sockaddr'. */
+
+ int (*init_listen_socket)(int);
+ /* Perform any necessary extra operations on a socket which is going
+ * to be used to listen for incoming connections.
+ */