API Corner: TCP/IP List Network Interfaces to a Browser
June 29, 2005 Shannon O'Donnell
The code for this article is available for download.
Welcome to a new feature of Four Hundred Guru called API Corner, where I will mine the mountain of APIs in OS/400 to find the gems that you can use. This week, I will be taking a look at the List TCP/IP Network Interfaces API. This API allows you to programmatically list the network interfaces on your system and retrieve certain information about same.
For example, some of the information you can retrieve includes the IP address of the network interface as well as its name and type. To make this example even more useful, we will push the information to a Web browser.
To push all of the retrieved network interface information to the user’s browser, we will use some simple CGI APIs. For more detailed information on how to use the CGI APIs to push a Web page to the browser from the iSeries, please refer to Step by Step, RPG IV and Interactive Web Pages. That article contains complete instructions on how to create a CGI program and how to set up the HTTP server on your iSeries to serve the output from your CGI programs to your users via the Web. You can download the sample program from this article at fhg062905-story01.zip.
QtocLstNetIfc
The API to List Network Interfaces is actually a procedure defined in IBM Service Program QTocNetSts which is included with the TCP/IP Utilities that came with your iSeries. The procedure name is QtocLstNetIfc. In order to use this external procedure, you will need to define a prototype in your RPGLE program that looks like the following:
*======================================== * List Network Intraces API Prototype *======================================== D ListNetInt PR ExtProc('QtocLstNetIfc') D UserSpace 10A const D Format 8A const D ErrorDs 256A const
Notice that we are using the ExtProc keyword as opposed the ExtPgm. We do this because we are accessing a procedure in a service program, not a stand alone program.
Because this procedure returns its data as a list value, we need a place to dump this list. For this API, we will use a user space to store the returned data.
So the first thing we need to do is to create the user space. We do that with the following bit of code:
* Create the Qualified User Space Name C Eval qUserNm = 'LSTNETINTFQGPL' C Eval qText = 'List Network Interface' * * Attempt to delete the user space first... * Just to clean it up C Call 'QUSDLTUS' 50 C Parm qUserNm C Parm dsEc * * Now create the user space C Call 'QUSCRTUS' 50 C Parm qUserNm C Parm *Blanks eXtAtr C Parm 5000 iNzSize C Parm *Blanks iNVal C Parm '*CHANGE' pUbAut C Parm qText C Parm rEplace C Parm dsEc *
As you can see here, we first named the user space, then attempted to delete it if it already existed, and then we tell the API to create the user space in library QGPL. You could just as easily move the deletion of the user space to the end of the program if you wanted and let that be the last thing that happens just before program termination. It’s entirely up to you.
Once the user space has been created we can then call the List Network Interface API to list all of the network interfaces on your system into the user space. Here’s how you would call this API:
* Now List the Network Intefaces and Place Into The User Space C Eval Format = 'NIFC0100' C Callp ListNetInt(qUserNM:Format:dsEc)
Extracting Data from the User Space
Now that the network interfaces have been listed into the user space, we can iterate through that user space to retrieve the information.
If you have never used any of the List APIs on the iSeries, then looping through a user space might be a new to you. Don’t let that discourage you if you fall into that category. The List APIs are actually pretty easy to use, assuming you define the required data structures correctly ahead of time, that is. And since I have already done that for you, there should not be any problem using these APIs.
Every List API builds a common header data structure. That is, no matter what kind of object a List API reports on, you will have a data structure with the following data:
********************************************* * List Data Generic Header ********************************************* D HdrSection Ds D UserArea 64 D GenHdrSiz 10i 0 D StrucLevel 4 D FormatName 8 D ApiUsed 10 D CreateStamp 13 D InfoStatus 1 D SizeUsUsed 10i 0 D InpParmOff 10i 0 D InpParmSiz 10i 0 D HeadOffset 10i 0 D HeaderSize 10i 0 D ListOffset 10i 0 D ListSize 10i 0 D ListNumber 10i 0 D EntrySize 10i 0
You can retrieve the header information into this data structure from the user space by executing this bit of code:
* Get the User Space Header Section C Call 'QUSRTVUS' C Parm qUserNM C Parm 1 qStart C Parm 140 qLen C Parm *Blanks HdrSection C Parm dsEc
Within this data structure you have all the information you need to process the contents of the user space. For example, by looking at the ListNumber variable, you can tell how many entries were returned by the QTocLstNetIfc API. In other words, in this case, the network interfaces on your system. By looking at the EntrySize variable, you can tell how long each entry in the list is, and by looking at the ListOffset, you can tell where in the user space to start extracting the first entry. Knowing all of this, we can then very easily loop through the user space and pull out the information we need.
* Write the HTML Header Information to the Browser C Exsr HTMLHdr * C Eval qStart = ListOffset + 1 * * ** Loop through User Space for number of list entries returned C Do ListNumber * C Call 'QUSRTVUS' C Parm qUserNM C Parm qStart C Parm EntrySize qLen C Parm *Blanks NIFC0100 C Parm dsEc * * Write the HTML Detail Information To the Browser from * the contents of the User Space C Exsr HTMLDtl * C Eval qStart = qStart + EntrySize C Enddo
Within this section of code, the first thing we do is to send the HTML webpage header information to the browser. You can refer to the sample program that accompanies this article to see how that part works. The next thing we do is set our index variable to the beginning of the returned data in the user space. We can determine this starting position by adding one to the ListOffset from the header data structure. Then entering the loop, which will loop for the number of entries returned in the list, we can call the QUSRTVUS (Retrieve User Space) API to pull the list data out of the user space and dump it into our data structure named NIFC0100, which describes the output from the QtocLstNetIfc API.
**************************************** * Output format for API QtocLstNetIfc **************************************** D NIFC0100 DS D IPAddress 15a D Rsvd1 1a D IpAdrBin 10i 0 D NetAddress 15a D Rsvd2 1a D NetAdrBin 10i 0 D NetName 10a D LineDesc 10a D IntfcName 10a D Rsvd3 2a D IntfcStat 10i 0 D IntfcSvcTyp 10i 0 D IntfcMTU 10i 0 D IntfcLnTyp 10i 0 D HostAddress 15a D Rsvd4 1a D HostAdrBin 10i 0 D IntfcSubNet 15a D DirBrdCstAdr 15a D Rsvd5 1a D DirBrdCstBin 10i 0 D ChangeDate 8a D ChangeTime 6a D AssocLclInt 15a D Rsvd6 3a D AssocLclBin 10i 0 D ChangeStat 10i 0 D PacketRules 10i 0 D AutoStart 10i 0 D TRLANBitSeq 10i 0 D IntfacType 10i 0 D ProxyARPEnl 10i 0 D ProxyARPAlw 10i 0 D ConfigMTU 10i 0 D NetNameFull 24a D IntNameFull 24a
I got the format for this data structure from the online documentation on IBM’s Information Center Web site for the QtocLstNetIfc API. There is a lot of information you can retrieve about a network interface. In our example program, we will only be displaying a few pieces of that data. Some of the information is stored as a numeric value so in order to convert it to something a little more friendly to the eye, I’ve defined a couple of subroutines to convert that number to a text value.
********************************************* * GetLinType - Translate Numeric Line Type Value to Text ********************************************* C GetLinType Begsr C Select C When IntfcLnTyp = -1 C Eval LineType = 'Other' C When IntfcLnTyp = -2 C Eval LineType = 'None' C When IntfcLnTyp = -3 C Eval LineType = 'Error' C When IntfcLnTyp = -4 C Eval LineType = 'NotFnd' C When IntfcLnTyp = 1 C Eval LineType = 'ELAN' C When IntfcLnTyp = 2 C Eval LineType = 'TRLAN' C When IntfcLnTyp = 3 C Eval LineType = 'FR' C When IntfcLnTyp = 4 C Eval LineType = 'ASYNC' C When IntfcLnTyp = 5 C Eval LineType = 'PPP' C When IntfcLnTyp = 6 C Eval LineType = 'WLS' C When IntfcLnTyp = 7 C Eval LineType = 'X.25' C When IntfcLnTyp = 8 C Eval LineType = 'DDI' C When IntfcLnTyp = 9 C Eval LineType = 'TDLC' C When IntfcLnTyp = 10 C Eval LineType = 'L2TP' C Endsl C Endsr ********************************************** * GetIntStat - Translate Numeric Interface Status to Text ********************************************** C GetIntStat Begsr C Select C When IntfcStat = 0 C Eval IStatus = 'Inactive' C When IntfcStat = 1 C Eval IStatus = 'Active' C When IntfcStat = 2 C Eval IStatus = 'Starting' C When IntfcStat = 3 C Eval IStatus = 'Ending' C When IntfcStat = 4 C Eval IStatus = 'RCYPND' C When IntfcStat = 5 C Eval IStatus = 'RCYCNCL' C When IntfcStat = 6 C Eval IStatus = 'Failed' C When IntfcStat = 7 C Eval IStatus = 'ASYNC' C When IntfcStat = 8 C Eval IStatus = 'DOD' C Endsl C Endsr
Writing the Information to the Browser
Now that you have this information, all you need to do is to write it out to your Web browser. To do that, send the data to be written to the Web browser to the Write to Standard Output, API, QtmhWrStout.
******************************************** * Writes HTML Code to STDOUT (user's browser) C SendToBrwsr Begsr * * Get the length of the data to write to STDOUT C eval BrwsrDtaln = %len(%trimr(BrwsrDta)) * C Callb 'QtmhWrStout' C Parm BrwsrDta C Parm BrwsrDtaln C PARM DsEc * C Endsr
For this example, I am doing nothing more than building a simple HTML Table into my Web page with some table headings that describe the data in the table, and then for each row of the table, I am listing the information returned in the NIFC0100 data structure.
The List Network Interfaces API is a very handy tool, especially if you have defined a lot of routes into your system. In future articles we will take a look at some of the other TCP/IP Management APIs to see how you can extract even more useful data from your system.