|
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-2024 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.