System API で NETSTAT 拡張情報の取得 (V5R4)

System API で NETSTAT 情報の取得 (V5R4)」で、NETSTAT コマンドで基本的に表示される情報を取得するためのプログラムを紹介しましたが、
NETSTAT コマンドには、ファンクション・キーを押すと表示させることができる追加情報もあります。

より詳細なフロー情報、たとえば、再試行の回数、やりとりされているバイト数、アイドルしている時間や、さらにはそのソケットを使用しているジョブなどもリアルタイムでわかるようになっています。

こうした情報を取得するためには、また別の QtocRtvNetCnnDta という System API が用意されています。
今回は、この API を使ったプログラム(の雛形)の紹介です。


取得できる情報

V5R4 時点で↓のような情報が取得できます。

NCND0100 Format

Format NCND0100 returns information regarding the TCP/IPv4 connection totals. For detailed descriptions of the fields in the table, see Field Descriptions.
Offset Type Field
Dec Hex
0 0 BINARY(4) Bytes returned
4 4 BINARY(4) Bytes available
8 8 BINARY(4) TCP connections currently established
12 C BINARY(4) TCP active opens
16 10 BINARY(4) TCP passive opens
20 14 BINARY(4) TCP attempted opens that failed
24 18 BINARY(4) TCP established and then reset
28 1C BINARY(4) TCP segments sent
32 20 BINARY(4) TCP retransmitted segments
36 24 BINARY(4) TCP reset segments
40 28 BINARY(4) TCP segments received
44 2C BINARY(4) TCP segments received in error
48 30 BINARY(4) UDP datagrams sent
52 34 BINARY(4) UDP datagrams received
56 38 BINARY(4) UDP datagrams not delivered application port not found
60 3C BINARY(4) UDP datagrams not delivered other datagrams in error
64 40 BINARY(4) Offset to additional information
68 44 BINARY(4) Length of additional information
72 48    

NCND0200 Format

This format returns detailed information about the TCP connection status in addition to the TCP/IPv4 connection totals (format NCND0100). For detailed descriptions of the fields in the table, see Field Descriptions.
Offset Type Field
Dec Hex
0 0
Returns everything from format NCND0100
Decimal and hexadecimal offsets are reached by using the offset to additional information field in format NCND0100. This applies to all entries below. BINARY(4) Protocol
BINARY(4) Local IP address
BINARY(4) Local port number
BINARY(4) Remote IP address
BINARY(4) Remote port number
BINARY(4) Round-trip time
BINARY(4) Round-trip variance
BINARY(4) Outgoing bytes buffered
BINARY(4) User send next
BINARY(4) Send next
BINARY(4) Send unacknowledged
BINARY(4) Outgoing push number
BINARY(4) Outgoing urgency number
BINARY(4) Outgoing window number
BINARY(4) Incoming bytes buffered
BINARY(4) Receive next
BINARY(4) User receive next
BINARY(4) Incoming push number
BINARY(4) Incoming urgency number
BINARY(4) Incoming window number
BINARY(4) Total retransmissions
BINARY(4) Current retransmissions
BINARY(4) Maximum window size
BINARY(4) Current window size
BINARY(4) Last update
BINARY(4) Last update acknowledged
BINARY(4) Congestion window
BINARY(4) Slow start threshold
BINARY(4) Maximum segment size
BINARY(4) Initial send sequence number
BINARY(4) Initial receive sequence number
BINARY(4) Connection transport layer
BINARY(4) TCP state
BINARY(4) Connection open type
BINARY(4) Idle time in milliseconds
CHAR(40) IP options
BINARY(4) Bytes in
BINARY(4) Bytes out
BINARY(4) Socket state
BINARY(4) Offset to list of socket options associated with connection
BINARY(4) Number of socket options associated with connection
BINARY(4) Entry length for list of socket options associated with connection
BINARY(4) Offset to list of jobs associated with connection
BINARY(4) Number of jobs associated with connection
BINARY(4) Entry length for list of jobs associated with connection
CHAR(10) Associated user profile
CHAR(2) Reserved

コーディングにあたって

呼び出す時のパラメータは↓のようになっています。

  Required Parameter Group:

1 Receiver variable Output Char(*)
2 Length of receiver variable Input Binary(4)
3 Format name Input Char(8)
4 Socket connection request Input Char(*)
5 Error Code I/O Char(*)

  Service Program: QTOCNETSTS

  Threadsafe: Yes

ソケット情報の指定

あまりなじみがないかもしれないのは、4番目の "Socket connection request" を渡すところでしょうか。

この "Socket connection request" というのは、接続先と接続元とプロトコルを指定してソケットを特定するキーになる情報です。
(ですから、"*" などといった指定はできません。あくまで特定のソケットについての追加情報を取得する、という位置づけの API なんですね)

