amiga-roadshow/examples/ShowNetStatus.c

2963 lines
78 KiB
C

/*
* $Id: ShowNetStatus.c,v 1.16 2007-08-26 12:30:16 obarthel Exp $
*
* :ts=4
*
* Copyright © 2001-2007 by Olaf Barthel. All Rights Reserved.
*/
#include <libraries/bsdsocket.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <dos/dosasl.h>
#include <dos/rdargs.h>
#include <dos/stdio.h>
#include <devices/sana2.h>
/****************************************************************************/
#if defined(__amigaos4__)
#include <dos/obsolete.h>
#endif /* __amigaos4__ */
/****************************************************************************/
#if !defined(__amigaos4__)
#define NO_INLINE_STDARG
#endif /* __amigaos4__ */
#define __NOLIBBASE__
#define __NOGLOBALIFACE__
#define __USE_INLINE__
/****************************************************************************/
#include <proto/bsdsocket.h>
#include <proto/utility.h>
#include <proto/locale.h>
#include <proto/exec.h>
#include <proto/dos.h>
/****************************************************************************/
#include <string.h>
#include <stdarg.h>
/****************************************************************************/
#include <netdb.h>
#include <net/route.h>
#include <net/if_dl.h>
#include <netinet/icmp_var.h>
#include <netinet/igmp_var.h>
#include <netinet/ip_mroute.h>
#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#include <netinet/tcp_var.h>
#include <netinet/udp_var.h>
#include <netinet/tcp_fsm.h>
#include <sys/mbuf.h>
/****************************************************************************/
#include "macros.h"
/****************************************************************************/
#include "ShowNetStatus_rev.h"
/****************************************************************************/
#ifndef AbsExecBase
#define AbsExecBase (*(struct ExecBase **)4)
#endif /* AbsExecBase */
/****************************************************************************/
#ifndef FORMAT_DEF
#define FORMAT_DEF 4
#endif /* FORMAT_DEF */
/****************************************************************************/
typedef LONG * NUMBER;
typedef LONG SWITCH;
typedef STRPTR KEY;
/****************************************************************************/
struct CommandContext
{
struct Library * cc_SysBase;
struct Library * cc_DOSBase;
struct Library * cc_UtilityBase;
struct Library * cc_SocketBase;
struct Library * cc_LocaleBase;
#if defined(__amigaos4__)
/************************************************************************/
struct ExecIFace * cc_IExec;
struct DOSIFace * cc_IDOS;
struct UtilityIFace * cc_IUtility;
struct SocketIFace * cc_ISocket;
struct LocaleIFace * cc_ILocale;
/************************************************************************/
#endif /* __amigaos4__ */
struct Catalog * cc_Catalog;
struct Locale * cc_Locale;
UBYTE cc_ProgramName[256];
UBYTE * cc_QueryBuffer;
LONG cc_QueryBufferSize;
BOOL cc_Stopped;
BOOL cc_HaveDomain;
STRPTR cc_Domain;
STRPTR cc_Line1;
STRPTR cc_Line2;
BOOL cc_NoNames;
BOOL cc_Something;
BOOL cc_Quiet;
};
/****************************************************************************/
#if defined(__amigaos4__)
/****************************************************************************/
#define DECLARE_SYSBASE(cc) \
struct ExecIFace * IExec = cc->cc_IExec; \
struct Library * SysBase = cc->cc_SysBase
#define DECLARE_DOSBASE(cc) \
struct DOSIFace * IDOS = cc->cc_IDOS; \
struct Library * DOSBase = cc->cc_DOSBase
#define DECLARE_UTILITYBASE(cc) \
struct UtilityIFace * IUtility = cc->cc_IUtility; \
struct Library * UtilityBase = cc->cc_UtilityBase
#define DECLARE_LOCALEBASE(cc) \
struct LocaleIFace * ILocale = cc->cc_ILocale; \
struct Library * LocaleBase = cc->cc_LocaleBase
#define DECLARE_SOCKETBASE(cc) \
struct SocketIFace * ISocket = cc->cc_ISocket; \
struct Library * SocketBase = cc->cc_SocketBase
/****************************************************************************/
#else
/****************************************************************************/
#define DECLARE_SYSBASE(cc) \
struct Library * SysBase = cc->cc_SysBase
#define DECLARE_DOSBASE(cc) \
struct Library * DOSBase = cc->cc_DOSBase
#define DECLARE_UTILITYBASE(cc) \
struct Library * UtilityBase = cc->cc_UtilityBase
#define DECLARE_LOCALEBASE(cc) \
struct Library * LocaleBase = cc->cc_LocaleBase
#define DECLARE_SOCKETBASE(cc) \
struct Library * SocketBase = cc->cc_SocketBase
/****************************************************************************/
#endif /* __amigaos4__ */
/****************************************************************************/
LONG _start(VOID);
/****************************************************************************/
STATIC VOID close_libs(struct CommandContext *cc);
STATIC LONG open_libs(struct CommandContext *cc, struct Library *SysBase);
LONG cmd(struct CommandContext *cc);
STATIC STRPTR begin_underline(struct CommandContext *cc);
STATIC STRPTR end_underline(struct CommandContext *cc);
STATIC ULONG divide_64_by_32(SBQUAD_T *dividend, ULONG divisor, SBQUAD_T *quotient);
STATIC VOID insert_grouping_characters(struct Locale *loc, STRPTR buffer);
STATIC STRPTR convert_quad_to_string(struct Locale *loc, const SBQUAD_T *const number, STRPTR string, LONG max_string_len);
STATIC LONG fill_query_buffer(struct CommandContext *cc, LONG type);
STATIC VARARGS68K VOID lprintf(struct CommandContext *cc, STRPTR format, ...);
STATIC VARARGS68K VOID lsprintf(struct CommandContext *cc, STRPTR buffer, STRPTR formatString, ...);
STATIC BOOL is_blank_space(UBYTE c);
STATIC VOID strip_extra_blank_spaces(STRPTR s);
STATIC STRPTR routename(struct CommandContext *cc, ULONG in, STRPTR line, LONG line_size);
STATIC ULONG forgemask(ULONG a);
STATIC STRPTR netname(struct CommandContext *cc, ULONG in, STRPTR line, LONG line_size);
STATIC STRPTR get_sockaddr(struct CommandContext *cc, struct sockaddr *sa, int flags, STRPTR line, LONG line_size);
STATIC VOID print_arp_table(struct CommandContext *cc, struct rt_msghdr *rtm);
STATIC VOID print_route_table(struct CommandContext *cc, struct rt_msghdr *rtm);
STATIC VOID print_dns_list(struct CommandContext *cc, struct List *dns_list);
STATIC VOID print_interface_list(struct CommandContext *cc, struct List *interface_list);
STATIC BOOL print_interface_info(struct CommandContext *cc, STRPTR name);
STATIC VOID print_icmp_status(struct CommandContext *cc, struct icmpstat *icps);
STATIC VOID print_igmp_status(struct CommandContext *cc, struct igmpstat *igps);
STATIC VOID print_ip_status(struct CommandContext *cc, struct ipstat *ips);
STATIC VOID print_mb_status(struct CommandContext *cc, struct mbstat *m);
STATIC VOID print_mrt_status(struct CommandContext *cc, struct mrtstat *mrts);
STATIC VOID print_rt_status(struct CommandContext *cc, struct rtstat *rts);
STATIC VOID print_tcp_status(struct CommandContext *cc, struct tcpstat *tcps);
STATIC VOID print_udp_status(struct CommandContext *cc, struct udpstat *udps);
STATIC VOID print_tcp_socket_status(struct CommandContext *cc, BOOL all_sockets, struct protocol_connection_data *pcd, LONG size);
STATIC VOID print_udp_socket_status(struct CommandContext *cc, BOOL all_sockets, struct protocol_connection_data *pcd, LONG size);
STATIC VOID print_net_status_summary(struct CommandContext *cc);
STATIC LONG VARARGS68K Local_ErrorPrintf(struct CommandContext *cc, STRPTR format, ...);
STATIC STRPTR get_builtin_str(LONG id);
STRPTR get_str(struct CommandContext *cc, LONG id);
STATIC VARARGS68K LONG Local_QueryInterfaceTags(struct CommandContext *cc, STRPTR interface_name, ...);
STATIC VARARGS68K LONG Local_SocketBaseTags(struct CommandContext *cc, ...);
/****************************************************************************/
/****** ROADSHOW/SHOWNETSTATUS **************************************************
*
* NAME
* ShowNetStatus - Display various information about the status of the
* network configuration.
*
* FORMAT
* ShowNetStatus [INTERFACE=<itf>[,<itf>...]] [INTERFACES] [ARPCACHE=ARP]
* [ROUTES] [DNS=DOMAINNAMESERVERS] [ICMP] [IGMP] [IP] [MB=MEMORY]
* [MR=MULTICASTROUTING] [RT=ROUTING] [TCP] [UDP] [TCPSOCKETS]
* [UDPSOCKETS] [NAMES] [ALL] [REPEAT] [QUIET]
*
* TEMPLATE
* INTERFACE/M,INTERFACES/S,ARPCACHE=ARP/S,ROUTES/S,
* DNS=DOMAINNAMESERVERS/S,ICMP/S,IGMP/S,IP/S,MB=MEMORY/S,
* MR=MULTICASTROUTING/S,RT=ROUTING/S,TCP/S,UDP/S,TCPSOCKETS/S,
* UDPSOCKETS/S,NAMES/S,ALL/S,REPEAT/S,QUIET/S
*
* PATH
* C:SHOWNETSTATUS
*
* FUNCTION
* This command can display a lot of informations about the active
* interfaces, either for one interface or for all them. It can be used
* to display the current settings or to give details on the quality of
* the network: transfer speed, number of errors, etc.
*
* You can request which details should be displayed. If you provide
* no options to this command, it will print a general summary of the
* current network status.
*
* OPTIONS
* INTERFACE/M
* For each interface provided in this list, show detailed
* configuration information and statistics.
*
* INTERFACES/S
* Show the list of all interfaces known to the TCP/IP stack.
*
* ARP/S
* Show the contents of the address resolution protocol (ARP) cache.
*
* ROUTES/S
* Show information on the routes that are configured. The
* default route is indicated by having a gateway address
* of 'default'.
*
* DNS=DOMAINNAMESERVERS/S
* Show a list of domain name servers known to the TCP/IP
* stack. Servers are either dynamically configured or
* statically (through the 'DEVS:Interfaces/name_resolution' file).
*
* ICMP/S
* Display Internet Control Message Protocol statistics.
*
* IGMP/S
* Display Internet Group Management Protocol statistics.
*
* IP/S
* Display Internet Protocol statistics.
*
* MB=MEMORY/S
* Display memory buffer statistics.
*
* MR=MULTICASTROUTING/S
* Display multicast routing statistics.
*
* RT=ROUTING/S
* Display routing statistics.
*
* TCP/S
* Display Transmission Control Protocol statistics.
*
* UDP/S
* Display User Datagram Protocol statistics.
*
* TCPSOCKETS/S
* Display information about the TCP sockets currently
* in use. Note that unless you use the 'ALL' option,
* sockets bound to local addresses will not be shown.
*
* UDPSOCKETS/S
* Display information about the UDP sockets currently
* in use. Note that unless you use the 'ALL' option,
* sockets bound to local addresses will not be shown.
*
* NAMES/S
* Attempt to figure out which symbolic names are associated
* with the IP addresses to be printed, and also attempt to
* associate port numbers with service names.
*
* ALL/S
* This option works in conjunction with the TCPSOCKETS and
* UDPSOCKETS parameters. It tells the respective display
* routines to show all currently active sockets, including
* those bound to local addresses.
*
* REPEAT/S
* Repeat the query and display process each second; the
* screen will be cleared before the new information is
* printed. To stop printing the data, press [Ctrl]+C.
*
* QUIET/S
* Do not show any error messages.
*
* EXAMPLES
* Show details on interface "itf".
*
* 1> SHOWNETSTATUS INTERFACE itf
*
* Show details on the Internet Group Management Protocol and routing
* statistics
*
* 1> SHOWNETSTATUS ROUTING IGMP
*
* NOTES
* This command works like a combination of the Unix "route", "ifconfig"
* and "netstat" commands.
*
* Most of the information printed is rather cryptic and not of much
* use to the casual user. It can help in debugging, though.
*
******************************************************************************
*/
LONG
_start(VOID)
{
struct Library *SysBase = (struct Library *)AbsExecBase;
#if defined(__amigaos4__)
struct ExecIFace * IExec = (struct ExecIFace *)((struct ExecBase *)SysBase)->MainInterface;
#endif /* __amigaos4__ */
struct CommandContext _cc,*cc = &_cc;
LONG result = RETURN_FAIL;
struct Process * pr;
LONG error;
memset(cc,0,sizeof(*cc));
pr = (struct Process *)FindTask(NULL);
if(pr->pr_CLI == ZERO)
{
struct MsgPort * mp = &pr->pr_MsgPort;
struct Message * mn;
WaitPort(mp);
mn = GetMsg(mp);
Forbid();
ReplyMsg(mn);
goto out;
}
error = open_libs(cc,SysBase);
if(error == OK)
{
DECLARE_LOCALEBASE(cc);
if(cc->cc_LocaleBase != NULL)
{
cc->cc_Catalog = OpenCatalogA(NULL,"roadshow.catalog",NULL);
cc->cc_Locale = OpenLocale(NULL);
}
result = cmd(cc);
if(cc->cc_QueryBuffer != NULL)
FreeVec(cc->cc_QueryBuffer);
if(cc->cc_Catalog != NULL)
CloseCatalog(cc->cc_Catalog);
if(cc->cc_Locale != NULL)
CloseLocale(cc->cc_Locale);
}
else
{
pr->pr_Result2 = error;
}
close_libs(cc);
out:
return(result);
}
/****************************************************************************/
STATIC VOID
close_libs(struct CommandContext * cc)
{
DECLARE_SYSBASE(cc);
#if defined(__amigaos4__)
{
if(cc->cc_IDOS != NULL)
DropInterface((struct Interface *)cc->cc_IDOS);
if(cc->cc_ILocale != NULL)
DropInterface((struct Interface *)cc->cc_ILocale);
if(cc->cc_ISocket != NULL)
DropInterface((struct Interface *)cc->cc_ISocket);
if(cc->cc_IUtility != NULL)
DropInterface((struct Interface *)cc->cc_IUtility);
}
#endif /* __amigaos4__ */
if(cc->cc_UtilityBase != NULL)
CloseLibrary(cc->cc_UtilityBase);
if(cc->cc_SocketBase != NULL)
CloseLibrary(cc->cc_SocketBase);
if(cc->cc_LocaleBase != NULL)
CloseLibrary(cc->cc_LocaleBase);
if(cc->cc_DOSBase != NULL)
CloseLibrary(cc->cc_DOSBase);
}
/****************************************************************************/
STATIC LONG
open_libs(struct CommandContext * cc,struct Library *SysBase)
{
#if defined(__amigaos4__)
struct ExecIFace * IExec = (struct ExecIFace *)((struct ExecBase *)SysBase)->MainInterface;
#endif /* __amigaos4__ */
LONG error;
cc->cc_SysBase = SysBase;
#if defined(__amigaos4__)
{
cc->cc_IExec = IExec;
}
#endif /* __amigaos4__ */
cc->cc_DOSBase = OpenLibrary("dos.library",36);
#if defined(__amigaos4__)
{
if(cc->cc_DOSBase != NULL)
{
cc->cc_IDOS = (struct DOSIFace *)GetInterface(cc->cc_DOSBase, "main", 1, 0);
if(cc->cc_IDOS == NULL)
{
CloseLibrary(cc->cc_DOSBase);
cc->cc_DOSBase = NULL;
}
}
}
#endif /* __amigaos4__ */
if(cc->cc_DOSBase == NULL)
{
error = ERROR_INVALID_RESIDENT_LIBRARY;
goto out;
}
cc->cc_LocaleBase = OpenLibrary("locale.library",38);
#if defined(__amigaos4__)
{
if(cc->cc_LocaleBase != NULL)
{
cc->cc_ILocale = (struct LocaleIFace *)GetInterface(cc->cc_LocaleBase, "main", 1, 0);
if(cc->cc_ILocale == NULL)
{
CloseLibrary(cc->cc_LocaleBase);
cc->cc_LocaleBase = NULL;
}
}
}
#endif /* __amigaos4__ */
cc->cc_UtilityBase = OpenLibrary("utility.library",37);
#if defined(__amigaos4__)
{
if(cc->cc_UtilityBase != NULL)
{
cc->cc_IUtility = (struct UtilityIFace *)GetInterface(cc->cc_UtilityBase, "main", 1, 0);
if(cc->cc_IUtility == NULL)
{
CloseLibrary(cc->cc_UtilityBase);
cc->cc_UtilityBase = NULL;
}
}
}
#endif /* __amigaos4__ */
/* The following may be necessary to flush out an inoperable
bsdsocket.library which reached the end of the shutdown
process. */
#if 1
{
struct ExecBase * ex = (struct ExecBase *)SysBase;
struct Library * lib;
Forbid();
lib = (struct Library *)FindName(&ex->LibList,"bsdsocket.library");
if(lib != NULL)
RemLibrary(lib);
Permit();
}
#endif
cc->cc_SocketBase = OpenLibrary("bsdsocket.library",4);
#if defined(__amigaos4__)
{
if(cc->cc_SocketBase != NULL)
{
cc->cc_ISocket = (struct SocketIFace *)GetInterface(cc->cc_SocketBase, "main", 1, 0);
if(cc->cc_ISocket == NULL)
{
CloseLibrary(cc->cc_SocketBase);
cc->cc_SocketBase = NULL;
}
}
}
#endif /* __amigaos4__ */
error = OK;
out:
return(error);
}
/****************************************************************************/
#define CATCOMP_ARRAY
#define SHOWNETSTATUS_CATALOG_STRINGS
#include "roadshow.h"
/****************************************************************************/
LONG
cmd(struct CommandContext * cc)
{
struct
{
KEY * Interface;
SWITCH Interfaces;
SWITCH ARP;
SWITCH Routes;
SWITCH DNS;
SWITCH ICMP;
SWITCH IGMP;
SWITCH IP;
SWITCH Memory;
SWITCH MulticastRouting;
SWITCH Routing;
SWITCH TCP;
SWITCH UDP;
SWITCH TCP_Sockets;
SWITCH UDP_Sockets;
SWITCH Names;
SWITCH All;
SWITCH Repeat;
SWITCH Quiet;
} args;
STRPTR args_template =
"INTERFACE/M,"
"INTERFACES/S,"
"ARPCACHE=ARP/S,"
"ROUTES/S,"
"DNS=DOMAINNAMESERVERS/S,"
"ICMP/S,"
"IGMP/S,"
"IP/S,"
"MB=MEMORY/S,"
"MR=MULTICASTROUTING/S,"
"RT=ROUTING/S,"
"TCP/S,"
"UDP/S,"
"TCPSOCKETS/S,"
"UDPSOCKETS/S,"
"NAMES/S,"
"ALL/S,"
"REPEAT/S,"
"QUIET/S"
VERSTAG;
DECLARE_SYSBASE(cc);
DECLARE_DOSBASE(cc);
DECLARE_UTILITYBASE(cc);
DECLARE_SOCKETBASE(cc);
struct List * interface_list = NULL;
struct List * dns_list = NULL;
struct rt_msghdr * route_table = NULL;
LONG result = RETURN_FAIL;
LONG have_status_api = FALSE;
LONG have_routing_api = FALSE;
LONG have_interface_api = FALSE;
LONG have_dns_api = FALSE;
BOOL show_net_status_summary = FALSE;
struct RDArgs * rda;
GetProgramName(cc->cc_ProgramName,sizeof(cc->cc_ProgramName));
memset(&args,0,sizeof(args));
rda = ReadArgs(args_template,(LONG *)&args,NULL);
if(rda == NULL)
{
PrintFault(IoErr(),cc->cc_ProgramName);
goto out;
}
if(args.Interface == NULL &&
args.Interfaces == FALSE &&
args.ARP == FALSE &&
args.Routes == FALSE &&
args.DNS == FALSE &&
args.ICMP == FALSE &&
args.IGMP == FALSE &&
args.IP == FALSE &&
args.Memory == FALSE &&
args.MulticastRouting == FALSE &&
args.Routing == FALSE &&
args.TCP == FALSE &&
args.UDP == FALSE &&
args.TCP_Sockets == FALSE &&
args.UDP_Sockets == FALSE)
{
show_net_status_summary = TRUE;
}
cc->cc_Quiet = args.Quiet;
if(UtilityBase == NULL)
{
if(NOT cc->cc_Quiet)
{
Local_ErrorPrintf(cc,get_str(cc,MSG_SHOWNETSTATUS_NO_UTILITY_TXT),
cc->cc_ProgramName);
}
goto out;
}
if(SocketBase == NULL)
{
if(NOT cc->cc_Quiet)
{
Local_ErrorPrintf(cc,get_str(cc,MSG_SHOWNETSTATUS_CANNOT_OPEN_BSDSOCKET_TXT),
cc->cc_ProgramName);
}
goto out;
}
if(Local_SocketBaseTags(cc,
SBTM_GETREF(SBTC_HAVE_STATUS_API),&have_status_api,
TAG_END) != 0)
{
have_status_api = FALSE;
}
if(NOT have_status_api)
{
if(NOT cc->cc_Quiet)
{
Local_ErrorPrintf(cc,get_str(cc,MSG_SHOWNETSTATUS_BSDSOCKET_HAS_NO_STATUS_API_TXT),
cc->cc_ProgramName, SocketBase->lib_Node.ln_Name, SocketBase->lib_Version, SocketBase->lib_Revision);
}
goto out;
}
if(Local_SocketBaseTags(cc,
SBTM_GETREF(SBTC_HAVE_ROUTING_API),&have_routing_api,
TAG_END) != 0)
{
have_routing_api = FALSE;
}
if(NOT have_routing_api)
{
if(NOT cc->cc_Quiet)
{
Local_ErrorPrintf(cc,get_str(cc,MSG_SHOWNETSTATUS_BSDSOCKET_HAS_NO_ROUTE_API_TXT),
cc->cc_ProgramName, SocketBase->lib_Node.ln_Name, SocketBase->lib_Version, SocketBase->lib_Revision);
}
goto out;
}
if(Local_SocketBaseTags(cc,
SBTM_GETREF(SBTC_HAVE_INTERFACE_API),&have_interface_api,
TAG_END) != 0)
{
have_interface_api = FALSE;
}
if(NOT have_interface_api)
{
if(NOT cc->cc_Quiet)
{
Local_ErrorPrintf(cc,get_str(cc,MSG_SHOWNETSTATUS_BSDSOCKET_HAS_NO_INTERFACE_API_TXT),
cc->cc_ProgramName, SocketBase->lib_Node.ln_Name, SocketBase->lib_Version, SocketBase->lib_Revision);
}
goto out;
}
if(Local_SocketBaseTags(cc,
SBTM_GETREF(SBTC_HAVE_DNS_API),&have_dns_api,
TAG_END) != 0)
{
have_dns_api = FALSE;
}
if(NOT have_dns_api)
{
if(NOT cc->cc_Quiet)
{
Local_ErrorPrintf(cc,get_str(cc,MSG_SHOWNETSTATUS_BSDSOCKET_HAS_NO_DNS_API_TXT),
cc->cc_ProgramName, SocketBase->lib_Node.ln_Name, SocketBase->lib_Version, SocketBase->lib_Revision);
}
goto out;
}
cc->cc_Domain = AllocVec(3 * (MAXHOSTNAMELEN + 1),MEMF_ANY|MEMF_PUBLIC);
if(cc->cc_Domain == NULL)
{
PrintFault(ERROR_NO_FREE_STORE,cc->cc_ProgramName);
goto out;
}
cc->cc_Line1 = cc->cc_Domain + MAXHOSTNAMELEN + 1;
cc->cc_Line2 = cc->cc_Line1 + MAXHOSTNAMELEN + 1;
if(args.Names)
cc->cc_NoNames = FALSE;
else
cc->cc_NoNames = TRUE;
while(TRUE)
{
if(show_net_status_summary)
print_net_status_summary(cc);
if(args.Interface != NULL)
{
STRPTR * key = args.Interface;
STRPTR name;
BOOL failed;
failed = FALSE;
while((name = (*key++)) != NULL)
{
if(CANNOT print_interface_info(cc,name))
{
if(NOT cc->cc_Quiet)
{
Local_ErrorPrintf(cc,get_str(cc,MSG_SHOWNETSTATUS_CANNOT_GET_INFO_ON_INTERFACE_TXT),
cc->cc_ProgramName,name);
}
failed = TRUE;
}
}
if(failed)
goto out;
}
if(args.Interfaces)
{
if(interface_list != NULL)
ReleaseInterfaceList(interface_list);
interface_list = ObtainInterfaceList();
if(interface_list == NULL)
{
if(NOT cc->cc_Quiet)
{
Local_ErrorPrintf(cc,get_str(cc,MSG_SHOWNETSTATUS_CANNOT_GET_INTERFACE_LIST_TXT),
cc->cc_ProgramName);
}
goto out;
}
print_interface_list(cc,interface_list);
}
if(args.DNS)
{
if(dns_list != NULL)
ReleaseDomainNameServerList(dns_list);
dns_list = ObtainDomainNameServerList();
if(dns_list == NULL)
{
if(NOT cc->cc_Quiet)
{
Local_ErrorPrintf(cc,get_str(cc,MSG_SHOWNETSTATUS_CANNOT_GET_DNS_LIST_TXT),
cc->cc_ProgramName);
}
goto out;
}
print_dns_list(cc,dns_list);
}
if(args.Routes)
{
if(route_table != NULL)
FreeRouteInfo(route_table);
route_table = GetRouteInfo(AF_UNSPEC,0);
if(route_table == NULL)
{
if(NOT cc->cc_Quiet)
{
Local_ErrorPrintf(cc,get_str(cc,MSG_SHOWNETSTATUS_CANNOT_GET_ROUTE_TABLE_TXT),
cc->cc_ProgramName);
}
goto out;
}
print_route_table(cc,route_table);
}
if(args.ARP)
{
if(route_table != NULL)
FreeRouteInfo(route_table);
route_table = GetRouteInfo(AF_INET,RTF_LLINFO);
if(route_table == NULL)
{
if(NOT cc->cc_Quiet)
{
Local_ErrorPrintf(cc,get_str(cc,MSG_SHOWNETSTATUS_NO_ARP_INFORMATION_TXT),
cc->cc_ProgramName);
}
goto out;
}
print_arp_table(cc,route_table);
}
if(args.ICMP)
{
if(fill_query_buffer(cc,NETSTATUS_icmp) < 0)
goto out;
print_icmp_status(cc,(struct icmpstat *)cc->cc_QueryBuffer);
if(cc->cc_Stopped)
{
result = RETURN_WARN;
goto out;
}
}
if(args.IGMP)
{
if(fill_query_buffer(cc,NETSTATUS_igmp) < 0)
goto out;
print_igmp_status(cc,(struct igmpstat *)cc->cc_QueryBuffer);
if(cc->cc_Stopped)
{
result = RETURN_WARN;
goto out;
}
}
if(args.IP)
{
if(fill_query_buffer(cc,NETSTATUS_ip) < 0)
goto out;
print_ip_status(cc,(struct ipstat *)cc->cc_QueryBuffer);
if(cc->cc_Stopped)
{
result = RETURN_WARN;
goto out;
}
}
if(args.Memory)
{
if(fill_query_buffer(cc,NETSTATUS_mb) < 0)
goto out;
print_mb_status(cc,(struct mbstat *)cc->cc_QueryBuffer);
if(cc->cc_Stopped)
{
result = RETURN_WARN;
goto out;
}
}
if(args.MulticastRouting)
{
if(fill_query_buffer(cc,NETSTATUS_mrt) < 0)
goto out;
print_mrt_status(cc,(struct mrtstat *)cc->cc_QueryBuffer);
if(cc->cc_Stopped)
{
result = RETURN_WARN;
goto out;
}
}
if(args.Routing)
{
if(fill_query_buffer(cc,NETSTATUS_rt) < 0)
goto out;
print_rt_status(cc,(struct rtstat *)cc->cc_QueryBuffer);
if(cc->cc_Stopped)
{
result = RETURN_WARN;
goto out;
}
}
if(args.TCP)
{
if(fill_query_buffer(cc,NETSTATUS_tcp) < 0)
goto out;
print_tcp_status(cc,(struct tcpstat *)cc->cc_QueryBuffer);
if(cc->cc_Stopped)
{
result = RETURN_WARN;
goto out;
}
}
if(args.UDP)
{
if(fill_query_buffer(cc,NETSTATUS_udp) < 0)
goto out;
print_udp_status(cc,(struct udpstat *)cc->cc_QueryBuffer);
if(cc->cc_Stopped)
{
result = RETURN_WARN;
goto out;
}
}
if(args.TCP_Sockets)
{
LONG size;
size = fill_query_buffer(cc,NETSTATUS_tcp_sockets);
if(size < 0)
goto out;
print_tcp_socket_status(cc,args.All,(struct protocol_connection_data *)cc->cc_QueryBuffer,size);
if(cc->cc_Stopped)
{
result = RETURN_WARN;
goto out;
}
}
if(args.UDP_Sockets)
{
LONG size;
size = fill_query_buffer(cc,NETSTATUS_udp_sockets);
if(size < 0)
goto out;
print_udp_socket_status(cc,args.All,(struct protocol_connection_data *)cc->cc_QueryBuffer,size);
if(cc->cc_Stopped)
{
result = RETURN_WARN;
goto out;
}
}
if(args.Repeat)
{
LONG i;
for(i = 0 ; i < 10 ; i++)
{
Delay(TICKS_PER_SECOND / 10);
if(CheckSignal(SIGBREAKF_CTRL_C))
{
cc->cc_Stopped = TRUE;
PrintFault(ERROR_BREAK,cc->cc_ProgramName);
result = RETURN_WARN;
break;
}
}
if(cc->cc_Stopped)
{
result = RETURN_WARN;
goto out;
}
cc->cc_Something = FALSE;
lprintf(cc,"\f");
}
else
{
break;
}
}
result = RETURN_OK;
out:
FreeVec(cc->cc_Domain);
if(interface_list != NULL)
ReleaseInterfaceList(interface_list);
if(dns_list != NULL)
ReleaseDomainNameServerList(dns_list);
if(route_table != NULL)
FreeRouteInfo(route_table);
if(rda != NULL)
FreeArgs(rda);
return(result);
}
STATIC STRPTR
begin_underline(struct CommandContext * cc)
{
DECLARE_DOSBASE(cc);
STRPTR result;
if(IsInteractive(Output()))
result = "\33[4m";
else
result = "";
return(result);
}
STATIC STRPTR
end_underline(struct CommandContext * cc)
{
DECLARE_DOSBASE(cc);
STRPTR result;
if(IsInteractive(Output()))
result = "\33[0m";
else
result = "";
return(result);
}
/****************************************************************************/
/* Divide a 64 bit integer by a 32 bit integer, filling in a 64 bit quotient
and returning a 32 bit remainder. */
STATIC ULONG
divide_64_by_32(SBQUAD_T * dividend,ULONG divisor,SBQUAD_T * quotient)
{
SBQUAD_T dividend_cdef = (*dividend);
ULONG dividend_ab = 0;
LONG i;
quotient->sbq_High = quotient->sbq_Low = 0;
for(i = 0 ; i < 64 ; i++)
{
/* Shift the quotient left by one bit. */
quotient->sbq_High = (quotient->sbq_High << 1);
if((quotient->sbq_Low & 0x80000000UL) != 0)
quotient->sbq_High |= 1;
quotient->sbq_Low = (quotient->sbq_Low << 1);
/* Shift the dividend left by one bit. We start
with the most significant 32 bit portion. */
dividend_ab = (dividend_ab << 1);
if((dividend_cdef.sbq_High & 0x80000000UL) != 0)
dividend_ab |= 1;
/* Now for the middle 32 bit portion. */
dividend_cdef.sbq_High = (dividend_cdef.sbq_High << 1);
if((dividend_cdef.sbq_Low & 0x80000000UL) != 0)
dividend_cdef.sbq_High |= 1;
/* Finally, the least significant portion. */
dividend_cdef.sbq_Low = (dividend_cdef.sbq_Low << 1);
/* Does the divisor actually divide the dividend? */
if(dividend_ab >= divisor)
{
dividend_ab -= divisor;
/* We could divide the divisor. Keep track of
this and take care of an overflow condition. */
quotient->sbq_Low++;
if(quotient->sbq_Low == 0)
quotient->sbq_High++;
}
}
return(dividend_ab);
}
/****************************************************************************/
STATIC VOID
insert_grouping_characters(struct Locale * loc,STRPTR buffer)
{
if(loc != NULL && loc->loc_Grouping != NULL && loc->loc_GroupSeparator != NULL)
{
UBYTE * grouping = loc->loc_Grouping;
UBYTE * group_separator = loc->loc_GroupSeparator;
UBYTE local_buffer[80];
LONG num_group_digits;
UBYTE * s;
LONG i,len;
/* Check which kind of grouping should be performed
for the first group. */
switch(*grouping)
{
/* Repeat current grouping scheme; there is nothing
to repeat in the first place since we don't even
know yet what we are going to repeat. */
case 0:
return;
/* Perform no further grouping. That means our job is
done! */
case 255:
return;
/* Use this initial group size. */
default:
num_group_digits = (*grouping++);
break;
}
/* Run down the number string, inserting grouping
characters where necessary. */
s = local_buffer;
len = strlen(buffer);
for(i = len-1 ; i >= 0 ; i--)
{
(*s++) = buffer[i];
/* Is this not the last character to be stored?
If so, check if we should insert a grouping
character right now. */
if(i != 0 && num_group_digits > 0)
{
if(--num_group_digits == 0)
{
int j;
/* Insert the group separator in reverse order. */
for(j = strlen(group_separator)-1 ; j >= 0 ; j--)
(*s++) = group_separator[j];
/* Now check which kind of grouping we should
perform next. */
switch(*grouping)
{
/* Repeat current grouping scheme. */
case 0:
num_group_digits = grouping[-1];
break;
/* Perform no further grouping. */
case 255:
break;
/* Use new grouping scheme. */
default:
num_group_digits = (*grouping++);
break;
}
}
}
}
len = (int)(((ULONG)s) - ((ULONG)local_buffer));
for(i = len-1 ; i >= 0 ; i--)
(*buffer++) = local_buffer[i];
(*buffer) = '\0';
}
}
/****************************************************************************/
/* Convert a 64 bit number into a textual representation, using base=10,
just like sprintf(...,"%lD",...) would do if it could handle multiprecision
numbers... */
STATIC STRPTR
convert_quad_to_string(struct Locale * loc,const SBQUAD_T * const number,STRPTR string,LONG max_string_len)
{
SBQUAD_T q;
STRPTR s;
UBYTE c;
ULONG r;
LONG i,len;
/* Make a local copy of the number. */
q = (*number);
s = string;
len = 0;
/* Build the number string in reverse order, calculating
the single digits: */
while(len < max_string_len)
{
/* Divide by ten and remember the remainder. */
r = divide_64_by_32(&q,10,&q);
(*s++) = '0' + r;
len++;
/* Stop when we hit zero. */
if(q.sbq_High == 0 && q.sbq_Low == 0)
break;
}
/* Don't forget to terminate the string. */
(*s) = '\0';
/* Reverse the string in place. */
for(i = 0 ; i < len/2 ; i++)
{
c = string[len-1-i];
string[len-1-i] = string[i];
string[i] = c;
}
insert_grouping_characters(loc,string);
return(string);
}
/****************************************************************************/
STATIC LONG
fill_query_buffer(struct CommandContext * cc,LONG type)
{
DECLARE_SYSBASE(cc);
DECLARE_SOCKETBASE(cc);
LONG size;
size = GetNetworkStatistics(type,NETWORKSTATUS_VERSION,NULL,0);
if(size > 0)
{
if(size > cc->cc_QueryBufferSize)
{
FreeVec(cc->cc_QueryBuffer);
cc->cc_QueryBuffer = AllocVec(size,MEMF_ANY|MEMF_CLEAR);
if(cc->cc_QueryBuffer != NULL)
{
cc->cc_QueryBufferSize = size;
}
else
{
if(NOT cc->cc_Quiet)
{
Local_ErrorPrintf(cc,get_str(cc,MSG_SHOWNETSTATUS_NOT_ENOUGH_MEMORY_TO_QUERY_STATUS_TXT),
cc->cc_ProgramName,get_str(cc,MSG_SHOWNETSTATUS_STATUS_NAME1_TXT + type - NETSTATUS_icmp));
}
size = -1;
goto out;
}
}
size = GetNetworkStatistics(type,NETWORKSTATUS_VERSION,cc->cc_QueryBuffer,size);
}
if(size < 0)
{
if(NOT cc->cc_Quiet)
{
Local_ErrorPrintf(cc,get_str(cc,MSG_SHOWNETSTATUS_CANNOT_GET_STATUS_INFORMATION_FOR_TXT),
cc->cc_ProgramName,get_str(cc,MSG_SHOWNETSTATUS_STATUS_NAME1_TXT + type - NETSTATUS_icmp));
}
}
out:
return(size);
}
/****************************************************************************/
STATIC VARARGS68K VOID
lprintf(struct CommandContext * cc,STRPTR format,...)
{
DECLARE_DOSBASE(cc);
if(NOT cc->cc_Stopped)
{
if(CheckSignal(SIGBREAKF_CTRL_C))
{
PrintFault(ERROR_BREAK,cc->cc_ProgramName);
cc->cc_Stopped = TRUE;
}
}
if(NOT cc->cc_Stopped)
{
va_list args;
#if defined(__amigaos4__)
{
va_startlinear(args,format);
VPrintf(format,va_getlinearva(args,APTR));
va_end(args);
}
#else
{
va_start(args,format);
VPrintf(format,(APTR)args);
va_end(args);
}
#endif /* __amigaos4__ */
}
}
/****************************************************************************/
STATIC VARARGS68K VOID
lsprintf(struct CommandContext * cc,STRPTR buffer,STRPTR formatString,...)
{
DECLARE_SYSBASE(cc);
va_list varArgs;
#if defined(__amigaos4__)
{
va_startlinear(varArgs,formatString);
RawDoFmt(formatString,va_getlinearva(varArgs,APTR),NULL,buffer);
va_end(varArgs);
}
#else
{
va_start(varArgs,formatString);
RawDoFmt(formatString,varArgs,(VOID (*)())"\x16\xC0\x4E\x75",buffer);
va_end(varArgs);
}
#endif /* __amigaos4__ */
}
/****************************************************************************/
STATIC BOOL
is_blank_space(UBYTE c)
{
BOOL result;
result = (BOOL)(c == ' ' || c == '\t' || c == (UBYTE)'\240');
return(result);
}
/****************************************************************************/
STATIC VOID
strip_extra_blank_spaces(STRPTR s)
{
LONG num_leading_spaces;
LONG num_trailing_spaces;
LONG len,i;
len = strlen(s);
num_leading_spaces = 0;
for(i = 0 ; i < len ; i++)
{
if(NOT is_blank_space(s[i]))
break;
num_leading_spaces++;
}
num_trailing_spaces = 0;
for(i = len-1 ; i >= 0 ; i--)
{
if(NOT is_blank_space(s[i]))
break;
num_trailing_spaces++;
}
if(num_trailing_spaces > 0)
{
len -= num_trailing_spaces;
s[len] = '\0';
}
if(num_leading_spaces > 0)
memmove(s,&s[num_leading_spaces],len+1);
}
/****************************************************************************/
#define C(x) ((x) & 0xff)
/****************************************************************************/
STATIC STRPTR
routename(struct CommandContext * cc,ULONG in,STRPTR line,LONG line_size)
{
DECLARE_UTILITYBASE(cc);
DECLARE_SOCKETBASE(cc);
struct hostent *hp;
STRPTR cp;
cp = NULL;
if(NOT cc->cc_NoNames)
{
if(NOT cc->cc_HaveDomain)
{
cc->cc_HaveDomain = TRUE;
if(gethostname(cc->cc_Domain, MAXHOSTNAMELEN) == 0 && (cp = index(cc->cc_Domain, '.')) != NULL)
strcpy(cc->cc_Domain, cp + 1);
else
cc->cc_Domain[0] = '\0';
}
hp = gethostbyaddr((char *)&in, sizeof(struct in_addr), AF_INET);
if(hp != NULL)
{
if((cp = index(hp->h_name, '.')) != NULL && Stricmp(cp + 1, cc->cc_Domain) == SAME)
(*cp) = 0;
cp = hp->h_name;
}
}
if(cp != NULL)
{
strncpy(line, cp, line_size - 1);
line[line_size - 1] = '\0';
}
else
{
in = ntohl(in);
lsprintf(cc, line, "%ld.%ld.%ld.%ld", C(in >> 24), C(in >> 16), C(in >> 8), C(in));
}
return(line);
}
STATIC ULONG
forgemask(ULONG a)
{
ULONG m;
if(IN_CLASSA(a))
m = IN_CLASSA_NET;
else if (IN_CLASSB(a))
m = IN_CLASSB_NET;
else
m = IN_CLASSC_NET;
return (m);
}
/* Return the name of the network whose address is given.
The address is assumed to be that of a net or subnet, not a host. */
STATIC STRPTR
netname(struct CommandContext * cc, ULONG in, STRPTR line, LONG line_size)
{
DECLARE_SOCKETBASE(cc);
STRPTR cp = NULL;
ULONG net;
ULONG i;
i = ntohl(in);
if(NOT cc->cc_NoNames && i)
{
ULONG mask;
int subnetshift;
mask = forgemask(i);
switch(mask)
{
case IN_CLASSA_NET:
subnetshift = 8;
break;
case IN_CLASSB_NET:
subnetshift = 8;
break;
case IN_CLASSC_NET:
subnetshift = 4;
break;
default:
subnetshift = 0;
break;
}
if(subnetshift > 0)
{
struct netent *np;
/* If there are more bits than the standard mask
would suggest, subnets must be in use.
Guess at the subnet mask, assuming reasonable
width subnet fields. */
while(i &~ mask)
mask = (long)mask >> subnetshift;
net = i & mask;
while((mask & 1) == 0)
mask >>= 1, net >>= 1;
np = getnetbyaddr(net, AF_INET);
if(np != NULL)
cp = np->n_name;
}
}
if(cp != NULL)
{
strncpy(line, cp, line_size - 1);
line[line_size - 1] = '\0';
}
else if ((i & 0xffffff) == 0)
{
lsprintf(cc, line, "%ld", C(i >> 24));
}
else if ((i & 0xffff) == 0)
{
lsprintf(cc, line, "%ld.%ld", C(i >> 24) , C(i >> 16));
}
else if ((i & 0xff) == 0)
{
lsprintf(cc, line, "%ld.%ld.%ld", C(i >> 24), C(i >> 16), C(i >> 8));
}
else
{
lsprintf(cc, line, "%ld.%ld.%ld.%ld", C(i >> 24), C(i >> 16), C(i >> 8), C(i));
}
return (line);
}
STATIC STRPTR
get_sockaddr(struct CommandContext * cc,struct sockaddr * sa,int flags,STRPTR line,LONG line_size)
{
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
STRPTR result;
if(sin->sin_addr.s_addr == INADDR_ANY)
result = get_str(cc,MSG_SHOWNETSTATUS_DEFAULT_TXT);
else if (flags & RTF_HOST)
result = routename(cc,sin->sin_addr.s_addr,line,line_size);
else
result = netname(cc,sin->sin_addr.s_addr,line,line_size);
return(result);
}
/****************************************************************************/
STATIC VOID
print_arp_table(struct CommandContext * cc,struct rt_msghdr *rtm)
{
DECLARE_SOCKETBASE(cc);
char *host;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
struct hostent *hp;
char address[24];
LONG n,c;
BOOL no_names;
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
no_names = cc->cc_NoNames;
for(n = 0 ;
rtm->rtm_msglen > 0 ;
rtm = (struct rt_msghdr *)(((ULONG)rtm) + rtm->rtm_msglen))
{
sin = (struct sockaddr_inarp *)(rtm + 1);
sdl = (struct sockaddr_dl *)(sin + 1);
host = get_str(cc,MSG_SHOWNETSTATUS_UNKNOWN_HOST_TXT);
if(NOT no_names)
{
hp = gethostbyaddr((APTR)&sin->sin_addr, sizeof (sin->sin_addr), AF_INET);
if(hp != NULL)
{
host = hp->h_name;
}
else
{
LONG h_errno;
Local_SocketBaseTags(cc,
SBTM_GETREF(SBTC_HERRNO),&h_errno,
TAG_END);
if(h_errno == TRY_AGAIN)
no_names = TRUE;
}
}
if(n++ == 0)
{
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ARP_HEADER_TXT),
begin_underline(cc),
get_str(cc,MSG_SHOWNETSTATUS_HOST_TXT),
get_str(cc,MSG_SHOWNETSTATUS_IP_ADDRESS_TXT),
get_str(cc,MSG_SHOWNETSTATUS_HARDWARE_ADDRESS_TXT),
get_str(cc,MSG_SHOWNETSTATUS_ATTRIBUTES_TXT),
end_underline(cc));
lprintf(cc,"\n");
}
if(sdl->sdl_alen > 0)
{
UBYTE * m;
m = (UBYTE *)LLADDR(sdl);
lsprintf(cc,address,"%02lx:%02lx:%02lx:%02lx:%02lx:%02lx",m[0],m[1],m[2],m[3],m[4],m[5]);
}
else
{
strcpy(address,get_str(cc,MSG_SHOWNETSTATUS_INCOMPLETE_HARDWARE_ADDRESS_TXT));
}
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ARP_HEADER_TXT),
"",
host,
Inet_NtoA(sin->sin_addr.s_addr),
address,
"",
"");
c = 0;
if (rtm->rtm_rmx.rmx_expire == 0)
{
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ARP_ENTRY_PERMANENT_TXT));
c++;
}
if (sin->sin_other & SIN_PROXY)
{
if(c != 0)
lprintf(cc,", ");
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ARP_ENTRY_PUBLISHED_PROXY_TXT));
c++;
}
if (rtm->rtm_addrs & RTA_NETMASK)
{
sin = (struct sockaddr_inarp *)(sdl->sdl_len + (char *)sdl);
if (sin->sin_addr.s_addr == 0xffffffff)
{
if(c != 0)
lprintf(cc,", ");
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ARP_ENTRY_PUBLISHED_TXT));
c++;
}
}
if(c == 0)
lprintf(cc,"-");
lprintf(cc,"\n");
}
if(n == 0)
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ARP_CACHE_EMPTY_TXT));
}
/****************************************************************************/
STATIC VOID
print_route_table(struct CommandContext * cc,struct rt_msghdr * rtm)
{
struct sockaddr * sa;
STRPTR gateway,destination;
LONG n;
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
for(n = 0 ;
rtm->rtm_msglen > 0 ;
rtm = (struct rt_msghdr *)(((ULONG)rtm) + rtm->rtm_msglen))
{
if(rtm->rtm_version != 3 || (rtm->rtm_addrs & RTA_DST) == 0)
continue;
sa = (struct sockaddr *)(rtm + 1);
if(sa->sa_family != AF_INET)
continue;
if((rtm->rtm_addrs & RTA_GATEWAY) != 0)
{
LONG len;
destination = get_sockaddr(cc,sa,rtm->rtm_flags,cc->cc_Line1,MAXHOSTNAMELEN);
if(sa->sa_len == 0)
len = sizeof(long);
else
len = sa->sa_len;
sa = (struct sockaddr *)(((ULONG)sa) + len);
if(sa->sa_family != AF_INET)
continue;
gateway = get_sockaddr(cc,sa,rtm->rtm_flags,cc->cc_Line2,MAXHOSTNAMELEN);
}
else
{
destination = get_sockaddr(cc,sa,rtm->rtm_flags,cc->cc_Line1,MAXHOSTNAMELEN);
gateway = "-";
}
if(n++ == 0)
{
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_DESTINATION_GATEWAY_ATTRIBUTES_TITLE_TXT),
begin_underline(cc),
get_str(cc,MSG_SHOWNETSTATUS_DESTINATION_TXT),
get_str(cc,MSG_SHOWNETSTATUS_GATEWAY_TXT),
get_str(cc,MSG_SHOWNETSTATUS_ATTRIBUTES_TXT),
end_underline(cc));
}
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_DESTINATION_GATEWAY_LINE_TXT),destination,gateway);
lprintf(cc," ");
if(rtm->rtm_flags & RTF_UP)
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_UP_TXT));
else
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_DOWN_TXT));
if(rtm->rtm_flags & RTF_GATEWAY)
{
lprintf(cc," ");
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_GATEWAY_TXT));
}
if(rtm->rtm_flags & RTF_HOST)
{
lprintf(cc," ");
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_HOST_TXT));
}
lprintf(cc,"\n");
}
if(n == 0)
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_NO_ROUTES_ARE_CONFIGURED_TXT));
}
/****************************************************************************/
STATIC VOID
print_dns_list(struct CommandContext * cc,struct List * dns_list)
{
DECLARE_SOCKETBASE(cc);
struct DomainNameServerNode * dnsn;
UBYTE default_domain_name[MAXHOSTNAMELEN];
LONG n;
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
n = 0;
for(dnsn = (struct DomainNameServerNode *)dns_list->lh_Head ;
dnsn->dnsn_MinNode.mln_Succ != NULL ;
dnsn = (struct DomainNameServerNode *)dnsn->dnsn_MinNode.mln_Succ)
{
if(n++ == 0)
{
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ADDRESS_TYPE_TITLE_TXT),
begin_underline(cc),
get_str(cc,MSG_SHOWNETSTATUS_ADDRESS_TXT),
get_str(cc,MSG_SHOWNETSTATUS_TYPE_TXT),
end_underline(cc));
}
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ADDRESS_TYPE_LINE_TXT),routename(cc,inet_addr(dnsn->dnsn_Address),cc->cc_Line1,MAXHOSTNAMELEN),
get_str(cc,(dnsn->dnsn_UseCount < 0) ? MSG_SHOWNETSTATUS_STATIC_TXT : MSG_SHOWNETSTATUS_DYNAMIC_TXT));
}
if(n == 0)
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_NO_DNS_CONFIGURED_TXT));
strcpy(default_domain_name,"");
GetDefaultDomainName(default_domain_name,sizeof(default_domain_name));
lprintf(cc,
get_str(cc,default_domain_name[0] != '\0' ? MSG_SHOWNETSTATUS_DEFAULT_DOMAIN_NAME_TXT : MSG_SHOWNETSTATUS_DEFAULT_DOMAIN_NAME_UNSET_TXT),
default_domain_name);
}
/****************************************************************************/
struct { LONG Number; STRPTR Name;} hardware_types[] =
{
{ S2WireType_Ethernet, "Ethernet" },
{ S2WireType_IEEE802, "IEEE 802" },
{ S2WireType_Arcnet, "Arcnet" },
{ S2WireType_LocalTalk, "LocalTalk" },
{ S2WireType_DyLAN, "DyLAN" },
{ S2WireType_AmokNet, "AmokNet" },
{ S2WireType_Liana, "Liana" },
{ S2WireType_PPP, "PPP" },
{ S2WireType_SLIP, "SLIP" },
{ S2WireType_CSLIP, "CSLIP" },
{ S2WireType_PLIP, "PLIP" }
};
/****************************************************************************/
STATIC VOID
print_interface_list(struct CommandContext * cc,struct List * interface_list)
{
UBYTE type_buffer[80];
STRPTR type;
struct Node * node;
struct sockaddr_in sin;
LONG mtu;
LONG hardware_type;
ULONG sent;
ULONG received;
ULONG bad;
ULONG overrun;
ULONG unknown;
LONG state;
LONG i;
STRPTR addr;
LONG n = 0;
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
for(node = interface_list->lh_Head ;
node->ln_Succ != NULL ;
node = node->ln_Succ)
{
memset(&sin,0,sizeof(sin));
mtu = hardware_type = received = sent = bad = overrun = unknown = state = 0;
if(Local_QueryInterfaceTags(cc,node->ln_Name,
IFQ_MTU, &mtu,
IFQ_HardwareType, &hardware_type,
IFQ_PacketsReceived, &received,
IFQ_PacketsSent, &sent,
IFQ_BadData, &bad,
IFQ_Overruns, &overrun,
IFQ_UnknownTypes, &unknown,
IFQ_Address, &sin,
IFQ_State, &state,
TAG_DONE) != 0)
{
continue;
}
type = NULL;
for(i = 0 ; i < (LONG)NUM_ENTRIES(hardware_types) ; i++)
{
if(hardware_types[i].Number == hardware_type)
{
type = hardware_types[i].Name;
break;
}
}
if(type == NULL)
lsprintf(cc,type = type_buffer,get_str(cc,MSG_SHOWNETSTATUS_UNKNOWN_HARDWARE_TYPE_TXT),hardware_type);
if(sin.sin_addr.s_addr != INADDR_ANY)
addr = routename(cc,sin.sin_addr.s_addr,cc->cc_Line1,MAXHOSTNAMELEN);
else
addr = "-";
if(n++ == 0)
{
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_TITLE_TXT),
begin_underline(cc),
get_str(cc,MSG_SHOWNETSTATUS_NAME_TXT),
get_str(cc,MSG_SHOWNETSTATUS_MTU_TXT),
get_str(cc,MSG_SHOWNETSTATUS_TYPE_TXT),
get_str(cc,MSG_SHOWNETSTATUS_ADDRESS_TXT),
get_str(cc,MSG_SHOWNETSTATUS_RECEIVED_TXT),
get_str(cc,MSG_SHOWNETSTATUS_SENT_TXT),
get_str(cc,MSG_SHOWNETSTATUS_DROPPED_TXT),
get_str(cc,MSG_SHOWNETSTATUS_OVERRUNS_TXT),
get_str(cc,MSG_SHOWNETSTATUS_UNKNOWN_TXT),
get_str(cc,MSG_SHOWNETSTATUS_STATUS_TXT),
end_underline(cc));
}
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_LINE_TXT),
node->ln_Name,mtu,type,addr,received,sent,bad,overrun,unknown,get_str(cc,(state == SM_Up) ? MSG_SHOWNETSTATUS_UP_TXT : MSG_SHOWNETSTATUS_DOWN_TXT));
}
if(n == 0)
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_NO_INTERFACES_AVAILABLE_TXT));
}
STATIC BOOL
print_interface_info(struct CommandContext * cc,STRPTR name)
{
DECLARE_DOSBASE(cc);
DECLARE_SOCKETBASE(cc);
struct SANA2CopyStats s2cs;
UBYTE type_buffer[80];
STRPTR type;
struct sockaddr_in sin;
struct sockaddr_in sin_peer;
struct sockaddr_in sin_mask;
LONG bps;
UBYTE hardware_address[16];
LONG hardware_address_size;
STRPTR device_name;
LONG device_unit;
LONG mtu;
LONG hardware_type;
ULONG sent;
ULONG received;
ULONG bad;
ULONG overrun;
ULONG unknown;
LONG bind_type;
struct DateStamp lease_expire;
LONG num_read_requests;
LONG max_read_requests;
LONG num_pending_read_requests;
LONG num_write_requests;
LONG max_write_requests;
LONG num_pending_write_requests;
LONG state;
LONG i;
SBQUAD_T bytes_in;
SBQUAD_T bytes_out;
UBYTE byte_count[80];
BOOL success;
BOOL have_peer_address;
LONG input_dropped = 0;
LONG output_dropped = 0;
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
memset(&sin,0,sizeof(sin));
memset(&sin_peer,0,sizeof(sin_peer));
memset(&sin_mask,0,sizeof(sin_mask));
memset(hardware_address,0,sizeof(hardware_address));
device_name = NULL;
device_unit = 0;
hardware_address_size = mtu = bps = hardware_type = received = sent = bad = overrun = unknown = state = 0;
bind_type = IFABT_Unknown;
memset(&lease_expire,0,sizeof(lease_expire));
memset(&s2cs,0,sizeof(s2cs));
if(Local_QueryInterfaceTags(cc,name,
IFQ_DeviceName, &device_name,
IFQ_DeviceUnit, &device_unit,
IFQ_HardwareAddressSize, &hardware_address_size,
IFQ_HardwareAddress, hardware_address,
IFQ_MTU, &mtu,
IFQ_BPS, &bps,
IFQ_HardwareType, &hardware_type,
IFQ_PacketsReceived, &received,
IFQ_PacketsSent, &sent,
IFQ_BadData, &bad,
IFQ_Overruns, &overrun,
IFQ_UnknownTypes, &unknown,
IFQ_Address, &sin,
IFQ_NetMask, &sin_mask,
IFQ_State, &state,
IFQ_AddressBindType, &bind_type,
IFQ_AddressLeaseExpires, &lease_expire,
IFQ_NumReadRequests, &num_read_requests,
IFQ_MaxReadRequests, &max_read_requests,
IFQ_NumReadRequestsPending, &num_pending_read_requests,
IFQ_NumWriteRequests, &num_write_requests,
IFQ_MaxWriteRequests, &max_write_requests,
IFQ_NumWriteRequestsPending, &num_pending_write_requests,
IFQ_GetBytesIn, &bytes_in,
IFQ_GetBytesOut, &bytes_out,
IFQ_GetSANA2CopyStats, &s2cs,
IFQ_InputDrops, &input_dropped,
IFQ_OutputDrops, &output_dropped,
TAG_DONE) != 0)
{
success = FALSE;
goto out;
}
if(hardware_address_size > (LONG)sizeof(hardware_address) * 8)
hardware_address_size = sizeof(hardware_address) * 8;
if(Local_QueryInterfaceTags(cc,name,
IFQ_DestinationAddress,&sin_peer,
TAG_DONE) == 0)
{
have_peer_address = TRUE;
}
else
{
have_peer_address = FALSE;
}
type = NULL;
for(i = 0 ; i < (LONG)NUM_ENTRIES(hardware_types) ; i++)
{
if(hardware_types[i].Number == hardware_type)
{
type = hardware_types[i].Name;
break;
}
}
if(type == NULL)
lsprintf(cc,type = type_buffer,get_str(cc,MSG_SHOWNETSTATUS_UNKNOWN_HARDWARE_TYPE_TXT),hardware_type);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_TITLE_TXT),
begin_underline(cc),
name,
end_underline(cc));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_DEVICE_NAME_TXT),device_name);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_DEVICE_UNIT_TXT),device_unit);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_HARDWARE_ADDRESS_TXT));
if(hardware_address_size == 32)
{
lprintf(cc,"%s",Inet_NtoA(sin.sin_addr.s_addr));
}
else
{
for(i = 0 ; i < hardware_address_size/8 ; i++)
{
if(i != 0)
lprintf(cc,":");
lprintf(cc,"%02lx",hardware_address[i]);
}
}
lprintf(cc,"\n");
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_MTU_TXT),mtu);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_TRANSMISSION_SPEED_TXT),bps);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_HARDWARE_TYPE_TXT),type);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_PACKETS_SENT_TXT),sent);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_PACKETS_RECEIVED_TXT),received);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_PACKETS_DROPPED_TXT),bad,input_dropped,output_dropped);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_BUFFER_OVERRUNS_TXT),overrun);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_UNKNOWN_PACKETS_TXT),unknown);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_ADDRESS_TXT),(sin.sin_addr.s_addr != INADDR_ANY) ? routename(cc,sin.sin_addr.s_addr,cc->cc_Line1,MAXHOSTNAMELEN) : get_str(cc,MSG_SHOWNETSTATUS_NOT_CONFIGURED_TXT));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_NETWORK_MASK_TXT),(sin_mask.sin_addr.s_addr != INADDR_ANY) ? Inet_NtoA(sin_mask.sin_addr.s_addr) : get_str(cc,MSG_SHOWNETSTATUS_NOT_CONFIGURED_TXT));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_NUM_READ_REQUESTS_TXT),num_read_requests,max_read_requests,num_pending_read_requests);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_NUM_WRITE_REQUESTS_TXT),num_write_requests,max_write_requests,num_pending_write_requests);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_NUM_BYTES_RECEIVED_TXT),convert_quad_to_string(cc->cc_Locale,&bytes_in,byte_count,sizeof(byte_count)));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_NUM_BYTES_SENT_TXT),convert_quad_to_string(cc->cc_Locale,&bytes_out,byte_count,sizeof(byte_count)));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_TRANSFER_STATISTICS_TXT),s2cs.s2cs_DMAIn,s2cs.s2cs_DMAOut,s2cs.s2cs_ByteIn,s2cs.s2cs_ByteOut,s2cs.s2cs_WordOut);
if(bind_type == IFABT_Static || bind_type == IFABT_Dynamic)
{
LONG id = (bind_type == IFABT_Static) ? MSG_SHOWNETSTATUS_INTERFACE_INFO_BINDING_STATIC_TXT : MSG_SHOWNETSTATUS_INTERFACE_INFO_BINDING_DYNAMIC_TXT;
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_ADDRESS_BINDING_TXT),get_str(cc,id));
if(bind_type == IFABT_Dynamic)
{
UBYTE buffer[2*LEN_DATSTRING+3];
STRPTR str;
if(lease_expire.ds_Days == 0 &&
lease_expire.ds_Minute == 0 &&
lease_expire.ds_Tick == 0)
{
str = get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_LEASE_NEVER_EXPIRES_TXT);
}
else
{
struct DateTime dat;
UBYTE date[LEN_DATSTRING+1];
UBYTE time[LEN_DATSTRING+1];
memset(&dat,0,sizeof(dat));
dat.dat_Stamp = lease_expire;
dat.dat_Format = FORMAT_DEF;
dat.dat_StrDate = date;
dat.dat_StrTime = time;
DateToStr(&dat);
strip_extra_blank_spaces(date);
strip_extra_blank_spaces(time);
strcpy(buffer,date);
strcat(buffer," ");
strcat(buffer,time);
str = buffer;
}
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_LEASE_EXPIRES_TXT),str);
}
}
if(have_peer_address)
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_PEER_ADDRESS_TXT),(sin_peer.sin_addr.s_addr != INADDR_ANY) ? routename(cc,sin_peer.sin_addr.s_addr,cc->cc_Line1,MAXHOSTNAMELEN) : get_str(cc,MSG_SHOWNETSTATUS_NOT_CONFIGURED_TXT));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_INTERFACE_INFO_STATUS_TXT),get_str(cc,(state == SM_Up) ? MSG_SHOWNETSTATUS_UP_TXT : MSG_SHOWNETSTATUS_DOWN_TXT));
success = TRUE;
out:
return(success);
}
/****************************************************************************/
STATIC VOID
print_icmp_status(struct CommandContext * cc,struct icmpstat *icps)
{
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_TITLE_TXT),begin_underline(cc),end_underline(cc));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_ERRORS_GENERATED_TXT),icps->icps_error);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_IP_PACKETS_TOO_SHORT_TXT),icps->icps_oldshort);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_PACKETS_NOT_RESPONDED_TO_TXT),icps->icps_oldicmp);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_ECHO_REPLY_PACKETS_SENT_TXT),icps->icps_outhist[ICMP_ECHOREPLY]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_DESTINATION_UNREACHABLE_TXT),icps->icps_outhist[ICMP_UNREACH]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_SOURCE_QUENCH_TXT),icps->icps_outhist[ICMP_SOURCEQUENCH]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_REDIRECT_TXT),icps->icps_outhist[ICMP_REDIRECT]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_ECHO_TXT),icps->icps_outhist[ICMP_ECHO]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_ROUTER_ADVERTIZEMENT_TXT),icps->icps_outhist[ICMP_ROUTERADVERT]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_ROUTER_SOLICITATION_TXT),icps->icps_outhist[ICMP_ROUTERSOLICIT]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_TIME_EXCEEDED_TXT),icps->icps_outhist[ICMP_TIMXCEED]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_BAD_IP_HEADER_TXT),icps->icps_outhist[ICMP_PARAMPROB]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_TIMESTAMP_REQUEST_TXT),icps->icps_outhist[ICMP_TSTAMP]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_TIMESTAMP_REPLY_TXT),icps->icps_outhist[ICMP_TSTAMPREPLY]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_INFORMATION_REQUEST_TXT),icps->icps_outhist[ICMP_IREQ]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_INFORMATION_REPLY_TXT),icps->icps_outhist[ICMP_IREQREPLY]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_ADDRESS_MASK_REQUEST_TXT),icps->icps_outhist[ICMP_MASKREQ]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_ADDRESS_MASK_REPLY_TXT),icps->icps_outhist[ICMP_MASKREPLY]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_RECEIVED_CODES_OUT_OF_RANGE_TXT),icps->icps_badcode);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_RECEIVED_PACKETS_TOO_SHORT_TXT),icps->icps_tooshort);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_RECEIVED_PACKET_CHECKSUM_ERRORS_TXT),icps->icps_checksum);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_RECEIVED_CODES_BOUND_MISMATCH_TXT),icps->icps_badlen);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_RESPONSES_SENT_TXT),icps->icps_reflect);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_ECHO_REPLIES_RECEIVED_TXT),icps->icps_inhist[ICMP_ECHOREPLY]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_DESTINATION_UNREACHABLE_RECEIVED_TXT),icps->icps_inhist[ICMP_UNREACH]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_SOURCE_QUENCH_RECEIVED_TXT),icps->icps_inhist[ICMP_SOURCEQUENCH]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_REDIRECT_RECEIVED_TXT),icps->icps_inhist[ICMP_REDIRECT]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_ECHO_RECEIVED_TXT),icps->icps_inhist[ICMP_ECHO]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_ROUTER_ADVERTIZEMENT_RECEIVED_TXT),icps->icps_inhist[ICMP_ROUTERADVERT]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_ROUTER_SOLICITATION_RECEIVED_TXT),icps->icps_inhist[ICMP_ROUTERSOLICIT]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_TIME_EXCEEDED_RECEIVED_TXT),icps->icps_inhist[ICMP_TIMXCEED]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_BAD_IP_HEADER_RECEIVED_TXT),icps->icps_inhist[ICMP_PARAMPROB]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_TIMESTAMP_REQUEST_RECEIVED_TXT),icps->icps_inhist[ICMP_TSTAMP]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_TIMESTAMP_REPLY_RECEIVED_TXT),icps->icps_inhist[ICMP_TSTAMPREPLY]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_INFORMATION_REQUEST_RECEIVED_TXT),icps->icps_inhist[ICMP_IREQ]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_INFORMATION_REPLY_RECEIVED_TXT),icps->icps_inhist[ICMP_IREQREPLY]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_ADDRESS_MASK_REQUEST_RECEIVED_TXT),icps->icps_inhist[ICMP_MASKREQ]);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ICMP_ADDRESS_MASK_REPLY_RECEIVED_TXT),icps->icps_inhist[ICMP_MASKREPLY]);
}
STATIC VOID
print_igmp_status(struct CommandContext * cc,struct igmpstat *igps)
{
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IGMP_TITLE_TXT),begin_underline(cc),end_underline(cc));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IGMP_TOTAL_MESSAGES_RECEIVED_TXT),igps->igps_rcv_total);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IGMP_MESSAGES_RECEIVED_TOO_SHORT_TXT),igps->igps_rcv_tooshort);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IGMP_MESSAGES_RECEIVED_BAD_CHECKSUM_TXT),igps->igps_rcv_badsum);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IGMP_MEMBERSHIP_QUERIES_RECEIVED_TXT),igps->igps_rcv_queries);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IGMP_INVALID_QUERIES_RECEIVED_TXT),igps->igps_rcv_badqueries);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IGMP_MEMBERSHIP_REPORTS_RECEIVED_TXT),igps->igps_rcv_reports);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IGMP_INVALID_REPORTS_RECEIVED_TXT),igps->igps_rcv_badreports);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IGMP_MEMBERSHIP_REPORTS_RECEIVED_FOR_THIS_GROUP_TXT),igps->igps_rcv_ourreports);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IGMP_MEMBERSHIP_REPORTS_SENT_TXT),igps->igps_snd_reports);
}
STATIC VOID
print_ip_status(struct CommandContext * cc,struct ipstat *ips)
{
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_TITLE_TXT),begin_underline(cc),end_underline(cc));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_TOTAL_PACKETS_RECEIVED_TXT),ips->ips_total);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_WITH_CHECKSUM_ERRORS_TXT),ips->ips_badsum);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_TOO_SHORT_TXT),ips->ips_tooshort);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_TOO_SMALL_TXT),ips->ips_toosmall);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_WITH_BAD_DATA_SIZE_TXT),ips->ips_badhlen);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_WITH_BAD_HEADER_SIZE_TXT),ips->ips_badlen);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_FRAGMENTS_RECEIVED_TXT),ips->ips_fragments);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_FRAGMENTS_DROPPED_TXT),ips->ips_fragdropped);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_FRAGMENTS_TIMED_OUT_TXT),ips->ips_fragtimeout);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_FORWARDED_TXT),ips->ips_forward);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_CANNOT_FORWARD_TXT),ips->ips_cantforward);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_FORWARDED_ON_SAME_NETWORK_TXT),ips->ips_redirectsent);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_WITH_UNKNOWN_PROTOCOLS_TXT),ips->ips_noproto);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_DATAGRAMS_DELIVERED_TXT),ips->ips_delivered);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_GENERATED_TXT),ips->ips_localout);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_LOST_TXT),ips->ips_odropped);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_REASSEMBLED_TXT),ips->ips_reassembled);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_FRAGMENTED_TXT),ips->ips_fragmented);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_OUTPUT_FRAGMENTS_CREATED_TXT),ips->ips_ofragments);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_CANNOT_FRAGMENT_TXT),ips->ips_cantfrag);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_ERRORS_IN_OPTION_PROCESSING_TXT),ips->ips_badoptions);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_NO_ROUTE_TXT),ips->ips_noroute);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_PACKETS_WITH_BAD_IP_VERSION_TXT),ips->ips_badvers);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_IP_RAW_PACKETS_SENT_TXT),ips->ips_rawout);
}
STATIC VOID
print_mb_status(struct CommandContext * cc,struct mbstat *m)
{
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MBUF_TITLE_TXT),begin_underline(cc),end_underline(cc));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MBUF_BUFFERS_FROM_PAGE_POOL_TXT),m->m_mbufs);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MBUF_CLUSTERS_FROM_PAGE_POOL_TXT),m->m_clusters);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MBUF_FREE_CLUSTERS_TXT),m->m_clfree);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MBUF_DROPS_TXT),m->m_drops);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MBUF_WAIT_TXT),m->m_wait);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MBUF_DRAIN_TXT),m->m_drain);
}
STATIC VOID
print_mrt_status(struct CommandContext * cc,struct mrtstat *mrts)
{
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MULTICAST_TITLE_TXT),begin_underline(cc),end_underline(cc));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MULTICAST_ROUTE_LOOKUPS_TXT),mrts->mrts_mrt_lookups);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MULTICAST_ROUTE_CACHE_MISSES_TXT),mrts->mrts_mrt_misses);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MULTICAST_GROUP_ADDRESS_LOOKUPS_TXT),mrts->mrts_grp_lookups);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MULTICAST_GROUP_ADDRESS_CACHE_MISSES_TXT),mrts->mrts_grp_misses);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MULTICAST_NO_ROUTE_TXT),mrts->mrts_no_route);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MULTICAST_BAD_TUNNEL_TXT),mrts->mrts_bad_tunnel);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MULTICAST_CANNOT_TUNNEL_TXT),mrts->mrts_cant_tunnel);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_MULTICAST_CANNOT_WRONG_INTERFACE_TXT),mrts->mrts_wrong_if);
}
STATIC VOID
print_rt_status(struct CommandContext * cc,struct rtstat *rts)
{
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ROUTING_TITLE_TXT),begin_underline(cc),end_underline(cc));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ROUTING_BAD_REDIRECT_TXT),rts->rts_badredirect);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ROUTING_DYNAMIC_TXT),rts->rts_dynamic);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ROUTING_NEW_GATEWAY_TXT),rts->rts_newgateway);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ROUTING_UNREACH_TXT),rts->rts_unreach);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_ROUTING_WILDCARD_TXT),rts->rts_wildcard);
}
STATIC VOID
print_tcp_status(struct CommandContext * cc,struct tcpstat *tcps)
{
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_TITLE_TXT),begin_underline(cc),end_underline(cc));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_CONNATTEMPT_TXT),tcps->tcps_connattempt);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_ACCEPTS_TXT),tcps->tcps_accepts);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_CONNECTS_TXT),tcps->tcps_connects);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_DROPS_TXT),tcps->tcps_drops);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_CONNDROPS_TXT),tcps->tcps_conndrops);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_CLOSED_TXT),tcps->tcps_closed);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_SEGSTIMED_TXT),tcps->tcps_segstimed);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RTTUPDATED_TXT),tcps->tcps_rttupdated);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_DELACK_TXT),tcps->tcps_delack);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_TIMEOUTDROP_TXT),tcps->tcps_timeoutdrop);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_PERSISTTIMEO_TXT),tcps->tcps_persisttimeo);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_KEEPTIMEO_TXT),tcps->tcps_keeptimeo);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_KEEPPROBE_TXT),tcps->tcps_keepprobe);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_KEEPDROPS_TXT),tcps->tcps_keepdrops);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_SNDTOTAL_TXT),tcps->tcps_sndtotal);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_SNDPACK_TXT),tcps->tcps_sndpack);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_SNDBYTE_TXT),tcps->tcps_sndbyte);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_SNDREXMITPACK_TXT),tcps->tcps_sndrexmitpack);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_SNDREXMITBYTE_TXT),tcps->tcps_sndrexmitbyte);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_SNDACKS_TXT),tcps->tcps_sndacks);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_SNDPROBE_TXT),tcps->tcps_sndprobe);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_SNDURG_TXT),tcps->tcps_sndurg);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_SNDWINUP_TXT),tcps->tcps_sndwinup);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_SNDCTRL_TXT),tcps->tcps_sndctrl);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVTOTAL_TXT),tcps->tcps_rcvtotal);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVPACK_TXT),tcps->tcps_rcvpack);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVBYTE_TXT),tcps->tcps_rcvbyte);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVBADSUM_TXT),tcps->tcps_rcvbadsum);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVBADOFF_TXT),tcps->tcps_rcvbadoff);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVSHORT_TXT),tcps->tcps_rcvshort);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVDUPPACK_TXT),tcps->tcps_rcvduppack);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVDUPBYTE_TXT),tcps->tcps_rcvdupbyte);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVOOPACK_TXT),tcps->tcps_rcvoopack);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVOOBYTE_TXT),tcps->tcps_rcvoobyte);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVPACKAFTERWIN_TXT),tcps->tcps_rcvpackafterwin);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVBYTEAFTERWIN_TXT),tcps->tcps_rcvbyteafterwin);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVAFTERCLOSE_TXT),tcps->tcps_rcvafterclose);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVWINPROBE_TXT),tcps->tcps_rcvwinprobe);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVDUPACK_TXT),tcps->tcps_rcvdupack);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVACKTOOMUCH_TXT),tcps->tcps_rcvacktoomuch);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVACKPACK_TXT),tcps->tcps_rcvackpack);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVACKBYTE_TXT),tcps->tcps_rcvackbyte);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_RCVWINUPD_TXT),tcps->tcps_rcvwinupd);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_PAWSDROP_TXT),tcps->tcps_pawsdrop);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_PREDACK_TXT),tcps->tcps_predack);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_PREDDAT_TXT),tcps->tcps_preddat);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_PERSISTDROP_TXT),tcps->tcps_persistdrop);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_BADSYN_TXT),tcps->tcps_badsyn);
}
STATIC VOID
print_udp_status(struct CommandContext * cc,struct udpstat *udps)
{
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_UDP_TITLE_TXT),begin_underline(cc),end_underline(cc));
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_UDP_IPACKETS_TXT),udps->udps_ipackets);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_UDP_HDROPS_TXT),udps->udps_hdrops);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_UDP_BADSUM_TXT),udps->udps_badsum);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_UDP_BADLEN_TXT),udps->udps_badlen);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_UDP_NOPORT_TXT),udps->udps_noport);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_UDP_NOPORTBCAST_TXT),udps->udps_noportbcast);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_UDP_FULLSOCK_TXT),udps->udps_fullsock);
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_UDP_OPACKETS_TXT),udps->udps_opackets);
}
STATIC VOID
print_tcp_socket_status(struct CommandContext * cc,BOOL all_sockets,struct protocol_connection_data *pcd,LONG size)
{
DECLARE_SOCKETBASE(cc);
struct servent * s;
STRPTR status;
LONG i,m,n;
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
if(size >= (int)sizeof(*pcd))
{
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_SOCKET_TITLE_TXT),
begin_underline(cc),
get_str(cc,MSG_SHOWNETSTATUS_LOCAL_TXT),
get_str(cc,MSG_SHOWNETSTATUS_REMOTE_TXT),
get_str(cc,MSG_SHOWNETSTATUS_RECEIVE_LEN_TXT),
get_str(cc,MSG_SHOWNETSTATUS_SEND_LEN_TXT),
get_str(cc,MSG_SHOWNETSTATUS_STATUS_TXT),
end_underline(cc));
}
for(i = m = n = 0 ; i < size / (int)sizeof(*pcd) ; i++, pcd++, n++)
{
if(pcd->pcd_local_address.s_addr == INADDR_ANY && NOT all_sockets)
{
m++;
continue;
}
if(pcd->pcd_local_address.s_addr != INADDR_ANY || cc->cc_NoNames)
routename(cc,pcd->pcd_local_address.s_addr,cc->cc_Line1,MAXHOSTNAMELEN);
else
strcpy(cc->cc_Line1,get_str(cc,MSG_SHOWNETSTATUS_WILDCARD_TXT));
if(cc->cc_NoNames)
s = NULL;
else
s = getservbyport(pcd->pcd_local_port,"tcp");
if(s != NULL)
lsprintf(cc,&cc->cc_Line1[strlen(cc->cc_Line1)],":%s",s->s_name);
else
lsprintf(cc,&cc->cc_Line1[strlen(cc->cc_Line1)],":%ld",pcd->pcd_local_port);
routename(cc,pcd->pcd_foreign_address.s_addr,cc->cc_Line2,MAXHOSTNAMELEN);
if(pcd->pcd_foreign_address.s_addr != INADDR_ANY)
{
if(cc->cc_NoNames)
s = NULL;
else
s = getservbyport(pcd->pcd_foreign_port,"tcp");
if(s != NULL)
lsprintf(cc,&cc->cc_Line2[strlen(cc->cc_Line2)],":%s",s->s_name);
else
lsprintf(cc,&cc->cc_Line2[strlen(cc->cc_Line2)],":%ld",pcd->pcd_foreign_port);
}
else
{
strcpy(cc->cc_Line2,"-");
}
if(TCPS_CLOSED <= pcd->pcd_tcp_state && pcd->pcd_tcp_state <= TCPS_TIME_WAIT)
status = get_str(cc,MSG_SHOWNETSTATUS_TCP_FSM_STATE1_TXT + pcd->pcd_tcp_state - TCPS_CLOSED);
else
status = "-";
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_TCP_SOCKET_LINE_TXT),cc->cc_Line1,cc->cc_Line2,pcd->pcd_receive_queue_size,pcd->pcd_send_queue_size,status);
}
if(n == 0)
{
if(m == 0)
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_NO_TCP_SOCKETS_IN_USE_TXT));
else
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_SOME_TCP_SOCKETS_IN_USE_TXT),m);
}
}
STATIC VOID
print_udp_socket_status(struct CommandContext * cc,BOOL all_sockets,struct protocol_connection_data *pcd,LONG size)
{
DECLARE_SOCKETBASE(cc);
struct servent * s;
LONG i,m,n;
if(cc->cc_Something)
lprintf(cc,"\n");
else
cc->cc_Something = TRUE;
if(size >= (int)sizeof(*pcd))
{
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_UDP_SOCKET_TITLE_TXT),
begin_underline(cc),
get_str(cc,MSG_SHOWNETSTATUS_LOCAL_TXT),
get_str(cc,MSG_SHOWNETSTATUS_REMOTE_TXT),
get_str(cc,MSG_SHOWNETSTATUS_RECEIVE_LEN_TXT),
get_str(cc,MSG_SHOWNETSTATUS_SEND_LEN_TXT),
end_underline(cc));
}
for(i = m = n = 0 ; i < size / (int)sizeof(*pcd) ; i++, pcd++, n++)
{
if(pcd->pcd_local_address.s_addr == INADDR_ANY && NOT all_sockets)
{
m++;
continue;
}
if(pcd->pcd_local_address.s_addr != INADDR_ANY || cc->cc_NoNames)
routename(cc,pcd->pcd_local_address.s_addr,cc->cc_Line1,MAXHOSTNAMELEN);
else
strcpy(cc->cc_Line1,get_str(cc,MSG_SHOWNETSTATUS_WILDCARD_TXT));
if(cc->cc_NoNames)
s = NULL;
else
s = getservbyport(pcd->pcd_local_port,"udp");
if(s != NULL)
lsprintf(cc,&cc->cc_Line1[strlen(cc->cc_Line1)],":%s",s->s_name);
else
lsprintf(cc,&cc->cc_Line1[strlen(cc->cc_Line1)],":%ld",pcd->pcd_local_port);
if(pcd->pcd_foreign_address.s_addr != INADDR_ANY)
{
routename(cc,pcd->pcd_foreign_address.s_addr,cc->cc_Line2,MAXHOSTNAMELEN);
if(cc->cc_NoNames)
s = NULL;
else
s = getservbyport(pcd->pcd_foreign_port,"udp");
if(s != NULL)
lsprintf(cc,&cc->cc_Line2[strlen(cc->cc_Line2)],":%s",s->s_name);
else
lsprintf(cc,&cc->cc_Line2[strlen(cc->cc_Line2)],":%ld",pcd->pcd_foreign_port);
}
else
{
strcpy(cc->cc_Line2,"-");
}
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_UDP_SOCKET_LINE_TXT),cc->cc_Line1,cc->cc_Line2,pcd->pcd_receive_queue_size,pcd->pcd_send_queue_size);
}
if(n == 0)
{
if(m == 0)
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_NO_UDP_SOCKETS_IN_USE_TXT));
else
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_SOME_UDP_SOCKETS_IN_USE_TXT),m);
}
}
/****************************************************************************/
STATIC VOID
print_net_status_summary(struct CommandContext * cc)
{
DECLARE_SOCKETBASE(cc);
struct List * interface_list;
struct List * dns_list;
struct rt_msghdr * route_table;
struct sockaddr_in * default_route;
char * default_interface_name;
struct sockaddr_in default_interface_address;
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_STATUS_SUMMARY_TXT),begin_underline(cc),end_underline(cc));
default_interface_name = NULL;
memset(&default_interface_address,0,sizeof(default_interface_address));
interface_list = ObtainInterfaceList();
if(interface_list != NULL && NOT IsListEmpty(interface_list))
{
struct Node * node;
ULONG host_id;
host_id = gethostid();
for(node = interface_list->lh_Head ;
node->ln_Succ != NULL ;
node = node->ln_Succ)
{
if(Local_QueryInterfaceTags(cc,node->ln_Name,
IFQ_Address,&default_interface_address,
TAG_DONE) != 0)
{
continue;
}
if(default_interface_address.sin_addr.s_addr == host_id)
{
default_interface_name = node->ln_Name;
break;
}
}
}
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_LOCAL_HOST_ADDRESS_TXT));
if(default_interface_name != NULL)
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_LOCAL_HOST_ADDRESS_ON_INTERFACE_TXT),Inet_NtoA(default_interface_address.sin_addr.s_addr),default_interface_name);
else
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_NOT_CONFIGURED_TXT));
lprintf(cc,"\n");
default_route = NULL;
route_table = GetRouteInfo(AF_UNSPEC,0);
if(route_table != NULL)
{
struct sockaddr_in * sin;
struct rt_msghdr * rtm;
struct sockaddr * sa;
LONG len;
for(rtm = route_table ;
rtm->rtm_msglen > 0 ;
rtm = (struct rt_msghdr *)(((ULONG)rtm) + rtm->rtm_msglen))
{
/* We need a route with a destination and a gateway address. */
if(rtm->rtm_version != 3 || (rtm->rtm_addrs & RTA_DST) == 0 || (rtm->rtm_addrs & RTA_GATEWAY) == 0)
continue;
/* The destination address follows the message header. */
sa = (struct sockaddr *)(rtm + 1);
/* The destination should be an Internet address */
if(sa->sa_family != AF_INET)
continue;
/* The default route is identified by having a 0.0.0.0 destination
address, which indicates a route that matches any destination
address. */
sin = (struct sockaddr_in *)sa;
if(sin->sin_addr.s_addr != INADDR_ANY)
continue;
/* Skip the destination address. */
if(sa->sa_len == 0)
len = sizeof(long);
else
len = sa->sa_len;
sa = (struct sockaddr *)(((ULONG)sa) + len);
/* This should be the IP address of the gateway. It should be
an Internet address. */
if(sa->sa_family != AF_INET)
continue;
default_route = (struct sockaddr_in *)sa;
break;
}
}
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_DEFAULT_GATEWAY_ADDRESS_TXT));
if(default_route != NULL)
lprintf(cc,"%s",Inet_NtoA(default_route->sin_addr.s_addr));
else
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_NOT_CONFIGURED_TXT));
lprintf(cc,"\n");
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_DOMAIN_NAME_SYSTEM_SERVERS_TXT));
dns_list = ObtainDomainNameServerList();
if(dns_list != NULL && NOT IsListEmpty(dns_list))
{
struct DomainNameServerNode * dnsn;
BOOL is_first = TRUE;
for(dnsn = (struct DomainNameServerNode *)dns_list->lh_Head ;
dnsn->dnsn_MinNode.mln_Succ != NULL ;
dnsn = (struct DomainNameServerNode *)dnsn->dnsn_MinNode.mln_Succ)
{
if(NOT is_first)
lprintf(cc,", ");
lprintf(cc,"%s",dnsn->dnsn_Address);
is_first = FALSE;
}
}
else
{
lprintf(cc,get_str(cc,MSG_SHOWNETSTATUS_NOT_CONFIGURED_TXT));
}
lprintf(cc,"\n");
if(interface_list != NULL)
ReleaseInterfaceList(interface_list);
if(dns_list != NULL)
ReleaseDomainNameServerList(dns_list);
if(route_table != NULL)
FreeRouteInfo(route_table);
}
/****************************************************************************/
STATIC LONG VARARGS68K
Local_ErrorPrintf(struct CommandContext * cc,STRPTR format,...)
{
DECLARE_DOSBASE(cc);
DECLARE_SYSBASE(cc);
va_list args;
LONG result;
BPTR fh;
#if defined(__amigaos4__)
{
fh = ErrorOutput();
}
#else
{
struct Process * this_process = (struct Process *)FindTask(NULL);
fh = this_process->pr_CES;
}
#endif /* __amigaos4__ */
if(fh == ZERO)
fh = Output();
#if defined(__amigaos4__)
{
va_startlinear(args,format);
result = VFPrintf(fh,format,va_getlinearva(args,APTR));
va_end(args);
}
#else
{
va_start(args,format);
result = VFPrintf(fh,format,args);
va_end(args);
}
#endif /* __amigaos4__ */
return(result);
}
/****************************************************************************/
/* This looks up a locale string ID in the builtin database; adapted
from CygnusEd because I couldn't find my own implementation for this
application... */
STATIC STRPTR
get_builtin_str(LONG id)
{
LONG top,middle,bottom;
STRPTR builtin_string;
/* The search area is all those message between bottom and top, inclusive. */
bottom = 0;
top = NUM_ENTRIES(CatCompArray) - 1;
/* Binary search through the CatCompArray to find the requested string.
Note that this assumes that the strings are sorted. Catcomp defaults
to creating sorted arrays, but it does _not_ force it. If in the .cd
file you specify out of order string numbers this routine will fail. */
while(bottom != top)
{
middle = (bottom + top) / 2;
if(CatCompArray[middle].cca_ID >= id)
top = middle;
else
bottom = middle + 1;
}
/* The only time this error message should occur is if you've passed
a garbage number OR if the CatCompArray is not sorted. */
if(CatCompArray[bottom].cca_ID == id)
builtin_string = (STRPTR)CatCompArray[bottom].cca_Str;
else
builtin_string = "";
return(builtin_string);
}
STRPTR
get_str(struct CommandContext * cc, LONG id)
{
STRPTR builtin_string;
STRPTR result;
builtin_string = get_builtin_str(id);
if(cc->cc_Catalog != NULL)
{
DECLARE_LOCALEBASE(cc);
result = (STRPTR)GetCatalogStr(cc->cc_Catalog,id,builtin_string);
}
else
{
result = builtin_string;
}
return(result);
}
/****************************************************************************/
STATIC VARARGS68K LONG
Local_QueryInterfaceTags(struct CommandContext * cc,STRPTR interface_name,...)
{
DECLARE_SOCKETBASE(cc);
va_list args;
LONG result;
#if defined(__amigaos4__)
{
va_startlinear(args,interface_name);
result = QueryInterfaceTagList(interface_name,va_getlinearva(args,struct TagItem *));
va_end(args);
}
#else
{
va_start(args,interface_name);
result = QueryInterfaceTagList(interface_name,(struct TagItem *)args);
va_end(args);
}
#endif /* __amigaos4__ */
return(result);
}
STATIC VARARGS68K LONG
Local_SocketBaseTags(struct CommandContext * cc,...)
{
DECLARE_SOCKETBASE(cc);
va_list args;
LONG result;
#if defined(__amigaos4__)
{
va_startlinear(args,cc);
result = SocketBaseTagList(va_getlinearva(args,struct TagItem *));
va_end(args);
}
#else
{
va_start(args,cc);
result = SocketBaseTagList((struct TagItem *)args);
va_end(args);
}
#endif /* __amigaos4__ */
return(result);
}