|
Hi Silvio,
At the bottom of the message is a utility program that will
look up domain names for a given IP address, or vice-versa. It is
designed to be callable from any other language (RPG II, RPG/400,
CL, etc) Compilation instructions, what parameters to give, etc
are all detailed in the comments within the code.
The AS/400 that I use is running V3R2. I've tested the code on
this machine, and it works. I have not tried it on any other versions
but, I don't know of any reasons why it wouldnt work on any later
versions as well.
Hope this helps...
"Silvio Santos" <Silvio.Santos@brainag.com> wrote:
>
> Hi Scott it would be great if you give me an example so I can call i
> from RPG/400,
> Thanks,
> Silvio.
>
** Normally, I keep the following definitions as part of a larger
** member containing the definitions for all of the sockets API,
** called SOCKET_H, I copied the necessary stuff in-line to simplify
** this example code.
**
** To compile:
** CRTBNDRPG PGM(xxxx) SRCFILE(xxxx/xxxx) DFTACTGRP(*NO) +
** ACTGRP(*CALLER)
** (actually, activation group can be whatever you prefer)
**
** Disclaimer:
** This program is meant to be an "example", to help explain a
** programming technique. Although it works to the best of my
** knowledge, neither I, nor my employer will be held responsible
** for any damages that it may cause.
** -------------------------------------------------------------------
D* The "internet" address family.
** -------------------------------------------------------------------
D AF_INET C CONST(2)
** -------------------------------------------------------------------
** inet_addr()--Converts an address from dotted-decimal format
** to a 32-bit IP address.
**
** unsigned long inet_addr(char *address_string)
**
** Converts an IP address from format 192.168.0.100 to an
** unsigned long, such as hex x'C0A80064'.
**
** returns -1 on error
** -------------------------------------------------------------------
D INet_Addr PR 10U 0 ExtProc('inet_addr')
D char_addr 16A
** -------------------------------------------------------------------
** inet_ntoa()--Converts an address from 32-bit IP address to
** dotted-decimal format.
**
** char *inet_ntoa(struct in_addr internet_address)
**
** Converts from 32-bit to dotted decimal, such as, x'C0A80064'
** to '192.168.0.100'. Will return -1 on error
**
** -------------------------------------------------------------------
D inet_ntoa PR * ExtProc('inet_ntoa')
D ulong_addr 10U 0 VALUE
** -------------------------------------------------------------------
** "Special" IP Address values
** -------------------------------------------------------------------
D* any address availabl
D INADDR_ANY C CONST(0)
D* broadcast
D INADDR_BRO C CONST(4294967295)
D* loopback/localhost
D INADDR_LOO C CONST(2130706433)
D* no address exists
D INADDR_NON C CONST(4294967295)
** -------------------------------------------------------------------
** gethostbyname() -- Resolves a domain name to an IP address
**
** struct hostent *gethostbyname(char *host_name)
**
** struct hostent {
** char *h_name;
** char **h_aliases;
** int h_addrtype;
** int h_length;
** char **h_addr_list;
** };
**
** Returns a pointer to a host entry structure. The aliases and
** address list items in the structure are pointers to arrays of
** pointers, which are null terminated.
**
** -------------------------------------------------------------------
D GetHostNam PR * extProc('gethostbyname')
D HostName 256A
** -------------------------------------------------------------------
** gethostbyaddr()--Get Host Information for IP Address
**
** struct hostent *gethostbyaddr(char *host_address,
** int address_length,
** int address_type)
** struct hostent {
** char *h_name;
** char **h_aliases;
** int h_addrtype;
** int h_length;
** char **h_addr_list;
** };
**
** An IP address (32-bit integer formnat) goes in, and a
** hostent structure pops out. Really, kinda fun, if you
** havent already learned to hate the hostent structure, that is.
**
** -------------------------------------------------------------------
D GetHostAdr PR * ExtProc('gethostbyaddr')
D IP_Address 10U 0
D Addr_Len 10I 0 VALUE
D Addr_Fam 10I 0 VALUE
** -------------------------------------------------------------------
** Host Database Entry (for DNS lookups, etc)
**
** (this is a partial implementation... didn't try to
** figure out how to deal with all possible addresses
** or all possible aliases for a host in RPG)
**
** struct hostent {
** char *h_name;
** char **h_aliases;
** int h_addrtype;
** int h_length;
** char **h_addr_list;
** };
**
** #define h_addr h_addr_list[0]
** -------------------------------------------------------------------
D p_hostent S *
D hostent DS Based(p_hostent)
D h_name *
D h_aliases *
D h_addrtype 5I 0
D h_length 5I 0
D h_addrlist *
D p_h_addr S * Based(h_addrlist)
D h_addr S 10U 0 Based(p_h_addr)
D*** internal "work" variables. (not part of /COPY file)
D wkInput S 256A
D wkIP S 10U 0
D wkLen S 10I 0
D p_Name S * INZ(*NULL)
D wkName S 256A BASED(p_name)
C****************************************************************
C* Parameters:
C*
C* RetType: May be *NAME or *ADDR. If *NAME is given,
C* we'll return a domain name. If *ADDR we'll return an
C* IP Address.
C*
C* Input: Host or IP address to lookup. IP addresses should
C* be given in x.x.x.x format.
C*
C* Output: Resulting IP address, host name or error code.
C* Error codes are: *TYPE = invalid "RetType" parameter.
C* *BLANK = Input cant be blank
C* *FAIL = Lookup failed for this host.
C*
C* Note: This program is meant to be called from another
C* program, not from the command line. If you're
C* intending to call it from the command line, I'd recommend
C* making a simple command and CL front-end. (If you call
C* this program directly, OS/400 will mess up the long parms)
C****************************************************************
C *entry plist
c parm RetType 5
c parm Input 256
c parm Output 256
C* If we werent given enough parms, just end this program now...
C* (we'll seton LR, even) We can't return an error since we
c* don't have an output parm to return it in (ack!)
c if %parms < 3
c eval *inlr = *on
c return
c endif
C* Did we have a valid return type?
c if RetType <> '*NAME'
c and RetType <> '*ADDR'
c eval Output = '*TYPE'
c Return
c endif
C* Was some input given?
C if Input = *blanks
c eval Output = '*BLANK'
c Return
c endif
C* were we given an IP address or a name?
c eval wkInput = %trim(Input) + x'00'
c eval wkIP = inet_addr(wkInput)
C* An address was requested... and the input was already
C* an address... return the input directly.
C* (this is useful in an interactive application where the
C* calling program might not know if the address typed was
C* an IP address or a name)
c if RetType = '*ADDR'
c and wkIP <> INADDR_NON
c eval Output = %trim(Input)
c Return
c endif
C* Call the OS/400 resolver routines to get the information that
C* we require. (It will check the hosts table first, then try DNS)
c if wkIP = INADDR_NON
c eval p_hostent = gethostnam(wkInput)
c else
c eval p_hostent = gethostadr(wkIP:4:AF_INET)
c endif
c if p_hostent = *NULL
c eval Output = '*FAIL'
c return
c endif
C* if we're returning an address, we'll need to use inet_ntoa
C* to convert it back to dotted-decimal x.x.x.x format.
C*
c if RetType = '*ADDR'
c eval p_name = inet_ntoa(h_addr)
c if p_name = *NULL
c eval Output = '*FAIL'
c else
c x'00' scan wkName wkLen
c eval Output = %subst(wkName:1:wkLen-1)
c endif
c return
c endif
C* the hostent structure contains a pointer to the requested
C* domain name... we'll need to base a variable on that pointer,
C* and then convert it from the "C" format for strings to a
C* fixed-length RPG string
c if h_name = *NULL
c eval Output = '*FAIL'
c return
c endif
c eval p_name = h_name
c x'00' scan wkName wkLen
c eval Output = %subst(wkName:1:wkLen-1)
c return
+---
| This is the RPG/400 Mailing List!
| To submit a new message, send your mail to RPG400-L@midrange.com.
| To subscribe to this list send email to RPG400-L-SUB@midrange.com.
| To unsubscribe from this list send email to RPG400-L-UNSUB@midrange.com.
| Questions should be directed to the list owner/operator: david@midrange.com
+---
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2025 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.