Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:15:38

0001 #ifndef __XRDNETIF_HH__
0002 #define __XRDNETIF_HH__
0003 /******************************************************************************/
0004 /*                                                                            */
0005 /*                           X r d N e t I F . h h                            */
0006 /*                                                                            */
0007 /* (c) 2013 by the Board of Trustees of the Leland Stanford, Jr., University  */
0008 /*                            All Rights Reserved                             */
0009 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
0010 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
0011 /*                                                                            */
0012 /* This file is part of the XRootD software suite.                            */
0013 /*                                                                            */
0014 /* XRootD is free software: you can redistribute it and/or modify it under    */
0015 /* the terms of the GNU Lesser General Public License as published by the     */
0016 /* Free Software Foundation, either version 3 of the License, or (at your     */
0017 /* option) any later version.                                                 */
0018 /*                                                                            */
0019 /* XRootD is distributed in the hope that it will be useful, but WITHOUT      */
0020 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or      */
0021 /* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public       */
0022 /* License for more details.                                                  */
0023 /*                                                                            */
0024 /* You should have received a copy of the GNU Lesser General Public License   */
0025 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file  */
0026 /* COPYING (GPL license).  If not, see <http://www.gnu.org/licenses/>.        */
0027 /*                                                                            */
0028 /* The copyright holder's institutional names and contributor's names may not */
0029 /* be used to endorse or promote products derived from this software without  */
0030 /* specific prior written permission of the institution or contributor.       */
0031 /******************************************************************************/
0032 
0033 #include <cstdlib>
0034 #include <cstring>
0035 
0036 //------------------------------------------------------------------------------
0037 //! The XrdNetIF class handles host interfaces. It is used to obtain the
0038 //! available interface addresses, encode them to be easily transmitted, and
0039 //! decode them to set the interface variations that can be used.
0040 //------------------------------------------------------------------------------
0041 
0042 class XrdNetAddrInfo;
0043 class XrdOucTList;
0044 class XrdSysError;
0045 
0046 struct sockaddr;
0047 
0048 class XrdNetIF
0049 {
0050 public:
0051 
0052 //------------------------------------------------------------------------------
0053 //! Display the final interface configuration.
0054 //!
0055 //! @param  pfx   The desired message prefix (default is as shown).
0056 //------------------------------------------------------------------------------
0057 
0058        void Display(const char *pfx="=====> ");
0059 
0060 //------------------------------------------------------------------------------
0061 //! The enum that is used to index into ifData to get appropriate interface.
0062 //------------------------------------------------------------------------------
0063 
0064        enum ifType {PublicV4  = 0,  //<! Public  IPv4 network
0065                     PrivateV4 = 1,  //<! Private IPv4 network
0066                     PublicV6  = 2,  //<! Public  IPv6 network
0067                     PrivateV6 = 3,  //<! Private IPv6 network
0068                     PrivateIF = 1,  //<! Bit to change PublicVx -> PrivateVx
0069                     ifNum     = 4,  //<! Count of actual interface types
0070                     Public46  = 4,  //<! Public  v4|6 network (dual stack)
0071                     Private46 = 5,  //<! Private v4|6 network (dual stack)
0072                     Public64  = 6,  //<! Public  v6|4 network (dual stack)
0073                     Private64 = 7,  //<! Private v6|4 network (dual stack)
0074                     ifMax     = 8,  //<! Total elements in if vector
0075                     ifAny     = 8}; //<! Used to select any avilable i/f
0076 
0077 //------------------------------------------------------------------------------
0078 //! Get the interface address with a port number.
0079 //!
0080 //! @param  dest  Pointer to the buffer where dest will be placed.
0081 //! @param  dlen  The length of the buffer.
0082 //! @param  ifT   Desired ifType (PublicV6 is the default)
0083 //! @param  prefn When true, a hostname:port is returned if possible
0084 //!
0085 //! @return The length of the name whose pointer is placed in name.
0086 //!         A value of zero indicates that no such interface exists or
0087 //!         the buffer was too small.
0088 //------------------------------------------------------------------------------
0089 
0090        int  GetDest(char *dest, int dlen, ifType ifT=PublicV6, bool prefn=false);
0091 
0092 //------------------------------------------------------------------------------
0093 //! Get the interface name without a port number.
0094 //!
0095 //! @param  name  Reference to where a pointer to the name will be placed
0096 //! @param  ifT   Desired ifType (PublicV6 is the default)
0097 //!
0098 //! @return The length of the name whose pointer is placed in name.
0099 //!         A value of zero indicates that no such interface exists.
0100 //------------------------------------------------------------------------------
0101 
0102 inline int  GetName(const char *&name, ifType ifT=PublicV6)
0103                    {if (ifT >= ifAny) ifT = static_cast<ifType>(ifAvail);
0104                     name = ifName[ifT]->iVal;
0105                     return ifName[ifT]->iLen;
0106                    }
0107 
0108 //------------------------------------------------------------------------------
0109 //! Copy the interface name and return port number.
0110 //!
0111 //! @param  nbuff Reference to buffer where the name will be placed. It must
0112 //!               be atleast 256 bytes in length.
0113 //! @param  nport Place where the port number will be placed.
0114 //! @param  ifT   Desired ifType (PublicV6 is the default)
0115 //!
0116 //! @return The length of the name copied into the buffer.
0117 //!         A value of zero indicates that no such interface exists.
0118 //------------------------------------------------------------------------------
0119 
0120 inline int  GetName(char *nbuff, int &nport, ifType ifT=PublicV6)
0121                    {if (ifT >= ifAny) ifT = static_cast<ifType>(ifAvail);
0122                     strcpy(nbuff, ifName[ifT]->iVal); nport = ifPort;
0123                     return ifName[ifT]->iLen;
0124                    }
0125 
0126 //------------------------------------------------------------------------------
0127 //! Obtain an easily digestable list of IP routable interfaces to this machine.
0128 //!
0129 //! @param  ifList   Place where the list of interfaces will be placed. If
0130 //!                  ifList is null, returns configured interface types.
0131 //! @param  eText    When not nil, is where to place error message text.
0132 //!
0133 //! @return Success: ifList != 0: returns the count of interfaces in the list.
0134 //!                  *ifList->sval[0] strlen(ifList->text)
0135 //!                  *ifList->sval[1] when != 0 the address is private.
0136 //!                  *ifList->text    the interface address is standard format.
0137 //!                  The list of objects belongs to the caller and must be
0138 //!                  deleted when no longer needed.
0139 //!
0140 //!                  ifList == 0: returns types of configured non-local i/f.
0141 //!                  This is or'd values of the static const ints haveXXXX.
0142 //!
0143 //!         Failure: Zero is returned. If eText is supplied, the error message,
0144 //!                  in persistent storage, is returned.
0145 //------------------------------------------------------------------------------
0146 
0147 static
0148 const  int  haveNoGI = 0;  //!< ifList == 0 && getifaddrs() is not supported
0149 static
0150 const  int  haveIPv4 = 1;  //!< ifList == 0 && non-local ipv4 i/f found (or'd)
0151 static
0152 const  int  haveIPv6 = 2;  //!< ifList == 0 && non-local ipv6 i/f found (or'd)
0153 static
0154 const  int  havePrv4 = 4;  //!< ifList == 0 && private   ipv4 i/f found (or'd)
0155 static
0156 const  int  havePrv6 = 8;  //!< ifList == 0 && private   ipv6 i/f found (or'd)
0157 static
0158 const  int  havePub4 =16;  //!< ifList == 0 && public    ipv4 i/f found (or'd)
0159 static
0160 const  int  havePub6 =32;  //!< ifList == 0 && public    ipv6 i/f found (or'd)
0161 
0162 static int  GetIF(XrdOucTList **ifList, const char **eText=0);
0163 
0164 //------------------------------------------------------------------------------
0165 //! Obtain an easily transmittable IP routable interfaces to this machine.
0166 //!
0167 //! @param  buff     Pointer to buffer to hold result which can be fed to SetIF.
0168 //! @param  blen     The length of the buffer (4K is really sufficient).
0169 //! @param  eText    When not nil, is where to place error message text.
0170 //! @param  show     When true configured interfaces are also displayed.
0171 //!
0172 //! @return Success: Number of bytes placed in buff, excluding the null.
0173 //!         Failure: Zero is returned. If eText is supplied, the error message,
0174 //!                  in persistent storage, is returned.
0175 //------------------------------------------------------------------------------
0176 
0177 static int  GetIF(char *buff, int blen, const char **eText=0, bool show=false);
0178 
0179 //------------------------------------------------------------------------------
0180 //! Obtain an easily transmittable IP routable interfaces to this machine.
0181 //!
0182 //! @param  ifline   Reference to a char * pointer that will get the result.
0183 //! @param  eText    When not nil, is where to place error message text.
0184 //! @param  show     When true configured interfaces are also displayed.
0185 //!
0186 //! @return Success: Number of bytes in the returned string ecluding the null.
0187 //!                  The caller is responsible for unallocating it via free().
0188 //!         Failure: Zero is returned. If eText is supplied, the error message,
0189 //!                  in persistent storage, is returned. *ifline is set to 0.
0190 //------------------------------------------------------------------------------
0191 
0192 static int  GetIF(char *&ifline, const char **eText=0, bool show=false);
0193 
0194 //------------------------------------------------------------------------------
0195 //! Get the ifType for client connection.
0196 //!
0197 //! @param  conIPv4  True if connected via IPv4, false means IPv6.
0198 //! @param  hasIP64  True if the client has an IPv4 and IPv6 address.
0199 //! @param  pvtIP    True if the ip address is private.
0200 //!
0201 //! @return The ifType correspodning to the passed arguments.
0202 //------------------------------------------------------------------------------
0203 
0204 static ifType GetIFType(bool conIPv4, bool hasIP64, bool pvtIP)
0205                        {ifType ifT;
0206                         if (conIPv4) ifT = (hasIP64 ? Public46 : PublicV4);
0207                            else      ifT = (hasIP64 ? Public64 : PublicV6);
0208                         if (pvtIP) Privatize(ifT);
0209                         return ifT;
0210                        }
0211 
0212 //------------------------------------------------------------------------------
0213 //! Determine whether or not an interface exists.
0214 //!
0215 //! @param  ifT   -> Desired ifType (PublicV6 is the default)
0216 //!
0217 //! @return true  -> desired dest exists.
0218 //!         false -> desired dest does not exist.
0219 //------------------------------------------------------------------------------
0220 
0221 inline bool HasDest(ifType ifT=PublicV6)
0222                    {return ifT >= ifAny || ifDest[ifT]->iLen != 0;}
0223 
0224 //------------------------------------------------------------------------------
0225 //! Determine if an endpoint is this domain based on hostname.
0226 //!
0227 //! @param  epaddr   Pointer to the endpoint NetAddrInfo object.
0228 //!
0229 //! @result true     The endpoint is in this domain.
0230 //! @result false    Either the endpoint is not in this domain, is a private
0231 //!                  address, or is not registered in DNS.
0232 //------------------------------------------------------------------------------
0233 
0234 static bool InDomain(XrdNetAddrInfo *epaddr);
0235 
0236 //------------------------------------------------------------------------------
0237 //! Get the ifType selection mask for this object.
0238 //!
0239 //! @return A single char that represents the selection mask.
0240 //------------------------------------------------------------------------------
0241 
0242        char Mask() {return ifMask;}
0243 
0244 //------------------------------------------------------------------------------
0245 //! Convert an ifType to its corresponding selection mask.
0246 //!
0247 //! @param  ifT   The ifType to convert.
0248 //!
0249 //! @return A single char that represents the selection mask.
0250 //------------------------------------------------------------------------------
0251 
0252 static char Mask(ifType ifT)
0253                 {if (ifT >= ifAny) return 0x0f;
0254                  return ifMaskVec[ifT];
0255                 }
0256 
0257 //------------------------------------------------------------------------------
0258 //! Get the human readable for for an ifType.
0259 //!
0260 //! @param  ifT   The ifType to convert.
0261 //!
0262 //! @return A pointer to the human readable name. The string resides in static
0263 //!         storage and is always valid.
0264 //------------------------------------------------------------------------------
0265 static
0266 const char *Name(ifType ifT) {if (ifT >= ifAny) return "any";
0267                               return ifTName[ifT];
0268                              }
0269 
0270 //------------------------------------------------------------------------------
0271 //! Get the assigned port number
0272 //!
0273 //! @return The port number.
0274 //------------------------------------------------------------------------------
0275 
0276 inline int  Port() {return ifPort;}
0277 
0278 //------------------------------------------------------------------------------
0279 //! Make an iofType refer to the private network.
0280 //!
0281 //! @param x     The iftype variable that will have the private bit set.
0282 //------------------------------------------------------------------------------
0283 
0284 static void Privatize(ifType &x) {x = ifType(x | PrivateIF);}
0285 
0286 //------------------------------------------------------------------------------
0287 //! Set the assigned port number. This method is not thread safe!
0288 //!
0289 //! @param  pnum     The port number.
0290 //!
0291 //! @return The previous port number.
0292 //------------------------------------------------------------------------------
0293 
0294        int  Port(int pnum);
0295 
0296 //------------------------------------------------------------------------------
0297 //! Set the default assigned port number.
0298 //!
0299 //! @param  pnum     The port number.
0300 //------------------------------------------------------------------------------
0301 
0302 static void PortDefault(int pnum=1094);
0303 
0304 //------------------------------------------------------------------------------
0305 //! Routing() and SetIF() parameter.
0306 //!
0307 //! netDefault - netSplit for Routing() and Routing() value for SetIF().
0308 //! netSplit   - public and private addresses are routed separately so that
0309 //!              substitution of one type of address for another is not allowed.
0310 //! netCommon  - clients with private addresses also have public addresses.
0311 //!              Source and target addresses should match but a public address
0312 //!              may be used in the absence of a private address.
0313 //! netLocal   - private addresses are registered and can be used by public
0314 //!              clients within this domain. Clients with public addresses can
0315 //!              be routed to private addresses.
0316 //------------------------------------------------------------------------------
0317 
0318        enum netType {netDefault = 0, netSplit, netCommon, netLocal};
0319 
0320 //------------------------------------------------------------------------------
0321 //! Set default interface network routing.
0322 //!
0323 //! @param  nettype  Network routing (see netType definition).
0324 //------------------------------------------------------------------------------
0325 
0326 static void Routing(netType nettype);
0327 
0328 //------------------------------------------------------------------------------
0329 //! Set the ifData structure based on the interface string generated by GetIF().
0330 //!
0331 //! @param  src      The network information of host supplying the if string.
0332 //! @param  ifList   The interface string, it must be null terminated.
0333 //! @param  port     The port associated with the interfaces; as follows:
0334 //!                  <0 -> Use previous setting if any.
0335 //!                  =0 -> use default port (the default).
0336 //!                  >0 -> Use the number passed.
0337 //! @param  nettype  Determines how undefined interfaces are resolved. See
0338 //!                  the netType definition.
0339 //! @param  xName    the known registered host name should ip address
0340 //!                  translation fail.
0341 //!
0342 //! @return Success: True.
0343 //!         Failure: False and if eText is supplied, the error message,
0344 //!                  in persistent storage, is returned.
0345 //------------------------------------------------------------------------------
0346 
0347        bool SetIF(XrdNetAddrInfo *src, const char *ifList, int port=0,
0348                   netType nettype=netDefault, const char *xName=0);
0349 
0350 //------------------------------------------------------------------------------
0351 //! Set the public and private network interface names.
0352 //!
0353 //! @param  ifnames  Pointer to the comma seperated interface names. This
0354 //!                  string is modified.
0355 //!
0356 //! @return true     Names have been set.
0357 //! @return false    Invalid interface name list.
0358 //------------------------------------------------------------------------------
0359 
0360 static bool SetIFNames(char *ifnames);
0361 
0362 //------------------------------------------------------------------------------
0363 //! Specify where messages are to be sent.
0364 //!
0365 //! @param  erp      Pointer to the error message object. By default, no error
0366 //!                  messages are printed. This is not a thread-safe call and
0367 //!                  the err disposition must be set at initialization time.
0368 //------------------------------------------------------------------------------
0369 
0370 static void SetMsgs(XrdSysError *erp);
0371 
0372 //------------------------------------------------------------------------------
0373 //! Specify wheter or not private IP addresses should be resolved.
0374 //!
0375 //! @param  rval     When true, private IP addresses are resolved. Otherwise,
0376 //!                  the IP addresses is used as the hostname.
0377 //------------------------------------------------------------------------------
0378 
0379 static void SetRPIPA(bool rval);
0380 
0381 //------------------------------------------------------------------------------
0382 //! Constructor and Destructor
0383 //------------------------------------------------------------------------------
0384 
0385        XrdNetIF() : ifBuff(0), ifMask(0), ifAvail(0)  {}
0386 
0387       ~XrdNetIF() {if (ifBuff) free(ifBuff);}
0388 
0389 private:
0390 
0391 struct ifAddrs
0392       {short hALen;
0393        short hDLen;
0394        bool  ipV6;
0395        bool  prvt;
0396        char  hAddr[64];    // address
0397        char  hDest[64];    // address possibly in deprecated format
0398       };
0399 
0400 bool  GenAddrs(ifAddrs &ifTab, XrdNetAddrInfo *src);
0401 bool  GenAddrs(ifAddrs &ifTab, const char *hName, bool wantV6);
0402 bool  GenIF(XrdNetAddrInfo **src, int srcnum, const char *xName=0);
0403 static const
0404 char *GetDomain();
0405 static
0406 bool  IsOkName(const char *ifn, short &ifIdx);
0407 void  SetIFPP();
0408 bool  SetIF64(bool retVal);
0409 static
0410 bool  V4LinkLocal(struct sockaddr *saP);
0411 
0412 struct ifData
0413 {
0414        short  iLen;
0415        char   iVal[6]; // Actually of size iLen
0416 
0417        ifData() : iLen(0) {*iVal = 0;}
0418       ~ifData() {}
0419 };
0420 
0421 ifData        *ifName[ifMax];
0422 ifData        *ifDest[ifMax];
0423 bool           ifxDNS[ifMax];
0424 char          *ifBuff;
0425 
0426 struct pInfo {char   len;
0427               char   val[7]; // Contains ":12345\0"
0428                      pInfo() : len(0) {*val = 0;}
0429              } portSfx;
0430 
0431 int            ifPort;
0432 short          ifRoute;
0433 char           ifMask;
0434 char           ifAvail;
0435 
0436 static
0437 XrdSysError   *eDest;
0438 static
0439 const char    *myDomain;
0440 static char   *ifCfg[2];
0441 static
0442 const char    *ifTName[ifMax];
0443 static
0444 const char    *ifMaskVec;
0445 static
0446 netType        netRoutes;
0447 static int     dfPort;
0448 static ifData  ifNull;
0449 static bool    rPIPA;
0450 };
0451 #endif