/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* sock_test.c. Implementing a CLI for inetboot testing.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "socket_impl.h"
#include "socket_inet.h"
#include <sys/sysmacros.h>
#include <netinet/in_systm.h>
#include <ctype.h>
#include <errno.h>
#include "tcp_inet.h"
#include "ipv4.h"
static int atoi(const char *);
static int st_accept(void);
static int st_bind(void);
static int st_connect(void);
static int st_echo(void);
static int st_getsockname(void);
static int st_getsockopt(void);
static int st_get_addr_and_port(in_addr_t *, unsigned short *);
static int st_get_buf_and_cnt(char **, int *);
static int st_listen(void);
static int st_match_option(char *, int *, int *);
static int st_send(void);
static int st_sendto(void);
static int st_recv(void);
static int st_recvfrom(void);
static int st_set_addr(void);
static int st_set_netmask(void);
static int st_set_router(void);
static int st_setsockopt(void);
static int st_socket(void);
static int st_sock_close(void);
static int st_tcp_tw_report(void);
static int st_toggle_promiscuous(void);
static int st_use_obp(void);
/* Wrapper for socket calls. */
static int st_local_getsockopt(int, int, int, void *, socklen_t *);
static int st_local_listen(int, int);
static int st_local_recv(int, void *, size_t, int);
socklen_t *);
static int st_local_send(int, const void *, size_t, int);
static int st_local_sendto(int, const void *, size_t, int,
static int st_local_setsockopt(int, int, int, const void *, socklen_t);
static int st_local_socket(int, int, int);
static int st_local_socket_close(int);
struct sock_test_cmd_s {
char *st_cmd;
int (*st_fn)(void);
};
{ "set_addr", st_set_addr},
{ "set_netmask", st_set_netmask},
{ "set_router", st_set_router},
{ "socket", st_socket },
{ "bind", st_bind },
{ "accept", st_accept },
{ "connect", st_connect },
{ "listen", st_listen },
{ "send", st_send },
{ "sendto", st_sendto },
{ "recv", st_recv },
{ "recvfrom", st_recvfrom },
{ "setsockopt", st_setsockopt },
{ "getsockopt", st_getsockopt },
{ "getsockname", st_getsockname },
{ "close", st_sock_close },
{ "echo", st_echo },
{ "toggle_promiscous", st_toggle_promiscuous},
{ "use_obp", st_use_obp},
{ "tcp_tw_report", st_tcp_tw_report},
};
struct so_option_string_s {
char *so_name;
int so_opt;
int so_opt_level;
} so_option_array[] = {
{ NULL, 0 }
};
/* Right now, we only allow one socket at one time. */
/* Boolean to decide if OBP network routines should be used. */
/*
* The following routines are wrappers for the real socket routines. The
* boolean use_obp is used to decide whether the real socket routines is
* called or the "equivalent" OBP provided routines should be called.
*/
static int
{
if (!use_obp) {
} else {
return (0);
}
}
static int
{
if (!use_obp) {
return (socket_close(sd));
} else {
return (0);
}
}
static int
{
if (!use_obp) {
} else {
return (0);
}
}
static int
{
if (!use_obp) {
} else {
return (0);
}
}
static int
{
if (!use_obp) {
} else {
return (0);
}
}
static int
{
if (!use_obp) {
} else {
return (0);
}
}
static int
{
if (!use_obp) {
} else {
return (0);
}
}
static int
{
if (!use_obp) {
} else {
return (0);
}
}
static int
{
if (!use_obp) {
} else {
return (0);
}
}
static int
{
if (!use_obp) {
} else {
return (0);
}
}
static int
{
if (!use_obp) {
} else {
return (0);
}
}
static int
{
if (!use_obp) {
} else {
return (0);
}
}
static int
{
if (!use_obp) {
} else {
return (0);
}
}
static int
atoi(const char *p)
{
int n;
int c = *p++, neg = 0;
while (isspace(c)) {
c = *p++;
}
if (!isdigit(c)) {
switch (c) {
case '-':
neg++;
/* FALLTHROUGH */
case '+':
c = *p++;
}
}
for (n = 0; isdigit(c); c = *p++) {
n *= 10; /* two steps to avoid unnecessary overflow */
n += '0' - c; /* accum neg to avoid surprises at MAX */
}
return (neg ? n : -n);
}
int
{
char *cmd;
int i;
return (-1);
}
}
return (-1);
}
static int
st_socket(void)
{
char *type;
printf("! usage: socket type\n");
return (-1);
}
if (g_sock_fd != NO_OPENED_SOCKET) {
printf("! Cannot open more than 1 socket\n");
return (-1);
}
0)) < 0) {
return (-1);
} else {
printf("@ TCP socket opened\n");
}
0)) < 0) {
return (-1);
} else {
printf("@ UDP socket opened\n");
}
return (-1);
} else {
printf("@ RAW socket opened\n");
}
} else {
return (-1);
}
return (0);
}
static int
st_set_addr(void)
{
char *tmp;
printf("! No address given\n");
return (-1);
}
printf("! Malformed address\n");
return (-1);
}
return (0);
}
static int
st_set_netmask(void)
{
char *tmp;
printf("! No netmask given\n");
return (-1);
}
printf("! Malformed netmask\n");
return (-1);
}
return (0);
}
static int
st_set_router(void)
{
char *tmp;
printf("! No router address given\n");
return (-1);
}
printf("! Malformed router address\n");
return (-1);
}
printf("! Cannot add default route\n");
} else {
}
return (0);
}
static int
{
char *tmp;
if (g_sock_fd == NO_OPENED_SOCKET) {
printf("! No socket opened\n");
return (-1);
}
printf("! No address given\n");
return (-1);
}
printf("! Malformed address\n");
return (-1);
}
printf("! No port given\n");
return (-1);
}
return (0);
}
static int
st_bind(void)
{
&(local_addr.sin_port)) < 0) {
return (-1);
}
sizeof (local_addr)) < 0) {
return (-1);
}
return (0);
}
static int
st_listen(void)
{
char *tmp;
if (g_sock_fd == NO_OPENED_SOCKET) {
printf("! No socket opened\n");
return (-1);
}
printf("! No backlog given\n");
return (-1);
}
return (-1);
}
printf("@ Listen succeeded\n");
return (0);
}
static int
st_accept(void)
{
int sd;
if (g_sock_fd == NO_OPENED_SOCKET) {
printf("! No socket opened\n");
return (-1);
}
addr_len = sizeof (struct sockaddr_in);
&addr_len)) < 0) {
return (-1);
}
printf("@ Accept succeeded from %s:%d. Socket descriptor saved\n",
return (0);
}
static int
st_connect(void)
{
return (-1);
}
sizeof (peer_addr)) < 0) {
return (-1);
}
return (0);
}
static int
{
char *cnt;
printf("! No send buffer\n");
return (-1);
}
printf("! Missing send length\n");
return (-1);
}
printf("! Invalid send count\n");
return (-1);
}
return (0);
}
static int
st_send(void)
{
char *buf;
int send_cnt;
if (g_sock_fd == NO_OPENED_SOCKET) {
printf("! No socket opened\n");
return (-1);
}
return (-1);
return (-1);
}
return (0);
}
static int
st_sendto(void)
{
char *buf;
int send_cnt;
return (-1);
}
return (-1);
return (-1);
}
return (0);
}
static int
st_recv(void)
{
char *tmp;
char *buf;
if (g_sock_fd == NO_OPENED_SOCKET) {
printf("! No socket opened\n");
return (-1);
}
printf("! No buffer len given\n");
return (-1);
}
return (-1);
}
if (ret == 0) {
return (0);
}
return (-1);
}
return (0);
}
static int
st_recvfrom(void)
{
char *tmp;
char *buf;
if (g_sock_fd == NO_OPENED_SOCKET) {
printf("! No socket opened\n");
return (-1);
}
printf("! No buffer len given\n");
return (-1);
}
return (-1);
}
if (ret == 0) {
return (0);
}
return (-1);
}
printf("@ Bytes received from %s/%d: %d\n",
return (0);
}
/*
* To act as an echo server. Note that it assumes the address and
* netmask have been set.
*/
static int
st_echo(void)
{
char *tmp;
int echo_port;
char *buf;
printf("! No echo port given\n");
return (-1);
}
printf("! No buffer size given\n");
return (-1);
}
/* Create local socket for echo server */
return (-1);
} else {
printf("@ Local TCP socket opened\n");
}
/* Bind local socket */
sizeof (addr)) < 0) {
return (-1);
}
return (-1);
}
&addr_size)) < 0) {
(void) st_local_socket_close(listen_fd);
return (-1);
}
(void) st_local_socket_close(listen_fd);
(void) st_local_socket_close(newfd);
return (-1);
}
return (-1);
}
}
(void) st_local_socket_close(newfd);
if (ret < 0) {
return (-1);
} else {
return (0);
}
}
static int
{
int i;
return (0);
}
}
printf("! Unknown option\n");
return (-1);
}
static int
st_setsockopt(void)
{
char *tmp;
if (g_sock_fd == NO_OPENED_SOCKET) {
printf("! No socket opened\n");
return (-1);
}
printf("! No option given\n");
return (-1);
}
return (-1);
}
/* We only support integer option for the moment. */
printf("! No option value given\n");
return (-1);
}
sizeof (int)) < 0) {
return (-1);
}
printf("@ Option set successfully\n");
return (0);
}
static int
st_getsockname(void)
{
if (g_sock_fd == NO_OPENED_SOCKET) {
printf("! No socket opened\n");
return (-1);
}
&len) < 0) {
return (-1);
}
return (0);
}
static int
st_getsockopt(void)
{
char *tmp;
if (g_sock_fd == NO_OPENED_SOCKET) {
printf("! No socket opened\n");
return (-1);
}
printf("! No option given\n");
return (-1);
}
return (-1);
}
&opt_len) < 0) {
return (-1);
}
return (-1);
}
static int
st_sock_close(void)
{
if (g_sock_fd == NO_OPENED_SOCKET) {
printf("! No socket opened\n");
return (-1);
}
if (st_local_socket_close(g_sock_fd) < 0) {
return (-1);
}
printf("@ Socket closed");
if (save_g_sock_fd != NO_OPENED_SOCKET) {
printf(", switching to saved socket descriptor\n");
} else {
printf("\n");
}
return (0);
}
static int
st_toggle_promiscuous(void)
{
/* We always start with non-promiscuous mode. */
(void) ipv4_setpromiscuous(promiscuous);
return (0);
}
static int
st_use_obp(void)
{
printf("@ Now using OBP routines\n");
} else {
printf("@ Now using socket routines\n");
}
return (0);
}
static int
st_tcp_tw_report(void)
{
printf("@ TCP Time Wait report\n");
return (0);
}