↓のような構造体をつくって

     DSocReqInfo       DS                  Qualified                                                
     D Protocol                      10U 0                                      Protocol            
     D LocalIP                       10U 0                                      Local IP Address    
     D LocalPort                     10U 0                                      Local Port Number   
     D RemoteIP                      10U 0                                      Remote IP Address   
     D RemotePort                    10U 0                                      Remote Port Number  

API に渡してあげればいいわけです。
(ここでは 4番目の spSocReq にあたります)

     D RtvNetCnnDta    Pr                  ExtProc( 'QtocRtvNetCnnDta' )                            
     D  spRcvVar                  65535a   Options( *VarSize )                                      
     D  spRcvVarLen                  10i 0 Const                                                    
     D  spFmtName                     8a   Const                                                    
     D  spSocReq                       *   value                                                    
     D  spError                   32767a   Options( *VarSize: *Omit )                               

「特定のソケットについての追加情報の取得」を目的とした API なので、プロトコルや接続元/接続先の IP アドレスとポートがわからない場合はすべて return で終了させています。

              Select ;                                                                              
                when pProtocol = '*TCP' ;                                                           
                     SocReqInfo.Protocol = 1 ;                                                      
                when pProtocol = '*UDP' ;                                                           
                     SocReqInfo.Protocol = 2 ;                                                      
                other ;                                                                             
                     return ;                                                                       
              endSL ;                                                                               
                                                                                                    
              if lAddr = *blank ;                                                                   
                  return ;                                                                          
              else ;                                                                                
                  SocReqInfo.LocalIP = inet_addr(%trimR(lAddr)) ;                                   
              endif ;                                                                               
                                                                                                    
              if lPort = *blanks ;                                                                  
                  return ;                                                                          
              else ;                                                                                
                  SocReqInfo.LocalPort = %int(lPort) ;                                              
              endif ;                                                                               
                                                                                                    
              if rAddr = *blank ;                                                                   
                  return ;                                                                          
              else ;                                                                                
                  SocReqInfo.RemoteIP = inet_addr(%trimR(rAddr)) ;                                  
              endif ;                                                                               
                                                                                                    
              if rPort = *blanks ;                                                                  
                  return ;                                                                          
              else ;                                                                                
                  SocReqInfo.RemotePort = %int(rPort) ;                                             
              endif ;                                                                               

考慮点

基本的に Receiver Variable を使用する場合のパターンどおりにコーディングすればいいのですが、いくつか考慮点があります。

拡張情報には、基本情報の基底ポインタからオフセットを計算してしかたどりつけません。
拡張情報は基本情報に追加して存在する/基本情報を含んだより大きな構造体、というわけではないんですね。

また、拡張情報の中にジョブ情報へのオフセット値があるのですが、このオフセット値は基本情報の基底ポインタからのオフセットになっています。
拡張情報の基底ポインタから計算すると微妙にずれた位置に行くので「バグ?!」と思ってしまうかもしれませんが、そうではありません。

