# S120NET.def: Collects Network Information # $Id: S120NET.def,v 1.49 2008/02/25 17:32:55 mschenke Exp $ # ARCS: $Header: /home/cvs/repository/RDA_4/src/scripting/lib/modules/S120NET.def,v 1.49 2008/02/25 17:32:55 mschenke Exp $ # # Change History # 20080225 MSC Change the copyright notice. =head1 NAME S120NET - Collects Network Information =head1 DESCRIPTION This module collects network information including all the general Oracle-related networking files and configurations (for example, listener status, network statistics, kernel parameters, and so on). The following reports can be generated and are regrouped under C: =cut echo tput('bold'),'Processing NET module ...',tput('off') # Initialization var $ETC = '/etc' var $HOSTS = '/etc/hosts' var $NETSTAT = undef var $NETWORKS = '/etc/networks' var $ORACLE_HOME = getSetting('ORACLE_HOME') var $PING = undef var $PROTOCOL = '/etc/protocols' var $PS_ARG var $PS_EF var $PS_ELF var $SERVICES = '/etc/services' var $SIZE = getSetting('NETWORK_LOG_SIZE',1048576) var $TAIL = getSetting('RDA_TAIL',1000) var $TNS_ADMIN = getEnv('TNS_ADMIN',catDir($ORACLE_HOME,'network','admin')) var $PACKET = getSetting('NETWORK_PACKET_SIZE',1280) var $TOC = '%TOC%' var $TOP = '[[#Top][Back to top]]' toc '1:Network' if getSetting('NETWORK_PING_TESTS') {echo tput('bold'),'Processing networking information \ (pings, network files, sql*net files)...',tput('off') echo tput('bold'),'Listener and network checks may take a few minutes. \ please be patient...',tput('off') } else {echo tput('bold'),'Processing networking information \ (network files, sql*net files)...',tput('off') echo tput('bold'),'Listener checks may take a few minutes. \ please be patient...',tput('off') } # Load the common macros run library() =head2 ifconfig - Interface Configuration Gets the network interface configuration (platform-specific code). =head2 tcpip_settings - TCP/IP Settings Gets the TCP/IP settings (platform-specific code). =head2 udp_settings - UDP Settings Gets the UDP settings (platform-specific code). =cut var $osn = getOsName() if match($osn,'solaris') {run OSsunos('NET',\$PING,\$NETSTAT,\$PS_ARG,\$PS_EF) } elsif match($osn,'hpux') {run OShpux('NET',\$PING,\$NETSTAT,\$PS_ARG,\$PS_EF) } elsif match($osn,'aix') {run OSaix('NET',\$PING,\$NETSTAT,\$PS_ARG,\$PS_EF) var $NETWORKS='/etc/hosts' } elsif match($osn,'dec_osf') {run OSosf('NET',\$PING,\$NETSTAT,\$PS_ARG,\$PS_EF) } elsif match($osn,'linux') {run OSlinux('NET',\$PING,\$NETSTAT,\$PS_ARG,\$PS_EF,\$PS_ELF) } elsif match($osn,'dynixptx') {run OSptx('NET',\$PING,\$NETSTAT,\$PS_ARG,\$PS_EF) } elsif match($osn,'darwin') {run OSdarwin('NET',\$PING,\$NETSTAT,\$PS_ARG,\$PS_EF) } elsif isWindows() {run OSwin32('NET',\$PING,\$NETSTAT) if match($osn,'MSWin32') {if getEnv('SYSTEMROOT') var $sys = last else var ($sys) = command('echo %SystemRoot%') var $ETC = catDir($sys,'system32','drivers','etc') } var $HOSTS = catFile($ETC,'hosts') var $NETWORKS = catFile($ETC,'networks') var $PROTOCOL = catFile($ETC,'protocol') var $SERVICES = catFile($ETC,'services') } elsif isUnix() {run OSunix('NET',\$PING,\$NETSTAT,\$PS_EF,\$PS_ARG) } elsif isVms() {run OSvms('NET',\$PING,\$NETSTAT,\$PS_EF,\$PS_ARG) } =head2 adapters - Adapters Output Executes the F<$ORACLE_HOME/bin/adapters> command. =cut report adapters var $pgm = catFile($ORACLE_HOME,'bin','adapters') if testFile('x',$pgm) {debug ' Inside NET module, about to run adapters command' var $pgm = lastCommand() write '---+!! Output from Adapters in $ORACLE_HOME/bin' write $TOC write '---+ Installed Protocol Adapters' call writeCommand($pgm) write $TOP write '---+ Protocol Adapters for Oracle Executable' call writeCommand(join(' ',$pgm,catCommand($ORACLE_HOME,'bin','oracle'))) write $TOP } elsif testFile('f',$pgm) {debug ' Inside NET module, adapters command not executable' write '**$ORACLE_HOME/bin/adapters not executable**%BR%\ Permissions for $ORACLE_HOME/bin/adapters are:%BR%' call statFile('b',$pgm) } if isCreated() toc '2:[[',getFile(),'][rda_report][Adapters Output]]' =pod Gets the SQL*Net configuration information. Some of the SQL*Net files can reside in multiple well-known locations. =cut var $HOM = getEnv('HOME') toc '2:SQL*Net Configuration' call cat_search('cman.ora',true,'sqlnet_') call cat_search('ldap.ora',true,'sqlnet_') call cat_search('listener.ora',false,'sqlnet_','^(PASSWORDS_\w*\s*=).*$',\ '%R:PASSWORD%') call cat_search('names.ora',true,'sqlnet_','(PASSWORDS_\w*\s*=).*$',\ '%R:PASSWORD%') call cat_search('protocol.ora',true,'sqlnet_') call cat_search('sqlnet.ora',false,'sqlnet_') call cat_search('tnsnames.ora',false,'sqlnet_') call cat_search('dbsnmp.ver',true,'sqlnet_') call cat_report($HOM,'.listener.ora','dot','^(PASSWORDS_\w*\s*=).*$',\ '%R:PASSWORD%') call cat_report($HOM,'.protocol.ora','dot') call cat_report($HOM,'.sqlnet.ora','dot') call cat_report($HOM,'.tnsnames.ora','dot') if isVms() {# List the present files report sys_login_net prefix write '---+ SYS$LOGIN SQL*Net Files' var @tbl = grepDir($HOM,'\.ora$','inp') call statFile('b',@tbl) if isCreated(true) toc '2:[[',getFile(),'][rda_report][SYS$LOGIN SQL*Net Files]]' # Collect some of them call cat_report($HOM,'listener.ora','home_','^(PASSWORDS_\w*\s*=).*$',\ '%R:PASSWORD%') call cat_report($HOM,'protocol.ora','home_') call cat_report($HOM,'sqlnet.ora','home_') call cat_report($HOM,'tnsnames.ora','home_') } =pod Captures the Oracle Names configuration. =cut pretoc '2:Oracle Names Configuration' if loadCommand('namesctl exit') {if !grepLastFile('NNL-00018\:','f') {debug ' Inside NET module, looking for Oracle Names server' report names write '---+ Oracle Names Server' call writeCommand('namesctl show server') write '---+ Oracle Names Status' call writeCommand('namesctl show status',false,0.5) unpretoc toc '2:[[',getFile(),'][rda_report][Oracle Names Configuration]]' } } var $dir = catDir($ORACLE_HOME,'network','names') call cat_report($dir,'sdns.ora','names_') call cat_report($HOM,'.sdns.ora','dot') unpretoc =pod Retrieves the Heterogeneous Services configuration and log files. =cut pretoc '2:Heterogeneous Services Configuration' var $dir = catDir($ORACLE_HOME,'hs','admin') loop $nam (grepDir($dir,'\.ora$','in')) call cat_report($dir,$nam,'hs_') unpretoc pretoc '2:Heterogeneous Services Log Files' call sort_files(3,$TAIL,\ grepDir(catDir($ORACLE_HOME,'hs','log'),'.','r'),\ grepDir(catDir($ORACLE_HOME,'hs','trace'),'.','r')) unpretoc =head2 sqlnet_log - sqlnet.log Extracts the last 1000 lines of F<$ORACLE_HOME/network/log/sqlnet.log>. =cut var $fil = catFile($ORACLE_HOME,'network','log','sqlnet.log') if testFile('r',$fil) {debug ' Inside NET module, process sqlnet.log' report sqlnet_log write '---+ Last ',$TAIL,' Lines of sqlnet.log File' write '---## Information Taken from ',$fil call writeTail($fil,$TAIL) toc '2:[[',getFile(),'][rda_report][sqlnet.log]]' } =head2 lstatus - Listener Status and Services It is possible that more than one listener can be started with the same name using a different Oracle home. On UNIX, because the listeners cannot be queried individually using the F that started them, it removes duplicate listener names to query the status of each one once only. On Windows, the listener list is extracted from the F file. C can hang, causing the script to hang. To prevent this, the request is limited to 30 seconds when C is supported in the Perl version. Passwords found in the F file are used. =cut debug ' Inside NET module, looking for running listeners' var $lsn = catFile(getEnv('TNS_ADMIN',catDir($ORACLE_HOME,'network','admin')),\ 'listener.ora') if isWindows() {# Extract the listener list debug ' Inside NET module, analyzing listener.ora' loop $lin (grepFile($lsn,'^sid_list_','i')) var $listeners{substr(key($lin),9)} = 1 # Determine the listener command if testDir('d',catDir($ORACLE_HOME,'net80','admin')) var $cmd = 'lsnrctl80.exe' else var $cmd = 'lsnrctl.exe' } elsif isUnix() {# Extract the listener list if loadCommand($PS_ARG) {# When ps -o works on the platform, use it to get the listener name. debug ' Inside NET module, using ps -o to find listener name' loop $lin (grepLastFile('tnslsnr')) var $listeners{field('\s+',2,$lin)} = 1 } elsif match($osn,'linux') {# On linux, ps elf must be used to get the listener name # (short listing does not provide the extra output) debug ' Inside NET module, using ps -elf to find listener name' if grepDir('/etc','suse.*release','i') var $off = 6 else var $off = 7 loop $lin (grepCommand($PS_ELF,'tnslsnr.*inherit')) var $listeners{field('\s+',$off,substr($lin,39))} = 1 } elsif match($osn,'aix') {# Output from aix ps, the listener name is in a different spot debug ' Inside NET module, using ps -ef to find listener name on AIX' loop $lin (grepCommand($PS_EF,'tnslsnr')) var $listeners{field('\s+',3,substr($lin,39))} = 1 } else {debug ' Inside NET module, using ps -ef to find listener name' loop $lin (grepCommand($PS_EF,'tnslsnr')) var $listeners{field('\s+',2,substr($lin,42))} = 1 } # Determine the listener command var $cmd = 'lsnrctl' } elsif isVms() {# Macro to resolve listener process name: ORA_NNN macro resolve_alias {var ($ref) = @arg var $pat = '(SID_LIST_|STARTUP_WAIT_TIME_|STOP_|CONNECT_TIMEOUT_|\ LOG_DIRECTORY_|LOG_LEVEL_|LOG_FILE_|TRACE_DIRECTORY_|\ TRACE_LEVEL_|TRACE_FILE_)' loop $lin (grepFile('TNS_ADMIN:LISTENER.ORA',$pat,'i')) {next match($lin,'^#') if match(trim(key($lin)),concat('^',$pat,'(.*)$'),true) {var (undef,$nam) = (last) if compare('eq',uc(substr($nam,-8)),$ref) return $nam } } return $ref } # Get processes currently using the Listener program loop $lin (grepCommand('show device/file ora_root/nosys',\ 'TNSLSNR(_64)?.EXE','i')) {var $nam = field('\s',0,$lin) var $lgt = length($nam) decr $lgt,7 var $nam = substr($nam,4,$lgt) if expr('>=',$lgt,8) var $nam = resolve_alias($nam) var $listeners{$nam} = 1 } # Determine the listener command var $cmd = 'lsnrctl' } else {var $cmd = undef } # Extract the passwords loop $lin (grepFile($lsn,'^passwords_\w*\s*=','i')) {var ($key) = match(key($lin),'passwords_(.*)',true) var $pwd{$key} = trim(value($lin),'\W+') } macro load_lsn {var ($cmd,$req,$lsn,$pwd) = @arg if $pwd {var $tmp = quote(createTemp('lsn'),'x') call writeTemp('lsn','set password ',$pwd) call writeTemp('lsn',$req,' ',$lsn) call writeTemp('lsn','exit') call closeTemp('lsn') call loadCommand(join(' <',$cmd,$tmp)) call unlinkTemp('lsn') } else call loadCommand(join(' ',$cmd,$req,$lsn)) } # Loop through all listeners debug ' Inside NET module, going to get the listener status' report lstatus write '---+!! Listener Status, Log and Services Information' write $TOC write write '%BR%**Are the listeners running?**%BR%\ If no information appears, either there are no listeners running or \ there are no listeners running from $ORACLE_HOME/bin%BR%' write toc '2:[[',getFile(),'][rda_report][Listener Status and Services]]' if testCommand(join(' ',$cmd,'exit')) {var $siz = sprintf('%d',expr('/',$SIZE,1024)) loop $lsn (keys(%listeners)) {# Get the status echo ' Processing listener status, services and log for listener ',$lsn debug ' Inside NET module, getting the listener status for ',$lsn write '---' write '#T_',$lsn toc '3:[[',getFile(),'#T_',$lsn,'][rda_report][',replace($lsn,'^$',' '),']]' write '---+ Status for ',$lsn call load_lsn($cmd,'status',$lsn,$pwd{$lsn}) call writeLastFile() write $TOP # Get and analyze the log file debug ' Inside NET module, getting the listener log file ',$log var ($lin) = grepLastFile('Log File','f') var $log = field('\s+',3,$lin) if !$log {write write 'Log File entry not found in listener status%BR%\ (This may be because the listener is not up)%BR%' } elsif createBuffer('log','T',$log,$SIZE) {var $flg = expr('<',last,0) write '---++!! Errors in Log' write '|*Listener Name*|', $lsn,' |' write '|*Listener Log File*|',$log,' |' var ($lgt,$cnt) = countBuffer('log','TNS-') if $flg write '|*Total TNS Errors*|', $cnt,' |' else write '|*TNS Errors (in last ',$siz,' KiB)*|', $cnt,' |' if $cnt {write '|*TNS Errors (in last 1000 lines)*|',\ grepBuffer('log','TNS-','c',0,expr('-',$lgt,1000),$lgt),' |' debug ' Inside NET module, showing the last 50 errors from listener ',$lsn write '---++!! Last 50 Errors for ',$lsn write '' loop $lin (grepBuffer('log','TNS-','',-50)) write $lin write '' call deleteBuffer('log') } write $TOP } else {write write 'Could not read the log file: ',$log,'%BR%\ It does not exist even though it is specified for this listener%BR%' } # Get services debug ' Inside NET module, getting the listener services for ',$lsn write '---+ Services Information for ',$lsn call load_lsn($cmd,'services',$lsn,$pwd{$lsn}) call writeLastFile() write $TOP } } else {write 'Unable to execute lsnrctl command' write 'File Permissions are:%BR%' call statFile('b',catFile($ORACLE_HOME,'bin',$cmd)) write 'User: ',id(),'%BR%' } # On VMS, report quotas in TNSLSNR.COM file if isVms() {write '---' write '---+ Quota Logicals in ORA_NETWORK:TNSLSNR.COM' prefix write '' loop $lin (grepFile('ORA_NETWORK:TNSLSNR.COM','define\s+ORA_LSNR_','i')) write $lin if hasOutput(true) write '' } =head2 cman - Connection Manager Shows the connection manager services and status. =cut if grepFile(catFile($TNS_ADMIN,'cman.ora'),'=','f') {var $nam = value(last) report cman write '---+!! Connection Manager' write $TOC write '---+ Services Information' var $cmd = concat('cmctl show services -c',' ',$nam) write '---## Using: ',$cmd call writeCommand($cmd) write $TOP write '---+ Status Information' var $cmd = concat('cmctl show status -c',' ',$nam) write '---## Using: ',$cmd call writeCommand($cmd) write $TOP toc '2:[[',getFile(),'][rda_report][Connection Manager]]' } =head2 netenv - Network Environment Checks the setting of C and lists C<.ora> files from well-known directories. =cut debug ' Inside NET module, net environment, looking for tns_admin' report netenv write '---+!! Display of Various Network Environment Information' write $TOC write '---+ Is TNS_ADMIN Being Used?' write '' loop $key (grepEnv('^TNS_')) write $key,'=',getEnv($key) write '' write $TOP debug ' Inside NET module, net environment, doing ls of directories' write '---+ Listing of .ora Files in the Well Known Locations' macro list_ora {var ($dir) = @arg import $TOP keep %tbl if exists($tbl{$dir}) return write '---++ Listing of .ora files from ',$dir if grepDir($dir,'\.ora$','inp') call statFile('b',last) else write 'There are no .ora files in ',$dir,'%BR%' write $TOP var $tbl{$dir} = 1 } call list_ora('/etc') call list_ora('/var/opt/oracle') call list_ora(catDir($ORACLE_HOME,'network','admin')) call list_ora(catDir($ORACLE_HOME,'network','names')) call list_ora(catDir($ORACLE_HOME,'hs','admin')) if getEnv('TNS_ADMIN') call list_ora(last) debug ' Inside NET module, net environment, looking for tnslsnr processes' prefix {write '---+ Checking for tnslsnr Processes' write '**Look for Cpu Hogs**' write '' write getHeader() } loop $lin (grepCommand($PS_EF,'tnslsnr','i')) write $lin if hasOutput(true) {write '' write $TOP } toc '2:[[',getFile(),'][rda_report][Network Environment]]' =head2 netperf - Network Performance Performs ping tests when specified in the setup file. Gets the list of F processes. Collects connection information and statistics from F. Lists declared ports. =cut debug ' Inside NET module, network performance' report netperf write '---+!! Network Performance' write $TOC if getSetting('NETWORK_PING_TESTS') {if !and(match($PACKET,'^\d+$'),expr('>=',$PACKET,64),expr('<=',$PACKET,65200)) {echo "The size of the ping packet must be between 64 and 65200 bytes" var $PACKET = 1280 } var $PING = replace($PING,'\%d',$PACKET) write '---' write '---## Pings done using: ',sprintf($PING,'<machine>') write '---' macro do_ping {var ($key,$ttl) = @arg import $PING,$TOP var $tgt = getSetting($key) debug ' Inside NET module, ping test to ',$tgt write '---+ ',$ttl,' (',$tgt,')' call writeCommand(sprintf($PING,$tgt)) write $TOP } call do_ping('LOCAL_NODE', 'Loopback Ping') call do_ping('WAN_NODE', 'Ping to a Wan Node') call do_ping('RDBMS_NODE', 'Ping to the RDBMS Server Node') call do_ping('WEB_NODE', 'Ping to the Web Server Node') call do_ping('CLIENT_NODE','Ping to a Client Node') } debug ' Inside NET module, get TNS listener processes' if isVms() {prefix {write '---+ TNS Listener Processes' write '' } loop $lin (grepCommand('show device/file ora_root/nosys',\ 'tnslsnr(_64)?\.exe','i')) write $lin } else {prefix {write '---+ TNS Listener Processes' write '' write getHeader() } loop $lin (grepCommand($PS_EF,'tnslsnr','i')) write $lin } if hasOutput(true) {write '' write $TOP } debug ' Inside NET module, collect connection information' write '---+ Network Connection Report' var $flt = cond(isFiltered(),'n','') write '---## Using: ',$NETSTAT,' -a',$flt if loadCommand(concat($NETSTAT,' -a',$flt),true) {var ($cnt) = grepLastFile('ESTABL','c') write '|*Established Connection Count:*| ',$cnt,'|' var ($cnt) = grepLastFile('WAIT','c') write '|*Waiting Connection Count:*| ',$cnt,'|' write '---++!! Established Connection Listing:' write '' loop $lin (grepLastFile('ESTABL')) write $lin write '' } else {write 'There were problems running the netstat command (apparent hang, \ command took longer than 30 seconds to complete). Established and \ waiting connection counts and lists are not gathered.%BR%' } write $TOP debug ' Inside NET module, get nestat interface table' write '---+ Network Interface Table' write '---## Using: ',$NETSTAT,' -i' call writeCommand(concat($NETSTAT,' -i')) write $TOP debug ' Inside NET module, get nestat performance statistics' write '---+ Network Performance Statistics' write '---## Using: ',$NETSTAT,' -s' call writeCommand(concat($NETSTAT,' -s')) write $TOP debug ' Inside NET module, get nestat Routing Table' write '---+ Network Routing Table' write '---## Using: ',$NETSTAT,' -r',$flt call writeCommand(concat($NETSTAT,' -r',$flt)) write $TOP toc '2:[[',getFile(),'][rda_report][Network Performance]]' =head2 etc_files - Key /etc Files Extracts the top 500 lines of F. Gets F, F, F, F. =cut if testDir('f',$HOSTS) {debug ' Inside NET module, gather key /etc files' report etc_files write '---+!! Key Files from the /etc Directory:' write $TOC write '---+ ',$HOSTS,' File' if loadFile($HOSTS) {write '**Total Lines:** ',getLastLength() write '---## Top 500 lines of ',$HOSTS call statFile('b',$HOSTS) call writeLastFile(0,499) write $TOP } macro dsp_file {var ($fil) = @arg import $TOP prefix write '---+ ',$fil,' File' if statFile('b',$fil) {if !writeFile($fil) write 'Cannot access ',$fil write $TOP } unprefix } macro skp_file {var ($fil) = @arg import $TOP prefix write '---+ ',$fil,' File' if statFile('b',$fil) {write 'Skipped for security reasons%BR%' write $TOP } unprefix } call dsp_file('/etc/group') call dsp_file('/etc/nodename') call dsp_file('/etc/nsswitch.conf') call dsp_file($PROTOCOL) if isFiltered() call skp_file($NETWORKS) else call dsp_file($NETWORKS) call dsp_file($SERVICES) toc '2:[[',getFile(),'][rda_report][Key /etc Files]]' } =head2 dynamic_dep - Dynamic Dependencies Lists the dynamic dependencies of executable files or shared libraries. =cut if match($osn,'linux|solaris') var $pgm = 'ldd' elsif match($osn,'hpux') var $pgm = 'chatr' elsif match($osn,'aix') var $pgm = 'dump -Xany -Hv' else var $pgm = undef if $pgm {debug ' Inside NET module, gather dynamic dependencies' report dynamic_dep prefix {write '---+!! Dynamic Dependencies' write $TOC } loop $fil (catFile($ORACLE_HOME,'bin','oracle'),\ catFile($ORACLE_HOME,'bin','tnslsnr'),\ catFile($ORACLE_HOME,'bin','names'),\ catFile($ORACLE_HOME,'lib','libclntsh.so')) {if testFile('r',$fil) {var $cmd = concat($pgm,' ',quote($fil,'x')) write '---+ Dynamic Dependencies of ', $fil write '---## Using: ',$cmd call writeCommand($cmd) write $TOP } } if isCreated(true) toc '2:[[',getFile(),'][rda_report][Dynamic Dependencies]]' } =head1 SEE ALSO See also L, L, L, L, L, L, L, L, L, L, L. =begin credits =over 10 =item RDA 4.0: Ed Bangma. =item RDA 4.1: Kevin Reardon, Guido Tijskens, Andy Young. =item RDA 4.4: Cameron Melvin. =item RDA 4.8: Johan Vanden Bossche. =item RDA 4.10: Russ Hodgson. =back =end credits =head1 COPYRIGHT NOTICE Copyright (c) 2002-2008, Oracle. All rights reserved. =head1 TRADEMARK NOTICE Oracle, JD Edwards, PeopleSoft, and Siebel are registered trademarks of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. =cut