+static int targopt(scanner *sc, addr_opts *ao)
+{
+ inet_targopts *io = (inet_targopts *)ao;
+
+ CONF_BEGIN(sc, "dest", "Internet socket target");
+ if (strcmp(sc->d.buf, "addr") == 0) {
+ addropt(sc, &io->io);
+ CONF_ACCEPT;
+ }
+ CONF_END;
+}
+
+static int inet_option(scanner *sc, addr_opts *ao, unsigned type)
+{
+ CONF_BEGIN(sc, "inet", "Internet socket");
+ if (type != ADDR_DEST && srcopt(sc, ao))
+ CONF_ACCEPT;
+ if (type != ADDR_SRC && targopt(sc, ao))
+ CONF_ACCEPT;
+ CONF_END;
+}
+
+/* --- @freeopts@ --- */
+
+static void inet_freesrcopts(addr_opts *ao)
+{
+ inet_srcopts *io = (inet_srcopts *)ao;
+ acl_free(io->acl);
+ DESTROY(io);
+}
+
+static void inet_freetargopts(addr_opts *ao)
+{
+ inet_targopts *io = (inet_targopts *)ao;
+ DESTROY(io);
+}
+
+/* --- @bind@ --- */
+
+static int inet_bind(addr *a, addr_opts *ao)
+{
+ inet_addrx *ia = (inet_addrx *)a;
+ inet_srcopts *io = (inet_srcopts *)ao;
+ struct sockaddr_in sin;
+ int opt = 1;
+ int fd;
+
+ if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
+ goto fail_0;
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+ fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
+ sin = ia->sin;
+ sin.sin_addr = io->io.bind;
+ if (bind(fd, (struct sockaddr *)&sin, sizeof(ia->sin)))
+ goto fail_1;
+ return (fd);
+
+fail_1:
+ close(fd);
+fail_0:
+ return (-1);
+}
+