コーディング例

     H bnddir('QC2LE')                                                                              
      *                                                                                             
     D RtvNetCnnD      PR                                                                           
     D  pProtocol                     4a                                                            
     D  lAddr                        15a                                                            
     D  lPort                         5a                                                            
     D  rAddr                        15a                                                            
     D  rPort                         5a                                                            
      *                                                                                             
     D RtvNetCnnD      PI                                                                           
     D  pProtocol                     4a                                                            
     D  lAddr                        15a                                                            
     D  lPort                         5a                                                            
     D  rAddr                        15a                                                            
     D  rPort                         5a                                                            
      *                                                                                             
     D RtvNetCnnDta    Pr                  ExtProc( 'QtocRtvNetCnnDta' )                            
     D  spRcvVar                  65535a   Options( *VarSize )                                      
     D  spRcvVarLen                  10i 0 Const                                                    
     D  spFmtName                     8a   Const                                                    
     D  spSocReq                       *   value                                                    
     D  spError                   32767a   Options( *VarSize: *Omit )                               
     **                                                                                             
      *                                                                                             
     D inet_addr       Pr            10u 0 ExtProc( 'inet_addr' )                                   
     D  srcAddr                        *   value options(*string)                                   
      *                                                                                             
     **-- Api error data structure:                                                                 
     D ERRC0100        Ds                  Qualified                                                
     D  BytPro                       10i 0 Inz( %Size( ERRC0100 ))                                  
     D  BytAvl                       10i 0 Inz                                                      
     D  MsgId                         7a                                                            
     D                                1a                                                            
     D  MsgDta                      128a                                                            
     **-- Global variables:                                                                         
     D ApiRcvSiz       s             10u 0                                                          
     **                                                                                             
     DSocReqInfo       DS                  Qualified                                                
     D Protocol                      10U 0                                      Protocol            
     D LocalIP                       10U 0                                      Local IP Address    
     D LocalPort                     10U 0                                      Local Port Number   
     D RemoteIP                      10U 0                                      Remote IP Address   
     D RemotePort                    10U 0                                      Remote Port Number  
      *                                                                                             
     DNCND0100         DS                  Qualified BASED(p2CnnInfo)                               
     D BytRtnd                       10U 0                                      Bytes Returned      
     D BytAvl                        10U 0                                      Bytes Available     
     D TCPConnCur                    10U 0                                      TCP Connections Cur 
     D TCPActiveOpn                  10U 0                                      TCP Active Opens    
     D TCPPasiveOpn                  10U 0                                      TCP Passive Opens   
     D TCPAtOpnFail                  10U 0                                      TCP Attempted Opn F 
     D TCPEstRset                    10U 0                                      TCP Established And 
     D TCPSegSent                    10U 0                                      TCP Segments Sent   
     D TCPRtrsmtSeg                  10U 0                                      TCP Retransmited Sg 
     D TCPRsetSeg                    10U 0                                      TCP Reset Segments  
     D TCPSegRcvd                    10U 0                                      TCP Segments Rcvd   
     D TCPSegRcvdErr                 10U 0                                      TCP Segments Rcvd Er
     D UDPDtagrmSent                 10U 0                                      UDP Datagrams Sent  
     D UDPDtagrmRcvd                 10U 0                                      UDP Datagrams Rcvd  
     D UDPDtagrmNDNF                 10U 0                                      UDP Datagrms ND NF  
     D UDPDtagrmNDDE                 10U 0                                      UDP Datagrms ND Err 
     D OffSet2Add                    10U 0                                      Offset To Add Info  
     D Len4AddInf                    10U 0                                      Length Of Add Info  
      *                                                                                             
     DNCND0200         DS                  Qualified BASED(p2Cnd2Info)                              
     D Protocol                      10U 0                                      Protocol            
     D LocalIP                       10U 0                                      Local IP Address    
     D LocalPort                     10U 0                                      Local Port Number   
     D RemoteIP                      10U 0                                      Remote IP Address   
     D RemotePort                    10U 0                                      Remote Port Number  
     D RoundTripTime                 10U 0                                      Round Trip Time     
     D RoundTripVar                  10U 0                                      Round Trip Variance 
     D OutByteBuf                    10U 0                                      Outgoing Bytes Buff 
     D UsrSndNxt                     10U 0                                      User Send Next      
     D SndNxt                        10U 0                                      Send Next           
     D SndUnAck                      10U 0                                      Send Unacknowledged 
     D OutPushNbr                    10U 0                                      Outgoing Push No    
     D OutUrgNbr                     10U 0                                      Outgoing Urgency No 
     D OutWindNbr                    10U 0                                      Outgoing Window No  
     D InByteBuf                     10U 0                                      Incoming Bytes Buff 
     D RcvNxt                        10U 0                                      Receive Next        
     D UsrRcvNxt                     10U 0                                      User Receive Next   
     D InPushNbr                     10U 0                                      Incoming Push No    
     D InUrgNbr                      10U 0                                      Incoming Urgency No 
     D InWindNbr                     10U 0                                      Incoming Window No  
     D TotRetrnsmt                   10U 0                                      Total Retransmit    
     D CurRetrnsmt                   10U 0                                      Currect Retransmit  
     D MaxWindSize                   10U 0                                      Maximum Window Size 
     D CurWindSize                   10U 0                                      Current Window Size 
     D LastUpdate                    10U 0                                      Last Update         
     D LastUpdateAckd                10U 0                                      Last Update Acked   
     D CongWind                      10U 0                                      Congestion Window   
     D SlowStrThresld                10U 0                                      Slow Start Threshold
     D MaxSegSize                    10U 0                                      Max Segment Size    
     D InitSendSeqNbr                10U 0                                      Init Send Seq No    
     D InitRcvSeqNbr                 10U 0                                      Init Receive Seq No 
     D ConnTrnpLayr                  10U 0                                      Conn Transport Layer
     D TCPState                      10U 0                                      TCP State           
     D CnnOpnType                    10U 0                                      Conn Open Type      
     D IdleTimeMsec                  10U 0                                      Idle Time Millisec  
     D IPOptions                     40a                                        IP Options          
     D ByteIn                        10U 0                                      Bytes In            
     D BytesOut                      10U 0                                      Bytes Out           
     D SocState                      10U 0                                      Socket State        
     D OfsLstSocOpt                  10U 0                                      Offset List Of Sock 
     D SocOptNbr                     10U 0                                      Num Soc Opts W Cnn  
     D EntLenSocOpt                  10U 0                                      Ent Len Soc Opts    
     D Ofs2LstJobs                   10U 0                                      Ofs List Jobs A W C 
     D HowManyJobsCnn                10U 0                                      Num Jobs A W Conn   
     D EntLenLstJobs                 10U 0                                      Ent Len Jobs A W Cnn
     D AssocUSRPRF                   10a                                        Associated USRPRF   
     D rsvd                           2a                                        reserved            
      *                                                                                             
     DJobInfo          DS                  Qualified  BASED(p2JobInfo)                              
     D FmtEntry                      10u 0                                      Format Entry        
     D Taskname                      16a                                        Task Name           
     D Jobname                       10a                                        Job Name            
     D JobUser                       10a                                        Job User            
     D JobNumber                      6a                                        Job Number          
     D IntJobID                      16a                                        Job Internal ID     
     D JobType                        1a                                        Job Type            
     D rsvd                           7a                                        reserved            
     D CurUSRPRF                     10a                                        Associated USRPRF   
      *                                                                                             
     D  i              s             10u 0                                                          
      /Free                                                                                         
                                                                                                    
             *inLR = *on;                                                                           
                                                                                                    
             ApiRcvSiz = 65535;                                                                     
             p2CnnInfo = %alloc( ApiRcvSiz );                                                       
             NCND0100.BytAvl = *Zero;                                                               
                                                                                                    
              Select ;                                                                              
                when pProtocol = '*TCP' ;                                                           
                     SocReqInfo.Protocol = 1 ;                                                      
                when pProtocol = '*UDP' ;                                                           
                     SocReqInfo.Protocol = 2 ;                                                      
                other ;                                                                             
                     return ;                                                                       
              endSL ;                                                                               
                                                                                                    
              if lAddr = *blank ;                                                                   
                  return ;                                                                          
              else ;                                                                                
                  SocReqInfo.LocalIP = inet_addr(%trimR(lAddr)) ;                                   
              endif ;                                                                               
                                                                                                    
              if lPort = *blanks ;                                                                  
                  return ;                                                                          
              else ;                                                                                
                  SocReqInfo.LocalPort = %int(lPort) ;                                              
              endif ;                                                                               
                                                                                                    
              if rAddr = *blank ;                                                                   
                  return ;                                                                          
              else ;                                                                                
                  SocReqInfo.RemoteIP = inet_addr(%trimR(rAddr)) ;                                  
              endif ;                                                                               
                                                                                                    
              if rPort = *blanks ;                                                                  
                  return ;                                                                          
              else ;                                                                                
                  SocReqInfo.RemotePort = %int(rPort) ;                                             
              endif ;                                                                               
                                                                                                    
             DoU  NCND0100.BytAvl <= ApiRcvSiz     Or                                               
                  ERRC0100.BytAvl  > *Zero;                                                         
                                                                                                    
               If  NCND0100.BytAvl > ApiRcvSiz;                                                     
                 ApiRcvSiz = NCND0100.BytAvl;                                                       
                 p2CnnInfo = %reAlloc( p2CnnInfo: ApiRcvSiz );                                      
               EndIf;                                                                               
                                                                                                    
               RtvNetCnnDta( NCND0100                                                               
                            : ApiRcvSiz                                                             
                            : 'NCND0200'                                                            
                            : %addr(SocReqInfo)                                                     
                            : ERRC0100                                                              
                             );                                                                     
              EndDo;                                                                                
                                                                                                    
              If  ERRC0100.BytAvl = *Zero;                                                          
                                                                                                    
                p2Cnd2Info = p2CnnInfo + NCND0100.OffSet2Add ;                                      
                                                                                                    
                 If NCND0200.HowManyJobsCnn = *Zero;                                                
                   return ;                                                                         
                 endIf ;                                                                            
                                                                                                    
            //  p2JobInfo = p2Cnd2Info + NCND0200.Ofs2LstJobs ;                                     
            //  Not offset from NCND0200 but NCND0100 ... (see above)                               
                p2JobInfo = p2CnnInfo + NCND0200.Ofs2LstJobs ;                                      
                                                                                                    
                for i = 1 to NCND0200.HowManyJobsCnn ;                                              
                // do something                                                                     
                  p2JobInfo = p2JobInfo + NCND0200.EntLenLstJobs ;                                  
                endfor ;                                                                            
                                                                                                    
              EndIf;                                                                                
                                                                                                    
              Dealloc p2CnnInfo ;                                                                   
                                                                                                    
              return;                                                                               
                                                                                                    
      /End-Free                                                                                     

[Top Pageに戻る]

Ads by TOK2