TSO NETSTAT command output parsing considerations

No message identifiers are displayed in the output for TSO NETSTAT if the command is issued from an IPv6-enabled stack or if the command is issued from an IPv4-only stack but the request is for a long format display. If you have developed REXX programs that issue Netstat commands under TSO and parse the output lines based on message identifiers, you need to change those REXX programs to use some other token in the output lines to decide the format of the line you are trying to parse.

Here are some tips that might make the migration easier for you:
  • Several Netstat reports display table entries such as the CONN report or the BYTEINFO report. If you are receiving Netstat output in LONG format, these table entries now take up more than one output line. The first line in a table entry always starts at position one in the line, and the remaining lines that belong to that same table entry start with an offset of two (position three). You can use that to determine which lines are the start of a table entry and which are follow-on lines that belong to that same table entry.
  • For the non-table type of reports, depending on the report you are parsing and the pieces of information you are looking for, you need to identify the individual lines on some other token than the MSGID, such a LNKNAME or DEVNAME.
A small REXX program produced the output in the following example based on a NETSTAT DEVLINKS report:
Link/Intf name =LOOPBACK           Bytes in =12387      Bytes out =12387  
Link/Intf name =VIPA1              Bytes in =0          Bytes out =0      
Link/Intf name =LINKEE             Bytes in =0          Bytes out =0      
Link/Intf name =TR1                Bytes in =110614     Bytes out =363744 
Link/Intf name =VIPLC0A86501       Bytes in =0          Bytes out =0      
Link/Intf name =VIPL092A689F       Bytes in =0          Bytes out =0      
This output was produced with a REXX program that used MSGIDs to identify lines. The sample REXX program is shown in the following example:
/* REXX */                                                       
/* Requires PROFILE MSGID - uses MSGIDs to identify lines     */ 
netstr = 'DEVLINKS'                                              
address TSO "NETSTAT "netstr" STACK"                             
n = queued()                                                     
if n > 0 then do x=1 to n                                        
   i = (n-x)+1                                                   
   pull line.i                                                   
end                                                              
line.0 = n                                                       
do x=1 to line.0                                                
   parse upper var line.x msgid t1 t2 t3 t4 .                    
   if msgid = 'EZZ2761I' then do                  /* MSGID EZZ2761I */               
      interface = t2                                             
   end                                                           
   if msgid = 'EZZ2820I' then do                  /* MSGID EZZ2820I */               
      bytesin = t2                                               
      bytesout = t4                                              
      st1 = 'Link/Intf name ='||substr(interface,1,18)           
      st1 = st1||' Bytes in ='||substr(bytesin,1,10)             
      st1 = st1||' Bytes out ='||substr(bytesout,1,10)           
      say st1                                                    
   end                                                           
end                                                              
exit                                                         
The exact same output can be produced using a modified REXX program that does not use MSGIDs but specific tokens in the Netstat report. In the following example, the only changes required are in the parse and if statements.
/* REXX */                                                       
/* Does not require MSGIDs, uses tokens to identify lines     */ 
/* This REXX works with z/OS V1R10                             */
netstr = 'DEVLINKS'                                              
address TSO "NETSTAT "netstr" STACK"                             
n = queued()                                                     
if n > 0 then do x=1 to n                                        
   i = (n-x)+1                                                   
   pull line.i                                                   
end                                                              
line.0 = n                                                       
do x =1 to line.0                                                
   parse upper var line.x t1 t2 t3 t4 .                          
   if t1 = 'LNKNAME:' | t1 = 'INTFNAME:' then do                 
      interface = t2                                             
   end                                                           
   if t1 = 'BYTESIN' then do                                     
      bytesin = t3                                               
   end                                                           
   if t1 = 'BYTESOUT' then do                                    
      bytesout = t3                                              
      st1 = 'Link/Intf name = '||substr(interface,1,18)          
      st1 = st1||' Bytes in = '||substr(bytesin,1,10)            
      st1 = st1||' Bytes out = '||substr(bytesout,1,10)          
      say st1                                                    
   end                                                           
end                                                              
exit