Retrieve TCP/IP API Information Using Java Toolbox

General
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Are you a Java developer looking to retrieve iSeries TCP/IP system API information? If so, this article is definitely for you. Here, you'll learn how to use Java Toolbox  to retrieve information using the TCP/IP management APIs that have been available since OS/400 V5R1.

Depending on the type of application a customer is creating, you can obtain certain iSeries system information. For instance, in a sockets application that allows many customers to connect to your iSeries system, you may want to monitor what IP address and Media Access Control (MAC) address is connecting to your system. An IP address is a network identifier that can be assigned to a system. The MAC address is the physical address that is burned into a computer's network card. If a client that connects to your iSeries socket application is doing something that makes you feel uncomfortable, you can retrieve its IP and MAC addresses using one of the iSeries TCP/IP system APIs.

When a client connects to your iSeries system from an external network for the first time, an ARP REQUEST must be sent out from your iSeries system to map the client's MAC address with its IP address. When your system receives an ARP REPLY with the MAC address, that value is put into the ARP table of the iSeries system. When the client connects again, it won't be necessary to send another ARP REQUEST to find the client's MAC address. On the iSeries, the TCP/IP system API called QtocLstPhyIfcARPTbl lists all the data for the iSeries ARP table.

When using system APIs, you need to know how to call them and what information to input. The QtocLstPhyIfcARPTbl requires a user space name, a format name, and a line name, as shown in the table below. If any problems occur when calling the API an error code will be outputted so you don’t have to worry about any input value to place within the error code.

Qualified user space name
Input
Char(20)
Format name
Input
Char(8)
Line name
Input
Char(10)
Error code
I/O
Char(*)

Service Program: QTOCNETSTS
Threadsafe: Yes


When calling the QtocLstPhyIfcARPTbl, you must put all the information into a predefined user space that you can create on the iSeries system.

A format name is also required because many iSeries system APIs have different formats. It is important to know the format because, when the API is called, all the information gets put in a predefined location within the user space. To retrieve that information, you need to know the exact decimal number within the user space. Within the QtocLstPhyIfcARPTbl, there is only one format name, ARPT0100 (see the table below).

Offset
Type
Field
Dec
Hex
0
0
CHAR(15)
Internet address
15
F
CHAR(1)
Reserved
16
10
BINARY(4)
Internet address binary
20
14
BINARY(4)
Line type
24
18
BINARY(4)
Ethernet type
28
1C
BINARY(4)
Type of entry
32
20
BINARY(4)
Data link connection identifier (DLCI)
36
24
BINARY(4)
Routing information field (RIF) valid mask
40
28
CHAR(18)
Routing information field (RIF)
58
3A
CHAR(17)
Physical address
75
4B
CHAR(1)
Reserved


The third parameter is the line name. When inputting this value, you can hard-code it in if you know it will not change or you can call the Retrieve Line Description (QDCRLIND) API, which will allow you to return the name of your line description. If you are designing a GUI, you can allow a user to choose among a number of line names for a particular iSeries system.

Using the Java Toolbox

Now that you understand how the system API works, you can put Java Toolbox to work. Java Toolbox has an API called ProgramCall. The ProgramCall class allows a user to call an iSeries system API, pass parameters to it (input and output), and access data returned in the output parameters after the program runs. Use ProgramCall to call programs; use ServiceProgramCall to call service programs. You will notice in the first table that the QtocLstPhyIfcARPTbl API has a service program called QTOCNETSTS. Since it's a service program, you will use the ServiceProgramCall.

Take a look at some of the code that allows you to call the QtocLstPhyIfcARPTbl and retrieve data back from the user space. Remember, before calling this system API, you need to create a user space. Java Toolbox has a UserSpace class that allows you to do just that. In the following method (Figure 1), you will see that I created a UserSpace object called ARP in library GARBERSB.

