8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / stand / lib / sock / sock_test.c
blob21932388ef08005b9c7699c4bf58e6c44650ec84
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 * sock_test.c. Implementing a CLI for inetboot testing.
28 #pragma ident "%Z%%M% %I% %E% SMI"
30 #include <sys/types.h>
31 #include "socket_impl.h"
32 #include "socket_inet.h"
33 #include <sys/socket.h>
34 #include <sys/sysmacros.h>
35 #include <netinet/in_systm.h>
36 #include <sys/promif.h>
37 #include <sys/salib.h>
38 #include <ctype.h>
39 #include <errno.h>
40 #include <netinet/in.h>
41 #include "tcp_inet.h"
42 #include "ipv4.h"
43 #include <netinet/tcp.h>
45 static int atoi(const char *);
46 static int st_accept(void);
47 static int st_bind(void);
48 static int st_connect(void);
49 static int st_echo(void);
50 static int st_getsockname(void);
51 static int st_getsockopt(void);
52 static int st_get_addr_and_port(in_addr_t *, unsigned short *);
53 static int st_get_buf_and_cnt(char **, int *);
54 static int st_listen(void);
55 static int st_match_option(char *, int *, int *);
56 static int st_send(void);
57 static int st_sendto(void);
58 static int st_recv(void);
59 static int st_recvfrom(void);
60 static int st_set_addr(void);
61 static int st_set_netmask(void);
62 static int st_set_router(void);
63 static int st_setsockopt(void);
64 static int st_socket(void);
65 static int st_sock_close(void);
66 static int st_tcp_tw_report(void);
67 static int st_toggle_promiscuous(void);
68 static int st_use_obp(void);
70 /* Wrapper for socket calls. */
71 static int st_local_accept(int, struct sockaddr *, socklen_t *);
72 static int st_local_bind(int, const struct sockaddr *, socklen_t);
73 static int st_local_connect(int, const struct sockaddr *, socklen_t);
74 static int st_local_getsockname(int, struct sockaddr *, socklen_t *);
75 static int st_local_getsockopt(int, int, int, void *, socklen_t *);
76 static int st_local_listen(int, int);
77 static int st_local_recv(int, void *, size_t, int);
78 static int st_local_recvfrom(int, void *, size_t, int, struct sockaddr *,
79 socklen_t *);
80 static int st_local_send(int, const void *, size_t, int);
81 static int st_local_sendto(int, const void *, size_t, int,
82 const struct sockaddr *, socklen_t);
83 static int st_local_setsockopt(int, int, int, const void *, socklen_t);
84 static int st_local_socket(int, int, int);
85 static int st_local_socket_close(int);
87 struct sock_test_cmd_s {
88 char *st_cmd;
89 int (*st_fn)(void);
92 static struct sock_test_cmd_s st_cmds[] = {
93 { "set_addr", st_set_addr},
94 { "set_netmask", st_set_netmask},
95 { "set_router", st_set_router},
96 { "socket", st_socket },
97 { "bind", st_bind },
98 { "accept", st_accept },
99 { "connect", st_connect },
100 { "listen", st_listen },
101 { "send", st_send },
102 { "sendto", st_sendto },
103 { "recv", st_recv },
104 { "recvfrom", st_recvfrom },
105 { "setsockopt", st_setsockopt },
106 { "getsockopt", st_getsockopt },
107 { "getsockname", st_getsockname },
108 { "close", st_sock_close },
109 { "echo", st_echo },
110 { "toggle_promiscous", st_toggle_promiscuous},
111 { "use_obp", st_use_obp},
112 { "tcp_tw_report", st_tcp_tw_report},
113 { NULL, NULL }
116 struct so_option_string_s {
117 char *so_name;
118 int so_opt;
119 int so_opt_level;
120 } so_option_array[] = {
121 { "rcvtimeo", SO_RCVTIMEO, SOL_SOCKET },
122 { "dontroute", SO_DONTROUTE, SOL_SOCKET },
123 { "reuseaddr", SO_REUSEADDR, SOL_SOCKET },
124 { "rcvbuf", SO_RCVBUF, SOL_SOCKET },
125 { "sndbuf", SO_SNDBUF, SOL_SOCKET },
126 { NULL, 0 }
129 #define NO_OPENED_SOCKET -1
131 /* Right now, we only allow one socket at one time. */
132 static int g_sock_fd = NO_OPENED_SOCKET;
133 static int save_g_sock_fd = NO_OPENED_SOCKET;
135 /* Boolean to decide if OBP network routines should be used. */
136 static boolean_t use_obp = B_FALSE;
140 * The following routines are wrappers for the real socket routines. The
141 * boolean use_obp is used to decide whether the real socket routines is
142 * called or the "equivalent" OBP provided routines should be called.
144 static int
145 st_local_socket(int domain, int type, int protocol)
147 if (!use_obp) {
148 return (socket(domain, type, protocol));
149 } else {
150 return (0);
154 static int
155 st_local_socket_close(int sd)
157 if (!use_obp) {
158 return (socket_close(sd));
159 } else {
160 return (0);
164 static int
165 st_local_accept(int sd, struct sockaddr *addr, socklen_t *addr_len)
167 if (!use_obp) {
168 return (accept(sd, addr, addr_len));
169 } else {
170 return (0);
174 static int
175 st_local_bind(int sd, const struct sockaddr *name, socklen_t namelen)
177 if (!use_obp) {
178 return (bind(sd, name, namelen));
179 } else {
180 return (0);
184 static int
185 st_local_connect(int sd, const struct sockaddr *addr, socklen_t addr_len)
187 if (!use_obp) {
188 return (connect(sd, addr, addr_len));
189 } else {
190 return (0);
194 static int
195 st_local_listen(int sd, int backlog)
197 if (!use_obp) {
198 return (listen(sd, backlog));
199 } else {
200 return (0);
204 static int
205 st_local_send(int sd, const void *msg, size_t len, int flags)
207 if (!use_obp) {
208 return (send(sd, msg, len, flags));
209 } else {
210 return (0);
214 static int
215 st_local_sendto(int sd, const void *msg, size_t len, int flags,
216 const struct sockaddr *to, socklen_t tolen)
218 if (!use_obp) {
219 return (sendto(sd, msg, len, flags, to, tolen));
220 } else {
221 return (0);
225 static int
226 st_local_recv(int sd, void *buf, size_t len, int flags)
228 if (!use_obp) {
229 return (recv(sd, buf, len, flags));
230 } else {
231 return (0);
235 static int
236 st_local_recvfrom(int sd, void *buf, size_t len, int flags,
237 struct sockaddr *from, socklen_t *fromlen)
239 if (!use_obp) {
240 return (recvfrom(sd, buf, len, flags, from, fromlen));
241 } else {
242 return (0);
246 static int
247 st_local_getsockname(int sd, struct sockaddr *name, socklen_t *namelen)
249 if (!use_obp) {
250 return (getsockname(sd, name, namelen));
251 } else {
252 return (0);
257 static int
258 st_local_getsockopt(int sd, int level, int option, void *optval,
259 socklen_t *optlen)
261 if (!use_obp) {
262 return (getsockopt(sd, level, option, optval, optlen));
263 } else {
264 return (0);
268 static int
269 st_local_setsockopt(int sd, int level, int option, const void *optval,
270 socklen_t optlen)
272 if (!use_obp) {
273 return (setsockopt(sd, level, option, optval, optlen));
274 } else {
275 return (0);
279 static int
280 atoi(const char *p)
282 int n;
283 int c = *p++, neg = 0;
285 while (isspace(c)) {
286 c = *p++;
288 if (!isdigit(c)) {
289 switch (c) {
290 case '-':
291 neg++;
292 /* FALLTHROUGH */
293 case '+':
294 c = *p++;
297 for (n = 0; isdigit(c); c = *p++) {
298 n *= 10; /* two steps to avoid unnecessary overflow */
299 n += '0' - c; /* accum neg to avoid surprises at MAX */
301 return (neg ? n : -n);
305 st_interpret(char *buf)
307 char *cmd;
308 int i;
310 if ((cmd = strtok(buf, " ")) == NULL)
311 return (-1);
313 for (i = 0; st_cmds[i].st_cmd != NULL; i++) {
314 if (strcmp(cmd, st_cmds[i].st_cmd) == 0) {
315 return (st_cmds[i].st_fn());
318 printf("! Unknown command: %s\n", cmd);
319 return (-1);
323 static int
324 st_socket(void)
326 char *type;
328 if ((type = strtok(NULL, " ")) == NULL) {
329 printf("! usage: socket type\n");
330 return (-1);
332 if (g_sock_fd != NO_OPENED_SOCKET) {
333 printf("! Cannot open more than 1 socket\n");
334 return (-1);
337 if (strcmp(type, "stream") == 0) {
338 if ((g_sock_fd = st_local_socket(AF_INET, SOCK_STREAM,
339 0)) < 0) {
340 printf("! Error in opening TCP socket: %d\n", errno);
341 return (-1);
342 } else {
343 printf("@ TCP socket opened\n");
345 } else if (strcmp(type, "dgram") == 0) {
346 if ((g_sock_fd = st_local_socket(AF_INET, SOCK_DGRAM,
347 0)) < 0) {
348 printf("! Error in opening UDP socket: %d\n", errno);
349 return (-1);
350 } else {
351 printf("@ UDP socket opened\n");
353 } else if (strcmp(type, "raw") == 0) {
354 if ((g_sock_fd = st_local_socket(AF_INET, SOCK_RAW, 0)) < 0) {
355 printf("! Error in opening RAW socket: %d\n", errno);
356 return (-1);
357 } else {
358 printf("@ RAW socket opened\n");
360 } else {
361 printf("! Unknown socket type: %s\n", type);
362 return (-1);
365 return (0);
368 static int
369 st_set_addr(void)
371 char *tmp;
372 struct in_addr addr;
374 tmp = strtok(NULL, " ");
375 if (tmp == NULL) {
376 printf("! No address given\n");
377 return (-1);
379 if ((addr.s_addr = inet_addr(tmp)) == (uint32_t)-1) {
380 printf("! Malformed address\n");
381 return (-1);
384 ipv4_setipaddr(&addr);
385 printf("@ IP address %s set\n", inet_ntoa(addr));
387 return (0);
390 static int
391 st_set_netmask(void)
393 char *tmp;
394 struct in_addr addr;
396 tmp = strtok(NULL, " ");
397 if (tmp == NULL) {
398 printf("! No netmask given\n");
399 return (-1);
401 if ((addr.s_addr = inet_addr(tmp)) == (uint32_t)-1) {
402 printf("! Malformed netmask\n");
403 return (-1);
406 ipv4_setnetmask(&addr);
407 printf("@ Netmask %s set\n", inet_ntoa(addr));
409 return (0);
412 static int
413 st_set_router(void)
415 char *tmp;
416 struct in_addr addr;
418 tmp = strtok(NULL, " ");
419 if (tmp == NULL) {
420 printf("! No router address given\n");
421 return (-1);
423 if ((addr.s_addr = inet_addr(tmp)) == (uint32_t)-1) {
424 printf("! Malformed router address\n");
425 return (-1);
428 ipv4_setdefaultrouter(&addr);
429 if (ipv4_route(IPV4_ADD_ROUTE, RT_DEFAULT, NULL, &addr) < 0) {
430 printf("! Cannot add default route\n");
431 } else {
432 printf("@ Default router %s set\n", inet_ntoa(addr));
435 return (0);
438 static int
439 st_get_addr_and_port(in_addr_t *addr, unsigned short *port)
441 char *tmp;
443 if (g_sock_fd == NO_OPENED_SOCKET) {
444 printf("! No socket opened\n");
445 return (-1);
448 tmp = strtok(NULL, "/");
449 if (tmp == NULL) {
450 printf("! No address given\n");
451 return (-1);
453 if ((*addr = inet_addr(tmp)) == (uint32_t)-1) {
454 printf("! Malformed address\n");
455 return (-1);
458 tmp = strtok(NULL, " ");
459 if (tmp == NULL) {
460 printf("! No port given\n");
461 return (-1);
463 *port = htons(atoi(tmp));
465 return (0);
468 static int
469 st_bind(void)
471 struct sockaddr_in local_addr;
473 if (st_get_addr_and_port(&(local_addr.sin_addr.s_addr),
474 &(local_addr.sin_port)) < 0) {
475 return (-1);
478 local_addr.sin_family = AF_INET;
479 if (st_local_bind(g_sock_fd, (struct sockaddr *)&local_addr,
480 sizeof (local_addr)) < 0) {
481 printf("! Bind failed: %d\n", errno);
482 return (-1);
484 printf("@ Socket bound to %s/%d\n", inet_ntoa(local_addr.sin_addr),
485 ntohs(local_addr.sin_port));
486 return (0);
489 static int
490 st_listen(void)
492 char *tmp;
494 if (g_sock_fd == NO_OPENED_SOCKET) {
495 printf("! No socket opened\n");
496 return (-1);
498 if ((tmp = strtok(NULL, " ")) == NULL) {
499 printf("! No backlog given\n");
500 return (-1);
502 if (st_local_listen(g_sock_fd, atoi(tmp)) < 0) {
503 printf("! Listen failed: %d\n", errno);
504 return (-1);
506 printf("@ Listen succeeded\n");
507 return (0);
510 static int
511 st_accept(void)
513 struct sockaddr_in addr;
514 socklen_t addr_len;
515 int sd;
517 if (g_sock_fd == NO_OPENED_SOCKET) {
518 printf("! No socket opened\n");
519 return (-1);
521 addr_len = sizeof (struct sockaddr_in);
522 if ((sd = st_local_accept(g_sock_fd, (struct sockaddr *)&addr,
523 &addr_len)) < 0) {
524 printf("! Accept failed: %d\n", errno);
525 return (-1);
527 printf("@ Accept succeeded from %s:%d. Socket descriptor saved\n",
528 inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
529 save_g_sock_fd = g_sock_fd;
530 g_sock_fd = sd;
531 return (0);
534 static int
535 st_connect(void)
537 struct sockaddr_in peer_addr;
539 if (st_get_addr_and_port(&(peer_addr.sin_addr.s_addr),
540 &(peer_addr.sin_port)) < 0) {
541 return (-1);
544 peer_addr.sin_family = AF_INET;
545 if (st_local_connect(g_sock_fd, (struct sockaddr *)&peer_addr,
546 sizeof (peer_addr)) < 0) {
547 printf("! Connect failed: %d\n", errno);
548 return (-1);
550 printf("@ Socket connected to %s/%d\n", inet_ntoa(peer_addr.sin_addr),
551 ntohs(peer_addr.sin_port));
553 return (0);
556 static int
557 st_get_buf_and_cnt(char **buf, int *send_cnt)
559 char *cnt;
561 if ((*buf = strtok(NULL, " ")) == NULL) {
562 printf("! No send buffer\n");
563 return (-1);
565 if ((cnt = strtok(NULL, " ")) == NULL) {
566 printf("! Missing send length\n");
567 return (-1);
570 if ((*send_cnt = atoi(cnt)) < 0) {
571 printf("! Invalid send count\n");
572 return (-1);
574 return (0);
577 static int
578 st_send(void)
580 char *buf;
581 int send_cnt;
583 if (g_sock_fd == NO_OPENED_SOCKET) {
584 printf("! No socket opened\n");
585 return (-1);
588 if (st_get_buf_and_cnt(&buf, &send_cnt) < 0)
589 return (-1);
591 if ((send_cnt = st_local_send(g_sock_fd, buf, send_cnt, 0)) < 0) {
592 printf("! Send failed: %d\n", errno);
593 return (-1);
595 printf("@ Send %d bytes\n", send_cnt);
597 return (0);
600 static int
601 st_sendto(void)
603 struct sockaddr_in peer_addr;
604 char *buf;
605 int send_cnt;
607 if (st_get_addr_and_port(&(peer_addr.sin_addr.s_addr),
608 &(peer_addr.sin_port)) < 0) {
609 return (-1);
611 peer_addr.sin_family = AF_INET;
613 if (st_get_buf_and_cnt(&buf, &send_cnt) < 0)
614 return (-1);
616 if ((send_cnt = st_local_sendto(g_sock_fd, buf, send_cnt, 0,
617 (struct sockaddr *)&peer_addr, sizeof (peer_addr))) < 0) {
618 printf("! Sendto failed: %d\n", errno);
619 return (-1);
621 printf("@ Send %d bytes\n", send_cnt);
623 return (0);
626 static int
627 st_recv(void)
629 char *tmp;
630 char *buf;
631 int buf_len, ret;
633 if (g_sock_fd == NO_OPENED_SOCKET) {
634 printf("! No socket opened\n");
635 return (-1);
638 if ((tmp = strtok(NULL, " ")) == NULL) {
639 printf("! No buffer len given\n");
640 return (-1);
642 buf_len = atoi(tmp);
644 if ((buf = bkmem_zalloc(buf_len)) == NULL) {
645 printf("! Cannot allocate buffer: %d\n", errno);
646 return (-1);
648 if ((ret = st_local_recv(g_sock_fd, buf, buf_len, 0)) <= 0) {
649 if (ret == 0) {
650 printf("@ EOF received: %d\n", errno);
651 return (0);
653 printf("! Cannot recv: %d\n", errno);
654 return (-1);
656 printf("@ Bytes received: %d\n", ret);
657 hexdump(buf, ret);
658 bkmem_free(buf, buf_len);
659 return (0);
662 static int
663 st_recvfrom(void)
665 char *tmp;
666 char *buf;
667 int buf_len, ret;
668 struct sockaddr_in from;
669 socklen_t fromlen;
671 if (g_sock_fd == NO_OPENED_SOCKET) {
672 printf("! No socket opened\n");
673 return (-1);
676 if ((tmp = strtok(NULL, " ")) == NULL) {
677 printf("! No buffer len given\n");
678 return (-1);
680 buf_len = atoi(tmp);
682 if ((buf = bkmem_zalloc(buf_len)) == NULL) {
683 printf("! Cannot allocate buffer: %d\n", errno);
684 return (-1);
686 fromlen = sizeof (from);
687 if ((ret = st_local_recvfrom(g_sock_fd, buf, buf_len, 0,
688 (struct sockaddr *)&from, &fromlen)) <= 0) {
689 if (ret == 0) {
690 printf("@ EOF received: %d\n", errno);
691 return (0);
693 printf("! Cannot recv: %d\n", errno);
694 return (-1);
696 printf("@ Bytes received from %s/%d: %d\n",
697 inet_ntoa(from.sin_addr), ntohs(from.sin_port), ret);
698 hexdump(buf, ret);
699 bkmem_free(buf, buf_len);
700 return (0);
704 * To act as an echo server. Note that it assumes the address and
705 * netmask have been set.
707 static int
708 st_echo(void)
710 char *tmp;
711 int listen_fd, newfd;
712 int echo_port;
713 struct sockaddr_in addr;
714 socklen_t addr_size;
715 int backlog = 20;
716 char *buf;
717 int buf_len, ret, snd_cnt;
719 tmp = strtok(NULL, " ");
720 if (tmp == NULL) {
721 printf("! No echo port given\n");
722 return (-1);
724 echo_port = atoi(tmp);
725 tmp = strtok(NULL, " ");
726 if (tmp == NULL) {
727 printf("! No buffer size given\n");
728 return (-1);
730 buf_len = atoi(tmp);
732 /* Create local socket for echo server */
733 if ((listen_fd = st_local_socket(AF_INET, SOCK_STREAM, 0)) < 0) {
734 printf("! Error in opening TCP socket: %d\n", errno);
735 return (-1);
736 } else {
737 printf("@ Local TCP socket opened\n");
740 /* Bind local socket */
741 addr.sin_family = AF_INET;
742 addr.sin_port = htons(echo_port);
743 addr.sin_addr.s_addr = INADDR_ANY;
745 if (st_local_bind(listen_fd, (struct sockaddr *)&addr,
746 sizeof (addr)) < 0) {
747 printf("! Bind failed: %d\n", errno);
748 return (-1);
750 if (st_local_listen(listen_fd, backlog) < 0) {
751 printf("! Listen failed: %d\n", errno);
752 return (-1);
755 addr_size = sizeof (addr);
756 if ((newfd = st_local_accept(listen_fd, (struct sockaddr *)&addr,
757 &addr_size)) < 0) {
758 printf("! Accept failed: %d\n", errno);
759 (void) st_local_socket_close(listen_fd);
760 return (-1);
762 printf("@ Accepted connection: %s/%d\n", inet_ntoa(addr.sin_addr),
763 ntohs(addr.sin_port));
764 (void) st_local_socket_close(listen_fd);
766 if ((buf = bkmem_zalloc(buf_len)) == NULL) {
767 printf("! Cannot allocate buffer: %d\n", errno);
768 (void) st_local_socket_close(newfd);
769 return (-1);
771 while ((ret = st_local_recv(newfd, buf, buf_len, 0)) > 0) {
772 printf("@ Bytes received: %d\n", ret);
773 hexdump(buf, ret);
774 if ((snd_cnt = st_local_send(newfd, buf, ret, 0)) < ret) {
775 printf("! Send failed: %d\n", errno);
776 bkmem_free(buf, buf_len);
777 return (-1);
779 printf("@ Sent %d bytes\n", snd_cnt);
781 (void) st_local_socket_close(newfd);
782 if (ret < 0) {
783 printf("! Cannot recv: %d\n", errno);
784 bkmem_free(buf, buf_len);
785 return (-1);
786 } else {
787 return (0);
791 static int
792 st_match_option(char *opt_s, int *opt, int *opt_level)
794 int i;
796 for (i = 0; so_option_array[i].so_name != NULL; i++) {
797 if (strcmp(so_option_array[i].so_name, opt_s) == 0) {
798 *opt = so_option_array[i].so_opt;
799 *opt_level = so_option_array[i].so_opt_level;
800 return (0);
803 printf("! Unknown option\n");
804 return (-1);
807 static int
808 st_setsockopt(void)
810 char *tmp;
811 int opt, opt_level, opt_val;
813 if (g_sock_fd == NO_OPENED_SOCKET) {
814 printf("! No socket opened\n");
815 return (-1);
818 if ((tmp = strtok(NULL, " ")) == NULL) {
819 printf("! No option given\n");
820 return (-1);
822 if (st_match_option(tmp, &opt, &opt_level) < 0) {
823 return (-1);
826 /* We only support integer option for the moment. */
827 if ((tmp = strtok(NULL, " ")) == NULL) {
828 printf("! No option value given\n");
829 return (-1);
831 opt_val = atoi(tmp);
833 if (st_local_setsockopt(g_sock_fd, opt_level, opt, &opt_val,
834 sizeof (int)) < 0) {
835 printf("! Cannot set option: %d\n", errno);
836 return (-1);
838 printf("@ Option set successfully\n");
839 return (0);
842 static int
843 st_getsockname(void)
845 struct sockaddr_in addr;
846 socklen_t len;
848 if (g_sock_fd == NO_OPENED_SOCKET) {
849 printf("! No socket opened\n");
850 return (-1);
853 len = sizeof (addr);
854 if (st_local_getsockname(g_sock_fd, (struct sockaddr *)&addr,
855 &len) < 0) {
856 printf("! getsockname failed: %d\n", errno);
857 return (-1);
859 printf("@ Local socket name: %s/%d\n", inet_ntoa(addr.sin_addr),
860 ntohs(addr.sin_port));
861 return (0);
864 static int
865 st_getsockopt(void)
867 char *tmp;
868 int opt, opt_level, opt_val;
869 socklen_t opt_len;
871 if (g_sock_fd == NO_OPENED_SOCKET) {
872 printf("! No socket opened\n");
873 return (-1);
876 if ((tmp = strtok(NULL, " ")) == NULL) {
877 printf("! No option given\n");
878 return (-1);
880 if (st_match_option(tmp, &opt, &opt_level) < 0) {
881 return (-1);
884 opt_len = sizeof (opt_val);
885 if (st_local_getsockopt(g_sock_fd, opt_level, opt, &opt_val,
886 &opt_len) < 0) {
887 printf("! Cannot get option: %d\n", errno);
888 return (-1);
890 printf("@ Option value is %d\n", opt_val);
891 return (-1);
894 static int
895 st_sock_close(void)
897 if (g_sock_fd == NO_OPENED_SOCKET) {
898 printf("! No socket opened\n");
899 return (-1);
901 if (st_local_socket_close(g_sock_fd) < 0) {
902 printf("! Error in closing socket: %d\n", errno);
903 return (-1);
905 printf("@ Socket closed");
906 if (save_g_sock_fd != NO_OPENED_SOCKET) {
907 g_sock_fd = save_g_sock_fd;
908 save_g_sock_fd = NO_OPENED_SOCKET;
909 printf(", switching to saved socket descriptor\n");
910 } else {
911 g_sock_fd = NO_OPENED_SOCKET;
912 printf("\n");
914 return (0);
917 static int
918 st_toggle_promiscuous(void)
920 /* We always start with non-promiscuous mode. */
921 static boolean_t promiscuous = B_FALSE;
923 promiscuous = !promiscuous;
924 (void) ipv4_setpromiscuous(promiscuous);
925 printf("@ Setting promiscuous to %d\n", promiscuous);
926 return (0);
929 static int
930 st_use_obp(void)
932 if ((use_obp = !use_obp) == B_TRUE) {
933 printf("@ Now using OBP routines\n");
934 } else {
935 printf("@ Now using socket routines\n");
937 return (0);
940 static int
941 st_tcp_tw_report(void)
943 printf("@ TCP Time Wait report\n");
944 tcp_time_wait_report();
945 return (0);