16ac5fe48SPawel Jakub Dawidek /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni *
46ac5fe48SPawel Jakub Dawidek * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org>
56ac5fe48SPawel Jakub Dawidek * All rights reserved.
66ac5fe48SPawel Jakub Dawidek *
76ac5fe48SPawel Jakub Dawidek * Redistribution and use in source and binary forms, with or without
86ac5fe48SPawel Jakub Dawidek * modification, are permitted provided that the following conditions
96ac5fe48SPawel Jakub Dawidek * are met:
106ac5fe48SPawel Jakub Dawidek * 1. Redistributions of source code must retain the above copyright
116ac5fe48SPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer.
126ac5fe48SPawel Jakub Dawidek * 2. Redistributions in binary form must reproduce the above copyright
136ac5fe48SPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer in the
146ac5fe48SPawel Jakub Dawidek * documentation and/or other materials provided with the distribution.
156ac5fe48SPawel Jakub Dawidek *
166ac5fe48SPawel Jakub Dawidek * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
176ac5fe48SPawel Jakub Dawidek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
186ac5fe48SPawel Jakub Dawidek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
196ac5fe48SPawel Jakub Dawidek * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
206ac5fe48SPawel Jakub Dawidek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
216ac5fe48SPawel Jakub Dawidek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
226ac5fe48SPawel Jakub Dawidek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
236ac5fe48SPawel Jakub Dawidek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
246ac5fe48SPawel Jakub Dawidek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
256ac5fe48SPawel Jakub Dawidek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
266ac5fe48SPawel Jakub Dawidek * SUCH DAMAGE.
276ac5fe48SPawel Jakub Dawidek */
286ac5fe48SPawel Jakub Dawidek
296ac5fe48SPawel Jakub Dawidek #include <stdio.h>
306ac5fe48SPawel Jakub Dawidek #include <stdlib.h>
316ac5fe48SPawel Jakub Dawidek #include <unistd.h>
326ac5fe48SPawel Jakub Dawidek #include <fcntl.h>
336ac5fe48SPawel Jakub Dawidek #include <sys/param.h>
346ac5fe48SPawel Jakub Dawidek #include <sys/disk.h>
356ac5fe48SPawel Jakub Dawidek #include <sys/stat.h>
366ac5fe48SPawel Jakub Dawidek #include <sys/endian.h>
376ac5fe48SPawel Jakub Dawidek #include <sys/socket.h>
386ac5fe48SPawel Jakub Dawidek #include <sys/linker.h>
396ac5fe48SPawel Jakub Dawidek #include <sys/module.h>
406ac5fe48SPawel Jakub Dawidek #include <netinet/in.h>
417be67fe3SPawel Jakub Dawidek #include <netinet/tcp.h>
426ac5fe48SPawel Jakub Dawidek #include <arpa/inet.h>
436ac5fe48SPawel Jakub Dawidek #include <signal.h>
446ac5fe48SPawel Jakub Dawidek #include <err.h>
456ac5fe48SPawel Jakub Dawidek #include <errno.h>
466ac5fe48SPawel Jakub Dawidek #include <string.h>
476ac5fe48SPawel Jakub Dawidek #include <strings.h>
486ac5fe48SPawel Jakub Dawidek #include <libgen.h>
4971ae6999SPawel Jakub Dawidek #include <libutil.h>
506ac5fe48SPawel Jakub Dawidek #include <netdb.h>
516ac5fe48SPawel Jakub Dawidek #include <syslog.h>
526ac5fe48SPawel Jakub Dawidek #include <stdarg.h>
5371ae6999SPawel Jakub Dawidek #include <stdint.h>
546ac5fe48SPawel Jakub Dawidek #include <libgeom.h>
556ac5fe48SPawel Jakub Dawidek
566ac5fe48SPawel Jakub Dawidek #include <geom/gate/g_gate.h>
576ac5fe48SPawel Jakub Dawidek #include "ggate.h"
586ac5fe48SPawel Jakub Dawidek
596ac5fe48SPawel Jakub Dawidek
606ac5fe48SPawel Jakub Dawidek int g_gate_devfd = -1;
616ac5fe48SPawel Jakub Dawidek int g_gate_verbose = 0;
626ac5fe48SPawel Jakub Dawidek
636ac5fe48SPawel Jakub Dawidek
646ac5fe48SPawel Jakub Dawidek void
g_gate_vlog(int priority,const char * message,va_list ap)656ac5fe48SPawel Jakub Dawidek g_gate_vlog(int priority, const char *message, va_list ap)
666ac5fe48SPawel Jakub Dawidek {
676ac5fe48SPawel Jakub Dawidek
686ac5fe48SPawel Jakub Dawidek if (g_gate_verbose) {
696ac5fe48SPawel Jakub Dawidek const char *prefix;
706ac5fe48SPawel Jakub Dawidek
716ac5fe48SPawel Jakub Dawidek switch (priority) {
726ac5fe48SPawel Jakub Dawidek case LOG_ERR:
736ac5fe48SPawel Jakub Dawidek prefix = "error";
746ac5fe48SPawel Jakub Dawidek break;
756ac5fe48SPawel Jakub Dawidek case LOG_WARNING:
766ac5fe48SPawel Jakub Dawidek prefix = "warning";
776ac5fe48SPawel Jakub Dawidek break;
786ac5fe48SPawel Jakub Dawidek case LOG_NOTICE:
796ac5fe48SPawel Jakub Dawidek prefix = "notice";
806ac5fe48SPawel Jakub Dawidek break;
816ac5fe48SPawel Jakub Dawidek case LOG_INFO:
826ac5fe48SPawel Jakub Dawidek prefix = "info";
836ac5fe48SPawel Jakub Dawidek break;
846ac5fe48SPawel Jakub Dawidek case LOG_DEBUG:
856ac5fe48SPawel Jakub Dawidek prefix = "debug";
866ac5fe48SPawel Jakub Dawidek break;
876ac5fe48SPawel Jakub Dawidek default:
886ac5fe48SPawel Jakub Dawidek prefix = "unknown";
896ac5fe48SPawel Jakub Dawidek }
906ac5fe48SPawel Jakub Dawidek
916ac5fe48SPawel Jakub Dawidek printf("%s: ", prefix);
926ac5fe48SPawel Jakub Dawidek vprintf(message, ap);
936ac5fe48SPawel Jakub Dawidek printf("\n");
946ac5fe48SPawel Jakub Dawidek } else {
956ac5fe48SPawel Jakub Dawidek if (priority != LOG_DEBUG)
966ac5fe48SPawel Jakub Dawidek vsyslog(priority, message, ap);
976ac5fe48SPawel Jakub Dawidek }
986ac5fe48SPawel Jakub Dawidek }
996ac5fe48SPawel Jakub Dawidek
1006ac5fe48SPawel Jakub Dawidek void
g_gate_log(int priority,const char * message,...)1016ac5fe48SPawel Jakub Dawidek g_gate_log(int priority, const char *message, ...)
1026ac5fe48SPawel Jakub Dawidek {
1036ac5fe48SPawel Jakub Dawidek va_list ap;
1046ac5fe48SPawel Jakub Dawidek
1056ac5fe48SPawel Jakub Dawidek va_start(ap, message);
1066ac5fe48SPawel Jakub Dawidek g_gate_vlog(priority, message, ap);
1076ac5fe48SPawel Jakub Dawidek va_end(ap);
1086ac5fe48SPawel Jakub Dawidek }
1096ac5fe48SPawel Jakub Dawidek
1106ac5fe48SPawel Jakub Dawidek void
g_gate_xvlog(const char * message,va_list ap)1116ac5fe48SPawel Jakub Dawidek g_gate_xvlog(const char *message, va_list ap)
1126ac5fe48SPawel Jakub Dawidek {
1136ac5fe48SPawel Jakub Dawidek
1146ac5fe48SPawel Jakub Dawidek g_gate_vlog(LOG_ERR, message, ap);
1156ac5fe48SPawel Jakub Dawidek g_gate_vlog(LOG_ERR, "Exiting.", ap);
1166ac5fe48SPawel Jakub Dawidek exit(EXIT_FAILURE);
1176ac5fe48SPawel Jakub Dawidek }
1186ac5fe48SPawel Jakub Dawidek
1196ac5fe48SPawel Jakub Dawidek void
g_gate_xlog(const char * message,...)1206ac5fe48SPawel Jakub Dawidek g_gate_xlog(const char *message, ...)
1216ac5fe48SPawel Jakub Dawidek {
1226ac5fe48SPawel Jakub Dawidek va_list ap;
1236ac5fe48SPawel Jakub Dawidek
1246ac5fe48SPawel Jakub Dawidek va_start(ap, message);
1256ac5fe48SPawel Jakub Dawidek g_gate_xvlog(message, ap);
1266ac5fe48SPawel Jakub Dawidek /* NOTREACHED */
1276ac5fe48SPawel Jakub Dawidek va_end(ap);
1286ac5fe48SPawel Jakub Dawidek exit(EXIT_FAILURE);
1296ac5fe48SPawel Jakub Dawidek }
1306ac5fe48SPawel Jakub Dawidek
1316ac5fe48SPawel Jakub Dawidek off_t
g_gate_mediasize(int fd)1326ac5fe48SPawel Jakub Dawidek g_gate_mediasize(int fd)
1336ac5fe48SPawel Jakub Dawidek {
1346ac5fe48SPawel Jakub Dawidek off_t mediasize;
1356ac5fe48SPawel Jakub Dawidek struct stat sb;
1366ac5fe48SPawel Jakub Dawidek
137122abe03SPawel Jakub Dawidek if (fstat(fd, &sb) == -1)
1386ac5fe48SPawel Jakub Dawidek g_gate_xlog("fstat(): %s.", strerror(errno));
1396ac5fe48SPawel Jakub Dawidek if (S_ISCHR(sb.st_mode)) {
140122abe03SPawel Jakub Dawidek if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) == -1) {
1416ac5fe48SPawel Jakub Dawidek g_gate_xlog("Can't get media size: %s.",
1426ac5fe48SPawel Jakub Dawidek strerror(errno));
1436ac5fe48SPawel Jakub Dawidek }
1446ac5fe48SPawel Jakub Dawidek } else if (S_ISREG(sb.st_mode)) {
1456ac5fe48SPawel Jakub Dawidek mediasize = sb.st_size;
1466ac5fe48SPawel Jakub Dawidek } else {
1476ac5fe48SPawel Jakub Dawidek g_gate_xlog("Unsupported file system object.");
1486ac5fe48SPawel Jakub Dawidek }
1496ac5fe48SPawel Jakub Dawidek return (mediasize);
1506ac5fe48SPawel Jakub Dawidek }
1516ac5fe48SPawel Jakub Dawidek
15215c7f46bSPawel Jakub Dawidek unsigned
g_gate_sectorsize(int fd)1536ac5fe48SPawel Jakub Dawidek g_gate_sectorsize(int fd)
1546ac5fe48SPawel Jakub Dawidek {
15515c7f46bSPawel Jakub Dawidek unsigned secsize;
1566ac5fe48SPawel Jakub Dawidek struct stat sb;
1576ac5fe48SPawel Jakub Dawidek
158122abe03SPawel Jakub Dawidek if (fstat(fd, &sb) == -1)
1596ac5fe48SPawel Jakub Dawidek g_gate_xlog("fstat(): %s.", strerror(errno));
1606ac5fe48SPawel Jakub Dawidek if (S_ISCHR(sb.st_mode)) {
161122abe03SPawel Jakub Dawidek if (ioctl(fd, DIOCGSECTORSIZE, &secsize) == -1) {
1626ac5fe48SPawel Jakub Dawidek g_gate_xlog("Can't get sector size: %s.",
1636ac5fe48SPawel Jakub Dawidek strerror(errno));
1646ac5fe48SPawel Jakub Dawidek }
1656ac5fe48SPawel Jakub Dawidek } else if (S_ISREG(sb.st_mode)) {
1666ac5fe48SPawel Jakub Dawidek secsize = 512;
1676ac5fe48SPawel Jakub Dawidek } else {
1686ac5fe48SPawel Jakub Dawidek g_gate_xlog("Unsupported file system object.");
1696ac5fe48SPawel Jakub Dawidek }
1706ac5fe48SPawel Jakub Dawidek return (secsize);
1716ac5fe48SPawel Jakub Dawidek }
1726ac5fe48SPawel Jakub Dawidek
1736ac5fe48SPawel Jakub Dawidek void
g_gate_open_device(void)1746ac5fe48SPawel Jakub Dawidek g_gate_open_device(void)
1756ac5fe48SPawel Jakub Dawidek {
1766ac5fe48SPawel Jakub Dawidek
177d44dbcbbSPawel Jakub Dawidek g_gate_devfd = open("/dev/" G_GATE_CTL_NAME, O_RDWR);
178122abe03SPawel Jakub Dawidek if (g_gate_devfd == -1)
1796ac5fe48SPawel Jakub Dawidek err(EXIT_FAILURE, "open(/dev/%s)", G_GATE_CTL_NAME);
1806ac5fe48SPawel Jakub Dawidek }
1816ac5fe48SPawel Jakub Dawidek
1826ac5fe48SPawel Jakub Dawidek void
g_gate_close_device(void)1836ac5fe48SPawel Jakub Dawidek g_gate_close_device(void)
1846ac5fe48SPawel Jakub Dawidek {
1856ac5fe48SPawel Jakub Dawidek
1866ac5fe48SPawel Jakub Dawidek close(g_gate_devfd);
1876ac5fe48SPawel Jakub Dawidek }
1886ac5fe48SPawel Jakub Dawidek
1896ac5fe48SPawel Jakub Dawidek void
g_gate_ioctl(unsigned long req,void * data)1906ac5fe48SPawel Jakub Dawidek g_gate_ioctl(unsigned long req, void *data)
1916ac5fe48SPawel Jakub Dawidek {
1926ac5fe48SPawel Jakub Dawidek
193122abe03SPawel Jakub Dawidek if (ioctl(g_gate_devfd, req, data) == -1) {
1946ac5fe48SPawel Jakub Dawidek g_gate_xlog("%s: ioctl(/dev/%s): %s.", getprogname(),
1956ac5fe48SPawel Jakub Dawidek G_GATE_CTL_NAME, strerror(errno));
1966ac5fe48SPawel Jakub Dawidek }
1976ac5fe48SPawel Jakub Dawidek }
1986ac5fe48SPawel Jakub Dawidek
1996ac5fe48SPawel Jakub Dawidek void
g_gate_destroy(int unit,int force)2006ac5fe48SPawel Jakub Dawidek g_gate_destroy(int unit, int force)
2016ac5fe48SPawel Jakub Dawidek {
2026ac5fe48SPawel Jakub Dawidek struct g_gate_ctl_destroy ggio;
2036ac5fe48SPawel Jakub Dawidek
2046ac5fe48SPawel Jakub Dawidek ggio.gctl_version = G_GATE_VERSION;
2056ac5fe48SPawel Jakub Dawidek ggio.gctl_unit = unit;
2066ac5fe48SPawel Jakub Dawidek ggio.gctl_force = force;
2076ac5fe48SPawel Jakub Dawidek g_gate_ioctl(G_GATE_CMD_DESTROY, &ggio);
2086ac5fe48SPawel Jakub Dawidek }
2096ac5fe48SPawel Jakub Dawidek
2106ac5fe48SPawel Jakub Dawidek void
g_gate_load_module(void)2116ac5fe48SPawel Jakub Dawidek g_gate_load_module(void)
2126ac5fe48SPawel Jakub Dawidek {
2136ac5fe48SPawel Jakub Dawidek
214122abe03SPawel Jakub Dawidek if (modfind("g_gate") == -1) {
2156ac5fe48SPawel Jakub Dawidek /* Not present in kernel, try loading it. */
216122abe03SPawel Jakub Dawidek if (kldload("geom_gate") == -1 || modfind("g_gate") == -1) {
2176ac5fe48SPawel Jakub Dawidek if (errno != EEXIST) {
2186ac5fe48SPawel Jakub Dawidek errx(EXIT_FAILURE,
2196ac5fe48SPawel Jakub Dawidek "geom_gate module not available!");
2206ac5fe48SPawel Jakub Dawidek }
2216ac5fe48SPawel Jakub Dawidek }
2226ac5fe48SPawel Jakub Dawidek }
2236ac5fe48SPawel Jakub Dawidek }
2246ac5fe48SPawel Jakub Dawidek
2252663c885SPawel Jakub Dawidek /*
2262663c885SPawel Jakub Dawidek * When we send from ggatec packets larger than 32kB, performance drops
2272663c885SPawel Jakub Dawidek * significantly (eg. to 256kB/s over 1Gbit/s link). This is not a problem
2282663c885SPawel Jakub Dawidek * when data is send from ggated. I don't know why, so for now I limit
2292663c885SPawel Jakub Dawidek * size of packets send from ggatec to 32kB by defining MAX_SEND_SIZE
2302663c885SPawel Jakub Dawidek * in ggatec Makefile.
2312663c885SPawel Jakub Dawidek */
2322663c885SPawel Jakub Dawidek #ifndef MAX_SEND_SIZE
2332663c885SPawel Jakub Dawidek #define MAX_SEND_SIZE MAXPHYS
2342663c885SPawel Jakub Dawidek #endif
2357be67fe3SPawel Jakub Dawidek ssize_t
g_gate_send(int s,const void * buf,size_t len,int flags)2367be67fe3SPawel Jakub Dawidek g_gate_send(int s, const void *buf, size_t len, int flags)
2377be67fe3SPawel Jakub Dawidek {
2387be67fe3SPawel Jakub Dawidek ssize_t done = 0, done2;
2397be67fe3SPawel Jakub Dawidek const unsigned char *p = buf;
2407be67fe3SPawel Jakub Dawidek
2417be67fe3SPawel Jakub Dawidek while (len > 0) {
2422663c885SPawel Jakub Dawidek done2 = send(s, p, MIN(len, MAX_SEND_SIZE), flags);
2437be67fe3SPawel Jakub Dawidek if (done2 == 0)
2447be67fe3SPawel Jakub Dawidek break;
2457be67fe3SPawel Jakub Dawidek else if (done2 == -1) {
2467be67fe3SPawel Jakub Dawidek if (errno == EAGAIN) {
2477be67fe3SPawel Jakub Dawidek printf("%s: EAGAIN\n", __func__);
2487be67fe3SPawel Jakub Dawidek continue;
2497be67fe3SPawel Jakub Dawidek }
2507be67fe3SPawel Jakub Dawidek done = -1;
2517be67fe3SPawel Jakub Dawidek break;
2527be67fe3SPawel Jakub Dawidek }
2537be67fe3SPawel Jakub Dawidek done += done2;
2547be67fe3SPawel Jakub Dawidek p += done2;
2557be67fe3SPawel Jakub Dawidek len -= done2;
2567be67fe3SPawel Jakub Dawidek }
2577be67fe3SPawel Jakub Dawidek return (done);
2587be67fe3SPawel Jakub Dawidek }
2597be67fe3SPawel Jakub Dawidek
2607be67fe3SPawel Jakub Dawidek ssize_t
g_gate_recv(int s,void * buf,size_t len,int flags)2617be67fe3SPawel Jakub Dawidek g_gate_recv(int s, void *buf, size_t len, int flags)
2627be67fe3SPawel Jakub Dawidek {
263a930f272SPawel Jakub Dawidek ssize_t done;
2647be67fe3SPawel Jakub Dawidek
265a930f272SPawel Jakub Dawidek do {
266a930f272SPawel Jakub Dawidek done = recv(s, buf, len, flags);
267a930f272SPawel Jakub Dawidek } while (done == -1 && errno == EAGAIN);
268a930f272SPawel Jakub Dawidek return (done);
2697be67fe3SPawel Jakub Dawidek }
2707be67fe3SPawel Jakub Dawidek
2717be67fe3SPawel Jakub Dawidek int nagle = 1;
2727be67fe3SPawel Jakub Dawidek unsigned rcvbuf = G_GATE_RCVBUF;
2737be67fe3SPawel Jakub Dawidek unsigned sndbuf = G_GATE_SNDBUF;
2747be67fe3SPawel Jakub Dawidek
2757be67fe3SPawel Jakub Dawidek void
g_gate_socket_settings(int sfd)2767be67fe3SPawel Jakub Dawidek g_gate_socket_settings(int sfd)
2777be67fe3SPawel Jakub Dawidek {
2787be67fe3SPawel Jakub Dawidek struct timeval tv;
2797be67fe3SPawel Jakub Dawidek int bsize, on;
2807be67fe3SPawel Jakub Dawidek
2817be67fe3SPawel Jakub Dawidek /* Socket settings. */
2827be67fe3SPawel Jakub Dawidek on = 1;
2837be67fe3SPawel Jakub Dawidek if (nagle) {
2847be67fe3SPawel Jakub Dawidek if (setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &on,
2857be67fe3SPawel Jakub Dawidek sizeof(on)) == -1) {
2867be67fe3SPawel Jakub Dawidek g_gate_xlog("setsockopt() error: %s.", strerror(errno));
2877be67fe3SPawel Jakub Dawidek }
2887be67fe3SPawel Jakub Dawidek }
2897be67fe3SPawel Jakub Dawidek if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
2907be67fe3SPawel Jakub Dawidek g_gate_xlog("setsockopt(SO_REUSEADDR): %s.", strerror(errno));
2917be67fe3SPawel Jakub Dawidek bsize = rcvbuf;
2927be67fe3SPawel Jakub Dawidek if (setsockopt(sfd, SOL_SOCKET, SO_RCVBUF, &bsize, sizeof(bsize)) == -1)
2937be67fe3SPawel Jakub Dawidek g_gate_xlog("setsockopt(SO_RCVBUF): %s.", strerror(errno));
2947be67fe3SPawel Jakub Dawidek bsize = sndbuf;
2957be67fe3SPawel Jakub Dawidek if (setsockopt(sfd, SOL_SOCKET, SO_SNDBUF, &bsize, sizeof(bsize)) == -1)
2967be67fe3SPawel Jakub Dawidek g_gate_xlog("setsockopt(SO_SNDBUF): %s.", strerror(errno));
297a930f272SPawel Jakub Dawidek tv.tv_sec = 8;
2987be67fe3SPawel Jakub Dawidek tv.tv_usec = 0;
2997be67fe3SPawel Jakub Dawidek if (setsockopt(sfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {
3007be67fe3SPawel Jakub Dawidek g_gate_log(LOG_ERR, "setsockopt(SO_SNDTIMEO) error: %s.",
3017be67fe3SPawel Jakub Dawidek strerror(errno));
3027be67fe3SPawel Jakub Dawidek }
3037be67fe3SPawel Jakub Dawidek if (setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
3047be67fe3SPawel Jakub Dawidek g_gate_log(LOG_ERR, "setsockopt(SO_RCVTIMEO) error: %s.",
3057be67fe3SPawel Jakub Dawidek strerror(errno));
3067be67fe3SPawel Jakub Dawidek }
3077be67fe3SPawel Jakub Dawidek }
3087be67fe3SPawel Jakub Dawidek
3096ac5fe48SPawel Jakub Dawidek #ifdef LIBGEOM
3106ac5fe48SPawel Jakub Dawidek static struct gclass *
find_class(struct gmesh * mesh,const char * name)3116ac5fe48SPawel Jakub Dawidek find_class(struct gmesh *mesh, const char *name)
3126ac5fe48SPawel Jakub Dawidek {
3136ac5fe48SPawel Jakub Dawidek struct gclass *class;
3146ac5fe48SPawel Jakub Dawidek
3156ac5fe48SPawel Jakub Dawidek LIST_FOREACH(class, &mesh->lg_class, lg_class) {
3166ac5fe48SPawel Jakub Dawidek if (strcmp(class->lg_name, name) == 0)
3176ac5fe48SPawel Jakub Dawidek return (class);
3186ac5fe48SPawel Jakub Dawidek }
3196ac5fe48SPawel Jakub Dawidek return (NULL);
3206ac5fe48SPawel Jakub Dawidek }
3216ac5fe48SPawel Jakub Dawidek
3226ac5fe48SPawel Jakub Dawidek static const char *
get_conf(struct ggeom * gp,const char * name)3236ac5fe48SPawel Jakub Dawidek get_conf(struct ggeom *gp, const char *name)
3246ac5fe48SPawel Jakub Dawidek {
3256ac5fe48SPawel Jakub Dawidek struct gconfig *conf;
3266ac5fe48SPawel Jakub Dawidek
3276ac5fe48SPawel Jakub Dawidek LIST_FOREACH(conf, &gp->lg_config, lg_config) {
3286ac5fe48SPawel Jakub Dawidek if (strcmp(conf->lg_name, name) == 0)
3296ac5fe48SPawel Jakub Dawidek return (conf->lg_val);
3306ac5fe48SPawel Jakub Dawidek }
3316ac5fe48SPawel Jakub Dawidek return (NULL);
3326ac5fe48SPawel Jakub Dawidek }
3336ac5fe48SPawel Jakub Dawidek
3346ac5fe48SPawel Jakub Dawidek static void
show_config(struct ggeom * gp,int verbose)3356ac5fe48SPawel Jakub Dawidek show_config(struct ggeom *gp, int verbose)
3366ac5fe48SPawel Jakub Dawidek {
3376ac5fe48SPawel Jakub Dawidek struct gprovider *pp;
33871ae6999SPawel Jakub Dawidek char buf[5];
3396ac5fe48SPawel Jakub Dawidek
3406ac5fe48SPawel Jakub Dawidek pp = LIST_FIRST(&gp->lg_provider);
3416ac5fe48SPawel Jakub Dawidek if (pp == NULL)
3426ac5fe48SPawel Jakub Dawidek return;
3436ac5fe48SPawel Jakub Dawidek if (!verbose) {
3446ac5fe48SPawel Jakub Dawidek printf("%s\n", pp->lg_name);
3456ac5fe48SPawel Jakub Dawidek return;
3466ac5fe48SPawel Jakub Dawidek }
3476ac5fe48SPawel Jakub Dawidek printf(" NAME: %s\n", pp->lg_name);
3486ac5fe48SPawel Jakub Dawidek printf(" info: %s\n", get_conf(gp, "info"));
3496ac5fe48SPawel Jakub Dawidek printf(" access: %s\n", get_conf(gp, "access"));
3506ac5fe48SPawel Jakub Dawidek printf(" timeout: %s\n", get_conf(gp, "timeout"));
3516ac5fe48SPawel Jakub Dawidek printf("queue_count: %s\n", get_conf(gp, "queue_count"));
3526ac5fe48SPawel Jakub Dawidek printf(" queue_size: %s\n", get_conf(gp, "queue_size"));
3536ac5fe48SPawel Jakub Dawidek printf(" references: %s\n", get_conf(gp, "ref"));
35471ae6999SPawel Jakub Dawidek humanize_number(buf, sizeof(buf), (int64_t)pp->lg_mediasize, "",
35571ae6999SPawel Jakub Dawidek HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
35671ae6999SPawel Jakub Dawidek printf(" mediasize: %jd (%s)\n", (intmax_t)pp->lg_mediasize, buf);
3576ac5fe48SPawel Jakub Dawidek printf(" sectorsize: %u\n", pp->lg_sectorsize);
3586ac5fe48SPawel Jakub Dawidek printf(" mode: %s\n", pp->lg_mode);
3596ac5fe48SPawel Jakub Dawidek printf("\n");
3606ac5fe48SPawel Jakub Dawidek }
3616ac5fe48SPawel Jakub Dawidek
3626ac5fe48SPawel Jakub Dawidek void
g_gate_list(int unit,int verbose)3636ac5fe48SPawel Jakub Dawidek g_gate_list(int unit, int verbose)
3646ac5fe48SPawel Jakub Dawidek {
3656ac5fe48SPawel Jakub Dawidek struct gmesh mesh;
3666ac5fe48SPawel Jakub Dawidek struct gclass *class;
3676ac5fe48SPawel Jakub Dawidek struct ggeom *gp;
3686ac5fe48SPawel Jakub Dawidek char name[64];
3696ac5fe48SPawel Jakub Dawidek int error;
3706ac5fe48SPawel Jakub Dawidek
3716ac5fe48SPawel Jakub Dawidek error = geom_gettree(&mesh);
3726ac5fe48SPawel Jakub Dawidek if (error != 0)
3736ac5fe48SPawel Jakub Dawidek exit(EXIT_FAILURE);
3746ac5fe48SPawel Jakub Dawidek class = find_class(&mesh, G_GATE_CLASS_NAME);
3756ac5fe48SPawel Jakub Dawidek if (class == NULL) {
3766ac5fe48SPawel Jakub Dawidek geom_deletetree(&mesh);
3776ac5fe48SPawel Jakub Dawidek exit(EXIT_SUCCESS);
3786ac5fe48SPawel Jakub Dawidek }
3796ac5fe48SPawel Jakub Dawidek if (unit >= 0) {
3806ac5fe48SPawel Jakub Dawidek snprintf(name, sizeof(name), "%s%d", G_GATE_PROVIDER_NAME,
3816ac5fe48SPawel Jakub Dawidek unit);
3826ac5fe48SPawel Jakub Dawidek }
3836ac5fe48SPawel Jakub Dawidek LIST_FOREACH(gp, &class->lg_geom, lg_geom) {
3846ac5fe48SPawel Jakub Dawidek if (unit != -1 && strcmp(gp->lg_name, name) != 0)
3856ac5fe48SPawel Jakub Dawidek continue;
3866ac5fe48SPawel Jakub Dawidek show_config(gp, verbose);
3876ac5fe48SPawel Jakub Dawidek }
3886ac5fe48SPawel Jakub Dawidek geom_deletetree(&mesh);
3896ac5fe48SPawel Jakub Dawidek exit(EXIT_SUCCESS);
3906ac5fe48SPawel Jakub Dawidek }
3916ac5fe48SPawel Jakub Dawidek #endif /* LIBGEOM */
3926ac5fe48SPawel Jakub Dawidek
3936ac5fe48SPawel Jakub Dawidek in_addr_t
g_gate_str2ip(const char * str)3946ac5fe48SPawel Jakub Dawidek g_gate_str2ip(const char *str)
3956ac5fe48SPawel Jakub Dawidek {
3966ac5fe48SPawel Jakub Dawidek struct hostent *hp;
3976ac5fe48SPawel Jakub Dawidek in_addr_t ip;
3986ac5fe48SPawel Jakub Dawidek
3996ac5fe48SPawel Jakub Dawidek ip = inet_addr(str);
4006ac5fe48SPawel Jakub Dawidek if (ip != INADDR_NONE) {
4016ac5fe48SPawel Jakub Dawidek /* It is a valid IP address. */
4026ac5fe48SPawel Jakub Dawidek return (ip);
4036ac5fe48SPawel Jakub Dawidek }
4046ac5fe48SPawel Jakub Dawidek /* Check if it is a valid host name. */
4056ac5fe48SPawel Jakub Dawidek hp = gethostbyname(str);
4066ac5fe48SPawel Jakub Dawidek if (hp == NULL)
4076ac5fe48SPawel Jakub Dawidek return (INADDR_NONE);
40886bfa454SPawel Jakub Dawidek return (((struct in_addr *)(void *)hp->h_addr)->s_addr);
4096ac5fe48SPawel Jakub Dawidek }
410