/* * "Roadshow" Amiga TCP/IP stack * * :ts=4 * * Copyright © 2001-2019 by Olaf Barthel. All Rights Reserved. */ #include #include #include #include #include #include #include #include #include /****************************************************************************/ #if defined(__amigaos4__) #include #endif /* __amigaos4__ */ /****************************************************************************/ #if !defined(__amigaos4__) #define NO_INLINE_STDARG #endif /* __amigaos4__ */ #define __NOLIBBASE__ #define __NOGLOBALIFACE__ #define __USE_INLINE__ /****************************************************************************/ #include #include #include #include #include /****************************************************************************/ #include #include /****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include /****************************************************************************/ #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=[,...]] [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:Internet/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); }