/*****************************************************************************/ /* TCPIP.h */ /*****************************************************************************/ #ifndef TCPIP_H_LOADED #define TCPIP_H_LOADED 1 /********************/ /* TCP/IP constants */ /********************/ #define INET_PROTYP$C_STREAM 1 #define INETACP$C_TRANS 2 #define INETACP$C_HOSTENT_OFFSET 5 #define INETACP_FUNC$C_GETHOSTBYNAME 1 #define INETACP_FUNC$C_GETHOSTBYADDR 2 #define TCPIP$C_INADDR_ANY 0 #define TCPIP$C_AF_INET 2 #define TCPIP$C_AF_INET6 26 #define TCPIP$C_DSC_ALL 2 #define TCPIP$C_FULL_DUPLEX_CLOSE 8192 #define TCPIP$C_TCP_MAXSEG 2 #define TCPIP$C_MSG_NBIO 64 #define TCPIP$C_MSG_PEEK 2 #define TCPIP$C_REUSEADDR 4 #define TCPIP$C_SNDBUF 4097 #define TCPIP$C_RCVBUF 4098 #define TCPIP$C_SHARE 4105 #define TCPIP$C_CCL 4106 #define TCPIP$C_SOCK_NAME 4 #define TCPIP$C_SOCKOPT 1 #define TCPIP$C_TCPOPT 6 #define TCPIP$C_TCP 6 /*********************/ /* TCP/IP structures */ /*********************/ /* ensure BSD 4.4 structures */ #define _SOCKADDR_LEN #pragma __member_alignment __save #pragma __nomember_alignment #define SIN_ADDR_SIZE 4 #define SIN$C_LENGTH 16 #define SIN$K_LENGTH 16 /* 27-APR-2021 MGD modified in line with BSD 4.4 structure */ typedef struct _SOCKADDRIN { unsigned char SIN$B_LEN; /* length of this struct */ unsigned char SIN$B_FAMILY; /* address family */ unsigned short int SIN$W_PORT; /* 2 bytes specifying a port */ unsigned int SIN$L_ADDR; /* 4 bytes specifying an IP address */ char SIN$T_ZERO [8]; /* 8 bytes */ } SOCKADDRIN; #define SIN6_ADDR_SIZE 16 #define SIN6$K_LENGTH 28 #define SIN6$C_LENGTH 28 typedef struct _SOCKADDRIN6 { unsigned char SIN6$B_LEN; /* length of this struct */ unsigned char SIN6$B_FAMILY; /* AF_INET6 */ unsigned short int SIN6$W_PORT; /* Transport layer port number */ unsigned int SIN6$L_FLOWLABEL; /* IPv6 flow information */ union { char SIN6$T_ADDR [16]; unsigned char SIN6$B_SA6_ADDR [16]; unsigned short int SIN6$W_SA6_WADDR [8]; unsigned int SIN6$L_SA6_LADDR [4]; unsigned int SIN6$Q_SA6_QADDR [2] [2]; } SIN6$R_ADDR_OVERLAY; unsigned int SIN6$L_SCOPE_ID; /* set of interfaces for a scope */ } SOCKADDRIN6; #define HOST$L_H_ADDR 16 #define HOST$C_LENGTH 20 #define HOST$K_LENGTH 20 typedef struct _HOSTENT { int HOST$L_H_NAME; /* pointer to the host name */ int HOST$L_H_ALIASES; /* pointer to array of pointers to alias */ unsigned int HOST$L_H_ADDRTYPE; /* host address type */ unsigned int HOST$L_H_LENGTH; /* length of address */ int HOST$L_H_ADDR_LIST; char HOST_STORAGE[1004]; } HOSTENT; #pragma __member_alignment __restore /*****************/ /* module macros */ /*****************/ #define TCPIP_HOSTNAME_MAX 127 /* must be able to accomodate both IPv4 and Ipv6 address strings */ #define TCPIP_ADDRESS_STRING_MAX 39 /* default number of seconds each cache entry remains current */ #define TCPIP_HOST_CACHE_EXPIRE_SECONDS 600 /* default number of 2 second retries */ #define TCPIP_LOOKUP_RETRY_COUNT 5 /* number of entries by which host/address cache is expanded */ #define TCPIP_HOST_CACHE_CHUNK 128 /* absolute maximum number of entries for host/address cache */ #define TCPIP_HOST_CACHE_MAX 1024 /* maximum number of IP addresses per host cache entry */ #define TCPIP_HOST_CACHE_ENTRIES_MAX 8 /*********************/ /* IP address macros */ /*********************/ /* set this IPADDRESS to have an IPv4 size */ #define IPADDRESS_V4(addr) (addr)->iadr_size=SIN_ADDR_SIZE /* set this IPADDRESS to have an IPv6 size */ #define IPADDRESS_V6(addr) (addr)->iadr_size=SIN6_ADDR_SIZE /* set this IPADDRESS to anyaddress using size */ #define IPADDRESS_SET(addr,value) \ memcpy((void*)(addr)->address,value,(void*)(addr)->iadr_size) /* to have a zeroed address and size (i.e. be neither IPv4 or IPv6) */ #define IPADDRESS_ZERO(addr) memset((void*)(addr),0,sizeof(IPADDRESS)) /* to have an IPv4 size and zeroed address */ #define IPADDRESS_ZERO4(addr) \ {(addr)->iadr_size=SIN_ADDR_SIZE;\ memset((void*)(addr)->address,0,SIN_ADDR_SIZE);} /* to have an IPv6 size and zeroed address */ #define IPADDRESS_ZERO6(addr) \ {(addr)->iadr_size=SIN6_ADDR_SIZE;\ memset((void*)(addr)->address,0,SIN6_ADDR_SIZE);} /* set the address to contain 0x00 (IPADDR_ANY) */ #define IPADDRESS_SET_ANY(addr) \ memset((void*)(addr)->address,0x00,(addr)->iadr_size); /* set the address to contain 0xff (unusable) */ #define IPADDRESS_SET_UNUSABLE(addr) \ memset((void*)(addr)->address,0xff,(addr)->iadr_size); /* true if this IPADDRESS has an IPv4 size */ #define IPADDRESS_IS_V4(addr) ((addr)->iadr_size==SIN_ADDR_SIZE) /* true if this IPADDRESS has an IPv6 size */ #define IPADDRESS_IS_V6(addr) ((addr)->iadr_size==SIN6_ADDR_SIZE) /* true if this address is INADDR_ANY (all zero) */ #define IPADDRESS_IS_ANY(addr) \ (!memcmp((addr)->address,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",(addr)->iadr_size)) /* true if this address is all zero */ #define IPADDRESS_IS_RESET(addr) \ (!memcmp((addr)->address,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",(addr)->iadr_size)) /* true if this address is not all zero */ #define IPADDRESS_IS_SET(addr) \ memcmp((addr)->address,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",(addr)->iadr_size) /* true if this address is unusable (all oneses) */ #define IPADDRESS_IS_UNUSABLE(addr) \ (!memcmp((addr)->address,"\xff\xff\xff\xff\xff\xff\xff\xff\ \xff\xff\xff\xff\xff\xff\xff\xff",(addr)->iadr_size)) /* true if the address structures are exactly the same */ #define IPADDRESS_IS_SAME(addr1,addr2) \ (!memcmp((void*)addr1,(void*)addr2,sizeof(IPADDRESS))) /* copy address 2 onto address 1 */ #define IPADDRESS_COPY(addr1,addr2) \ memcpy((void*)addr1,(void*)addr2,sizeof(*addr1)); /* get IPv4 integer into address setting IPv4 size */ #define IPADDRESS_GET4(addr,ip4ptr) \ {(addr)->iadr_size=4;memset((void*)(addr)->address,0,16);\ memcpy((void*)(addr)->address,(void*)(ip4ptr),SIN_ADDR_SIZE);} /* get IPv6 byte-array into address setting IPv6 size */ #define IPADDRESS_GET6(addr,ip6) \ {(addr)->iadr_size=SIN6_ADDR_SIZE;\ memcpy((void*)(addr)->address,(void*)(ip6),SIN6_ADDR_SIZE);} /* access an IPv4 integer address */ #define IPADDRESS_ADR4(addr) &(addr)->address /* access an IPv6 address, as a pointer */ #define IPADDRESS_ADR6(addr) &(addr)->address /* access an IPv4 or IPv6 address, as a pointer */ #define IPADDRESS_ADR46(addr) &(addr)->address /* set an IPv4 integer address */ #define IPADDRESS_SET4(ip4ptr,addr) \ *(UINTPTR)(ip4ptr) = *(UINTPTR)(addr)->address; /* set an IPv6 byte-array address */ #define IPADDRESS_SET6(ip6,addr) \ memcpy((void*)ip6,(void*)(addr)->address,SIN6_ADDR_SIZE); /* the int size of the IPADDRESS */ #define IPADDRESS_SIZE(addr) (addr)->iadr_size /*******************/ /* sockaddr macros */ /*******************/ /* set this SOCKADDRESS to have an IPv4 size */ #define SOCKADDRESS_V4(addr) (addr)->sadr_size=SIN$K_LENGTH /* set this SOCKADDRESS to have an IPv6 size */ #define SOCKADDRESS_V6(addr) (addr)->sadr_size=SIN6$K_LENGTH /* to have an IPv4 size and zeroed structure */ #define SOCKADDRESS_ZERO4(addr) \ {(addr)->sadr_size=SIN$K_LENGTH;\ memset((void*)&(addr)->sa.v4,0,SIN$K_LENGTH);} /* to have an IPv6 size and zeroed address */ #define SOCKADDRESS_ZERO6(addr) \ {(addr)->sadr_size=SIN6$K_LENGTH;\ memset((void*)&(addr)->sa.v6,0,SIN6$K_LENGTH);} /* true if this SOCKADDRESS has an IPv4 size */ #define SOCKADDRESS_IS_V4(addr) (addr)->sadr_size==SIN$K_LENGTH /* true if this SOCKADDRESS has an IPv6 size */ #define SOCKADDRESS_IS_V6(addr) (addr)->sadr_size==SIN6$K_LENGTH /* access an IPv4 integer address */ #define SOCKADDRESS_ADR4(addr) &(addr)->sa.v4.SIN$L_ADDR /* access an IPv6 byte-array address */ #define SOCKADDRESS_ADR6(addr) &(addr)->sa.v6.SIN6$R_ADDR_OVERLAY.SIN6$T_ADDR /*********************/ /* module structures */ /*********************/ #pragma __member_alignment __save #pragma __member_alignment /* This structure will contain both IPv4 and IPv6 addresses. The 'size' element indicates the former with 4 and the latter with 16. The IPv4 address is stored in the first 4 octets. The IPv6 address uses all 16 octets. 27-APR-2021 MGD move |size| to end of structure */ typedef struct _IPADDRESS { unsigned char address [16]; /* if the size is 4 it's IPv4, if the size is 16 it's IPv6 */ int iadr_size; } IPADDRESS; typedef struct _SOCKADDRESS { union { struct _SOCKADDRIN v4; struct _SOCKADDRIN6 v6; } sa; /* if the size is 16 it's IPv4, if the size is 28 it's IPv6 */ int sadr_size; } SOCKADDRESS; typedef struct _TCPIP_HOST_LOOKUP { BOOL AddrToName, DropConnect; int AgentBusyCount, HostNameLength, RetryCount; ushort HostLength, LookupChannel; uint64 LookupBeginTime64, LookupDeltaTime64; char HostName [TCPIP_HOSTNAME_MAX+1]; struct dsc$descriptor HostAddressDsc; struct dsc$descriptor HostNameDsc; IO_SB LookupIOsb; void *AstFunction; unsigned long AstParam; IPADDRESS IpAddress; HOSTENT HostEntry; } TCPIP_HOST_LOOKUP; typedef struct _TCPIP_HOST_CACHE { BOOL DropConnect; uint ExpiresTickSecond, HitCountAddressToName, HitCountNameToAddress, HostNameLength; uint64 LookupDeltaTime64; char HostName [TCPIP_HOSTNAME_MAX+1]; IPADDRESS IpAddress [TCPIP_HOST_CACHE_ENTRIES_MAX]; } TCPIP_HOST_CACHE; #pragma __nomember_alignment typedef struct _TCP_SOCKET_ITEM { unsigned short Protocol; unsigned char Type; unsigned char Family; } TCP_SOCKET_ITEM; #pragma __member_alignment __restore /***********************/ /* function prototypes */ /***********************/ /** TCPIP.C functions **/ char* TcpIpAddressToString (int, int); int TcpIpAddressToName (TCPIP_HOST_LOOKUP*, IPADDRESS*, int, void*, unsigned long); int TcpIpCacheAddressToName (TCPIP_HOST_LOOKUP*, IPADDRESS*); int TcpIpCacheNameToAddress (TCPIP_HOST_LOOKUP*, char*, int); int TcpIpCacheSetEntry (TCPIP_HOST_LOOKUP*); TcpIpHostCacheInit (); TcpIpHostCacheReport (); TcpIpHostCacheSupervisor (unsigned int); void TcpIpLookupDelta (TCPIP_HOST_LOOKUP*); void TcpIpLookupReport (REQUEST_STRUCT*); int TcpIpNameToAddress (TCPIP_HOST_LOOKUP*, char*, int, void*, unsigned long); int TcpIpNetMask (REQUEST_STRUCT*, int, char**, IPADDRESS*); int TcpIpSocketBufferSize (void*); TcpIpSetAgentInfo (); int TcpIpStringToAddress (char*, IPADDRESS*); /** TCPIPALT.C functions **/ int TcpIpAltAgentBegin (TCPIP_HOST_LOOKUP*); void TcpIpAltAgentEnd (REQUEST_STRUCT *rqptr); int TcpIpAltAgentAddressToName (TCPIP_HOST_LOOKUP*); int TcpIpAltAgentNameToAddress (TCPIP_HOST_LOOKUP*); int TcpIpAltInlineLookup (TCPIP_HOST_LOOKUP*); int TcpIpAltGet4AddrInfo (TCPIP_HOST_LOOKUP*); int TcpIpAltGet6AddrInfo (TCPIP_HOST_LOOKUP*); int TcpIpAltGetNameInfo (TCPIP_HOST_LOOKUP*); /** TCPIP6.C functions **/ BOOL TcpIp6GetAddrInfo (char*, IPADDRESS*); BOOL TcpIp6GetNameInfo (char*, IPADDRESS*); BOOL TcpIp6Nodes (char*, IPADDRESS*); #endif /* TCPIP_H_LOADED */ /*****************************************************************************/