//Method that allows us to create a UserSpace in library
//GARBERSB called ARP.
public void createUserSpace() {
try {
//Create the UserSpace object.
us = new UserSpace(system, "/QSYS.LIB/GARBERSB.LIB/ARP.USRSPC");

//When set to true this means that ProgramCall has read
//and write access to this UserSpace.
us.setMustUseProgramCall(true);

//Create the UserSpace with an initial size of 256 * 1024,
//a true value informing us the UserSpace can be replaced,
//no extended attribute, an initial value of 0 and the 
//public authority set to *EXCLUDE.
us.create(
256 * 1024,
true,
"",
(byte) 0,
"User space for Netstat Connections",
"*EXCLUDE");

catch (Exception e) {
System.out.println("Problems creating the user space.");
}
}

Figure 1: Use this code to create a user space.

Once the user space is created, you can fill in your system API parameters. First, define the ProgramParameter array with a length of 4. Note that the AS400 system object has been pre-created. This is shown in Figure 2.

// The API has 4 parameters.
ProgramParameter[] parms = new ProgramParameter[4];


// PARM 1: We will use the AS400Text to take our the library name and 

//user space name and place it into our parms array.
AS400Text userSpaceText = new AS400Text(20, system.getCcsid(), system);
parms[0] = new ProgramParameter(

     userSpaceText.toBytes(fullyQualifiedUserSpaceName));


// PARM 2: Format Name ARPT0100 in the List Physical Interface ARP 

//Table API
String formatName = "ARPT0100";
AS400Text text4 = new AS400Text(8, system.getCcsid(), system);
parms[1] = new ProgramParameter(text4.toBytes(formatName));

// PARM 3: Format Name ARPT0100 in the List Physical Interface ARP Table 

//API. Note that we pass in the line name.
AS400Text text = new AS400Text(10, system.getCcsid(), system);
parms[2] = new ProgramParameter(text.toBytes(lineName));

//PARM 4:  Error messages that will be called from the API.
parms[3] = new ProgramParameter(new byte[5]);

// We will pass everything in by reference
parms[0].setParameterType(ProgramParameter.PASS_BY_REFERENCE);
parms[1].setParameterType(ProgramParameter.PASS_BY_REFERENCE);
parms[2].setParameterType(ProgramParameter.PASS_BY_REFERENCE);
parms[3].setParameterType(ProgramParameter.PASS_BY_REFERENCE);

Figure 2: This code sets the ProgramParameter array.

Once you have your ProgramParameter set up, all you have to do is create and call the ServiceProgramCall. It is important to make sure you catch possible AS400Messages that might end up getting thrown for debugging purposes. See Figure 3.

// Now setup the ProgramCall.
ServiceProgramCall pc = new ServiceProgramCall(
system,
"/QSYS.LIB/QTOCNETSTS.SRVPGM",
"QtocLstPhyIfcARPTbl",
parms);


//Now we will call the ProgramCall that we created above
try {
boolean result = pc.run();

// If the call didn't work, check for any messages.
if (!result) {
AS400Message[] messages = pc.getMessageList();
for (int i = 0; i < messages.length; ++i) {

// Show each message
messages[i].load();
System.out.println(messages[i].getText());
System.out.println(messages[i].getID());
System.out.println(messages[i].toString());
System.out.println(messages[i].getHelp());

}

else {
System.out.println("QtocLstPhyIfcARPTbl API Worked");
}

Figure 3: Call the service program.

Now that you have called the QtocLstPhyIfcARPTbl, you can retrieve the information that was put within your user space. Figure 4 shows how you can retrieve certain information from the user space.

//We will create a byte buffer to read the information in from the 

//UserSpace
byte[] buf = null;

//Here we will get the length of the UserSpace
int size = us.getLength();
buf = new byte[size];

//Temporary int value of where we are in the UserSpace.
int temp = us.read(buf, 0);

//We will print out the Starting offset
int startingOffset = BinaryConverter.byteArrayToInt(buf, 124);
System.out.println("Starting offset " + startingOffset);

//We will print out the number of entries
int numEntries = BinaryConverter.byteArrayToInt(buf, 132);
System.out.println("Number of entries " + numEntries);

//Here we will get the entry size and print it out.
int entrySize = BinaryConverter.byteArrayToInt(buf, 136);
System.out.println("Entry size " + entrySize);

int index = 0;

//We will loop through each entry.
if (numEntries > 0) {
forLoop : for (int i = 0; i < numEntries; i++) {

//Set the index value.
index = startingOffset + (i * entrySize);
CharConverter ch = new CharConverter(ccsid, system);

//Retrieve the IP Address
//Note that we get the value 16 from the ARPT0100 API
index += 16;
a.setInternetAddress(
Common.intToIPString( BinaryConverter.byteArrayToInt(buf, index)));
}

Figure 4: Retrieve information from your predefined user space.

As you can see, you can keep on increasing the index by the decimal offset value of the API.

Figure 5 shows an example of what happens when you run the example code. Note that you will have to log onto an iSeries system that has a release of V5R1 or later.

Defining Program Parameters.
Fully Qualified UserSpace Name :ARP       GARBERSB  
Before reading the UserSpace()
After reading the UserSpace()
Let's try Retrieving ARP Information now.
QtocLstPhyIfcARPTbl API Worked
Starting offset 644
Number of entries 8
Arp Object Length will be [Lcom.ibm.test.arp.ArpObject;@193722c
Entry size 76
Entry ccsid 37
------------------------------------------------
Internet Address 9.5.4.129
Line Type Ethernet
Ethernet Type Ethernet Version 2
Type Of Entry Dynamic
DLCI 0
RIF Valid Mask Not Valid
RIF null


Physical Address 00:00:0C:07:AC:01
30 30 3a 30 36 3a 32 39 3a 45 43 3a 36 30 3a 39 39 

Figure 5: This output is a result of the example code.

In the example output, you now see that the IP address 9.5.4.129 is within the ARP table with a MAC address of 00:00:0C:07:AC:01. You can implement this information within your socket application, possibly disconnecting it and not letting it connect in the future if the client is doing something malicious.

Now that you know how to program the QtocLstPhyIfcARPTbl API, you should be able to move on to program different iSeries system TCP/IP APIs. All of the TCP/IP APIs can be viewed within the iSeries Information Center. Many of the APIs can be useful when you want certain information to be retrieved within your application.

Benjamin Garbers is a Software Engineer within the Rochester Support Center. He is currently developing Internet applications for IBM's iSeries Technical Web site.

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$0.00 Raised:
$